github.com/zmwangx/ets@v0.2.2-0.20201107170110-98f3846f5ca3/README.md (about)

     1  <h1 align="center"><img src="assets/logo.svg" height="50" alt="ets" /></h1>
     2  
     3  <p align="center">
     4    <a href="https://github.com/zmwangx/ets/releases"><img src="https://img.shields.io/github/v/release/zmwangx/ets" alt="GitHub release" /></a>
     5    <a href="https://github.com/zmwangx/ets/actions"><img src="https://github.com/zmwangx/ets/workflows/test/badge.svg?branch=master" alt="Build status" /></a>
     6  </p>
     7  
     8  <p align="center"><img src="assets/animation.svg" alt="ets" /></p>
     9  <p align="center"><img src="assets/animation-progressbar.svg" alt="ets" /></p>
    10  
    11  `ets` is a command output timestamper — it prefixes each line of a command's output with a timestamp.
    12  
    13  The purpose of `ets` is similar to that of moreutils [`ts(1)`](https://manpages.ubuntu.com/manpages/focal/en/man1/ts.1.html), but `ets` differentiates itself from similar offerings by running commands directly within ptys, hence solving thorny issues like pipe buffering and commands disabling color and interactive features when detecting a pipe as output. (`ets` does provide a reading-from-stdin mode if you insist.) `ets` also recognizes carriage return as a line seperator, so it doesn't choke if your command prints a progress bar. A more detailed comparison of `ets` and `ts` can be found [below](#comparison-to-moreutils-ts).
    14  
    15  `ets` currently supports macOS, Linux, and various other *ix variants.
    16  
    17  <!-- START doctoc generated TOC please keep comment here to allow auto update -->
    18  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
    19  
    20  
    21  - [Examples](#examples)
    22  - [Installation](#installation)
    23  - [Usage](#usage)
    24  - [Comparison to moreutils ts](#comparison-to-moreutils-ts)
    25  - [License](#license)
    26  
    27  <!-- END doctoc generated TOC please keep comment here to allow auto update -->
    28  
    29  ## Examples
    30  
    31  Run a command with `ets`:
    32  
    33  ```console
    34  $ ets ping localhost
    35  [2020-06-16 17:13:03] PING localhost (127.0.0.1): 56 data bytes
    36  [2020-06-16 17:13:03] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
    37  [2020-06-16 17:13:04] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
    38  [2020-06-16 17:13:05] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
    39  ...
    40  ```
    41  
    42  Run a shell command:
    43  
    44  ```console
    45  $ ets 'ping localhost | grep icmp'
    46  [2020-06-16 17:13:03] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
    47  [2020-06-16 17:13:04] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
    48  [2020-06-16 17:13:05] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
    49  ...
    50  ```
    51  
    52  Pipe command output into stdin:
    53  
    54  ```console
    55  $ ping localhost | grep icmp | ets
    56  [2020-06-16 17:13:03] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
    57  [2020-06-16 17:13:04] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
    58  [2020-06-16 17:13:05] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
    59  ...
    60  ```
    61  
    62  Show elapsed time:
    63  
    64  ```console
    65  $ ets -s ping -i5 localhost
    66  [00:00:00] PING localhost (127.0.0.1): 56 data bytes
    67  [00:00:00] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.039 ms
    68  [00:00:05] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.031 ms
    69  [00:00:10] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.030 ms
    70  [00:00:15] 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.045 ms
    71  ...
    72  ```
    73  
    74  Show incremental time (since last timestamp):
    75  
    76  ```console
    77  $ ets -i ping -i5 localhost
    78  [00:00:00] PING localhost (127.0.0.1): 56 data bytes
    79  [00:00:00] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.043 ms
    80  [00:00:05] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.047 ms
    81  [00:00:05] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.116 ms
    82  [00:00:05] 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.071 ms
    83  ...
    84  ```
    85  
    86  Use a different timestamp format:
    87  
    88  ```console
    89  $ ets -f '%b %d %T|' ping localhost
    90  Jun 16 17:13:03| PING localhost (127.0.0.1): 56 data bytes
    91  Jun 16 17:13:03| 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
    92  Jun 16 17:13:04| 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
    93  Jun 16 17:13:05| 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
    94  ...
    95  ```
    96  
    97  Millisecond precision (microsecond available too):
    98  
    99  ```console
   100  $ ets -s -f '[%T.%L]' ping -i 0.1 localhost
   101  [00:00:00.004] PING localhost (127.0.0.1): 56 data bytes
   102  [00:00:00.004] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.032 ms
   103  [00:00:00.108] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.038 ms
   104  [00:00:00.209] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.051 ms
   105  [00:00:00.311] 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.049 ms
   106  ...
   107  ```
   108  
   109  Use a different timezone:
   110  
   111  ```console
   112  $ ets ping localhost  # UTC
   113  [2020-06-16 09:13:03] PING localhost (127.0.0.1): 56 data bytes
   114  [2020-06-16 09:13:03] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
   115  [2020-06-16 09:13:04] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
   116  [2020-06-16 09:13:05] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
   117  ```
   118  
   119  ```console
   120  $ ets -z America/Los_Angeles -f '[%F %T%z]' ping localhost
   121  [2020-06-16 02:13:03-0700] PING localhost (127.0.0.1): 56 data bytes
   122  [2020-06-16 02:13:03-0700] 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.036 ms
   123  [2020-06-16 02:13:04-0700] 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.077 ms
   124  [2020-06-16 02:13:05-0700] 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.037 ms
   125  ```
   126  
   127  Color the timestamps:
   128  
   129  ```console
   130  $ ets -c ping localhost
   131  ...
   132  ```
   133  
   134  ## Installation
   135  
   136  - On macOS you can install ets with Homebrew:
   137  
   138    ```
   139    brew tap zmwangx/ets https://github.com/zmwangx/ets
   140    brew install zmwangx/ets/ets
   141    ```
   142  
   143  - On macOS and Linux you get download a prebuilt tarball/package from the [release page](https://github.com/zmwangx/ets/releases).
   144  
   145  - On Arch Linux you can install the [ets-bin](https://aur.archlinux.org/packages/ets-bin/) binary package from AUR:
   146  
   147    ```sh
   148    pacman -S ets-bin
   149    # or
   150    yay -S ets-bin
   151    ```
   152  
   153  - On a supported platform, if you have the Go toolchain installed, you may install with
   154  
   155    ```
   156    go get github.com/zmwangx/ets
   157    ```
   158  
   159  ## Usage
   160  
   161  <!-- begin manpage -->
   162  
   163  ```
   164  
   165  ETS(1)                    BSD General Commands Manual                   ETS(1)
   166  
   167  NAME
   168       ets -- command output timestamper
   169  
   170  SYNOPSIS
   171       ets [-s | -i] [-f format] [-u | -z timezone] command [arg ...]
   172       ets [options] shell_command
   173       ets [options]
   174  
   175  DESCRIPTION
   176       ets prefixes each line of a command's output with a timestamp. Lines are
   177       delimited by CR, LF, or CRLF.
   178  
   179       The three forms in SYNOPSIS correspond to three command execution modes:
   180  
   181       o If given a single command without whitespace(s), or a command and its
   182         arguments, execute the command with exec in a pty;
   183  
   184       o If given a single command with whitespace(s), the command is treated as
   185         a shell command and executed as `SHELL -c shell_command', where SHELL
   186         is the current user's login shell, or sh if login shell cannot be
   187         determined;
   188  
   189       o If given no command, output is read from stdin, and the user is respon-
   190         sible for piping in a command's output.
   191  
   192       There are three mutually exclusive timestamp modes:
   193  
   194       o The default is absolute time mode, where timestamps from the wall clock
   195         are shown;
   196  
   197       o -s, --elapsed turns on elapsed time mode, where every timestamp is the
   198         time elapsed from the start of the command (using a monotonic clock);
   199  
   200       o -i, --incremental turns on incremental time mode, where every timestamp
   201         is the time elapsed since the last timestamp (using a monotonic clock).
   202  
   203       The default format of the prefixed timestamps depends on the timestamp
   204       mode active. Users may supply a custom format string with the -f,
   205       --format option.
   206  
   207       The timezone for absolute timestamps can be controlled via the -u, --utc
   208       and -z, --timezone options. Local time is used by default.
   209  
   210       The full list of options:
   211  
   212       -s, --elapsed
   213                Run in elapsed time mode.
   214  
   215       -i, --incremental
   216                Run in incremental time mode.
   217  
   218       -f, --format format
   219                Use custom strftime(3)-style format string format for prefixed
   220                timestamps.
   221  
   222                The default is ``[%Y-%m-%d %H:%M:%S]'' for absolute time mode
   223                and ``[%H:%M:%S]'' for elapsed and incremental time modes.
   224  
   225                See FORMATTING DIRECTIVES for details.
   226  
   227       -u, --utc
   228                Use UTC for absolute timestamps instead of local time.
   229  
   230                This option is mutually exclusive with --z, --timezone.
   231  
   232       -z, --timezone timezone
   233                Use timezone for absolute timestamps instead of local time.
   234                timezone is an IANA time zone name, e.g.
   235                ``America/Los_Angeles''.
   236  
   237                This option is mutually exclusive with -u, --utc.
   238  
   239       -c, --color
   240                Print timestamps in color.
   241  
   242  FORMATTING DIRECTIVES
   243       Formatting directives largely match strftime(3)'s directives on FreeBSD
   244       and macOS, with the following differences:
   245  
   246       o Additional directives %f for microsecond and %L for millisecond are
   247         supported.
   248  
   249       o POSIX locale extensions %E* and %O* are not supported;
   250  
   251       o glibc extensions %-*, %_*, and %0* are not supported;
   252  
   253       o Directives %G, %g, and %+ are not supported.
   254  
   255       Below is the full list of supported directives:
   256  
   257       %A    is replaced by national representation of the full weekday name.
   258  
   259       %a    is replaced by national representation of the abbreviated weekday
   260             name.
   261  
   262       %B    is replaced by national representation of the full month name.
   263  
   264       %b    is replaced by national representation of the abbreviated month
   265             name.
   266  
   267       %C    is replaced by (year / 100) as decimal number; single digits are
   268             preceded by a zero.
   269  
   270       %c    is replaced by national representation of time and date.
   271  
   272       %D    is equivalent to ``%m/%d/%y''.
   273  
   274       %d    is replaced by the day of the month as a decimal number (01-31).
   275  
   276       %e    is replaced by the day of the month as a decimal number (1-31);
   277             single digits are preceded by a blank.
   278  
   279       %F    is equivalent to ``%Y-%m-%d''.
   280  
   281       %f    is replaced by the microsecond as a decimal number (000000-999999).
   282  
   283       %H    is replaced by the hour (24-hour clock) as a decimal number
   284             (00-23).
   285  
   286       %h    the same as %b.
   287  
   288       %I    is replaced by the hour (12-hour clock) as a decimal number
   289             (01-12).
   290  
   291       %j    is replaced by the day of the year as a decimal number (001-366).
   292  
   293       %k    is replaced by the hour (24-hour clock) as a decimal number (0-23);
   294             single digits are preceded by a blank.
   295  
   296       %L    is replaced by the millisecond as a decimal number (000-999).
   297  
   298       %l    is replaced by the hour (12-hour clock) as a decimal number (1-12);
   299             single digits are preceded by a blank.
   300  
   301       %M    is replaced by the minute as a decimal number (00-59).
   302  
   303       %m    is replaced by the month as a decimal number (01-12).
   304  
   305       %n    is replaced by a newline.
   306  
   307       %p    is replaced by national representation of either "ante meridiem"
   308             (a.m.)  or "post meridiem" (p.m.)  as appropriate.
   309  
   310       %R    is equivalent to ``%H:%M''.
   311  
   312       %r    is equivalent to ``%I:%M:%S %p''.
   313  
   314       %S    is replaced by the second as a decimal number (00-60).
   315  
   316       %s    is replaced by the number of seconds since the Epoch, UTC (see
   317             mktime(3)).
   318  
   319       %T    is equivalent to ``%H:%M:%S''.
   320  
   321       %t    is replaced by a tab.
   322  
   323       %U    is replaced by the week number of the year (Sunday as the first day
   324             of the week) as a decimal number (00-53).
   325  
   326       %u    is replaced by the weekday (Monday as the first day of the week) as
   327             a decimal number (1-7).
   328  
   329       %V    is replaced by the week number of the year (Monday as the first day
   330             of the week) as a decimal number (01-53).  If the week containing
   331             January 1 has four or more days in the new year, then it is week 1;
   332             otherwise it is the last week of the previous year, and the next
   333             week is week 1.
   334  
   335       %v    is equivalent to ``%e-%b-%Y''.
   336  
   337       %W    is replaced by the week number of the year (Monday as the first day
   338             of the week) as a decimal number (00-53).
   339  
   340       %w    is replaced by the weekday (Sunday as the first day of the week) as
   341             a decimal number (0-6).
   342  
   343       %X    is replaced by national representation of the time.
   344  
   345       %x    is replaced by national representation of the date.
   346  
   347       %Y    is replaced by the year with century as a decimal number.
   348  
   349       %y    is replaced by the year without century as a decimal number
   350             (00-99).
   351  
   352       %Z    is replaced by the time zone name.
   353  
   354       %z    is replaced by the time zone offset from UTC; a leading plus sign
   355             stands for east of UTC, a minus sign for west of UTC, hours and
   356             minutes follow with two digits each and no delimiter between them
   357             (common form for RFC 822 date headers).
   358  
   359       %%    is replaced by `%'.
   360  
   361  SEE ALSO
   362       ts(1), strftime(3)
   363  
   364  HISTORY
   365       The name ets comes from ``enhanced ts'', referring to moreutils ts(1).
   366  
   367  AUTHORS
   368       Zhiming Wang <i@zhimingwang.org>
   369  
   370                                   July 3, 2020
   371  ```
   372  
   373  <!-- end manpage -->
   374  
   375  ## Comparison to moreutils ts
   376  
   377  Advantages:
   378  
   379  - Runs commands in ptys, making ets mostly transparent and avoiding pipe-related issues like buffering and lost coloring and interactivity.
   380  - Recognizes carriage return as line separator, does not choke on progress bars.
   381  - Has better operating defaults (uses monotonic clock where appropriate) and better formatting defaults (subjective).
   382  - Supports alternative time zones.
   383  - Is written in Go, not Perl, so you install a single executable, not script plus modules.
   384  - Has an executable name that doesn't conflict with other known packages. moreutils as a whole is a conflicting hell, and ts alone conflicts with at least task-spooler.
   385  
   386  Disadvantages:
   387  
   388  - Needs an additional `-f` for format string, because ets reserves positional arguments for its core competency. Hopefully offset by better default.
   389  - Does not support the `-r` mode of ts. It's a largely unrelated mode of operation and I couldn't even get `ts -r` to work anywhere, maybe because optional dependencies aren't satisfied, or maybe I misunderstood the feature altogether. Anyway, not interested.
   390  - Supports fewer formatting directives. Let me know if this is actually an issue, it could be fixable.
   391  
   392  ## License
   393  
   394  Copyright © 2020 Zhiming Wang <i@zhimingwang.org>
   395  
   396  The project is distributed under [the MIT license](https://opensource.org/licenses/MIT).
   397  
   398  Special thanks to DinosoftLab on None Project for the [hourglass icon](https://thenounproject.com/term/hourglass/1674538/) used in the logo, and [termtosvg](https://github.com/nbedos/termtosvg) for the animated terminal recording.