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.