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