1) Slow news day ... and this being an example of read's -t option put to a good use.
2) Ah, pedantic nitpicking, love it. Because the script is meant for interactive use with no streams redirected off the terminal, and because it doesn't output diagnostics or errors, but rather augments the stdout.
Or put differently - show me an example where writing into stderr would make more sense.
(edit) I guess someone can tee the output afterwards. Fine, I'll make it use stderr.
One argument against using stderr: IIRC stdout defaults to line buffering (or more if piped), while stderr is flushed immediately, so using stderr vs. stdout can yield different results.
Hey, I can envisage this being helpful. Thanks. One criticism, which I think has already been voiced, is that you you print to standard error instead of standard out. That way anyone piping to a file won't be surprised when things break if the file is read by something else.
Another alternative is 'ts' which is part of joey hess's awesome collection of unix tools, moreutils.[1] I did not find out about ts until too late so I am still in the habit of using tai64n from djb's daemontools, which adds a tai64 timestamp to every file[2] and then tai64nlocal[3] in order to convert the timestamps to something useful to humans.
If you don't know about moreutils check out the collection. I don't know what I'd do without vipe or vidir:
Chronic: runs a command quietly unless it fails
combine: combine the lines in two files using boolean operations
ifdata: get network interface info without parsing ifconfi
ifne: run a program if the standard input is not empty
isutf8: check if a file or standard input is utf-8
lckdo: execute a program with a lock held
mispipe: pipe two commands, returning the exit status of
parallel: run multiple jobs at once
pee: tee standard input to pipes
sponge: soak up standard input and write to a file
ts: timestamp standard input
vidir: edit a directory in your text editor
vipe: insert a text editor into a pipe
zrun: automatically uncompress arguments to command
> ifdata: get network interface info without parsing ifconfi
If it's Linux, ifconfig isn't maintained anymore and might actually be lying (eg, virtual IPs on vlans on bonded NICs - sounds exotic but almost every trading house uses this config). Use the 'ip' command for most things you would have done with 'ifconfig'.
Thank god for the Linux people innovating and replacing a perfectly functional tool that could be properly extended to add support for that configuration, and instead requiring people to learn yet another command.
It's about as bad as Solaris with their ifconfig/ipadm stuff and changing everything around so that configuration exists in multiple places and one tool doesn't handle the other. ipadm doesn't properly deal with /etc/<hostname>.<interface> files and the two will conflict. Ugh.
In the "Unix Programming Environment" book from 1984 there is an "overwrite" shell script depicted that does exactly this. I wonder why this never made it into the standard UNIX toolkit.
The whole point of a pipe is to have concurrent input and output. If so, and if you open the same file for input and output, you risk erasing the file by opening and deleting the file on the output side before reading it on the input side.
If the pipe is an unfulfilled promise (no concurrency) then there's no problem. But if the pipe does what it's designed to do, you will lose the file.
EDIT: this doesn't work for the "sed s/foo/bar/ file|sponge file" case, but it does for certain other usages where you basically want to wait until EOF before outputting
I'm not sure I really see a point in this. How are you going to forget the server's time zone when it's listed in the timestamps? It doesn't really make sense.
It's for the cases when you are in a different timezone than the server. When the log says "03/Mar/2013 09:24:13 -0800" and it's 13:50 where I am, it takes me a while to understand how old that line is.
I know it's different, meaning that I have to do some basic arithmetics to get the log line age. It also requires me to roll my precious eyes to look at the local time in a system tray. It's just all too tedious.
Actually with that setup (which is a bit like mine) you can see how long it took from the finishing time of the last command you executed (when your PS1 was redisplayed) to the finishing of the command you just executed.
which doesn't invoke a subshell. env vars can always be prepended to the executable name for use with just that program (not sure if that's bash only, though).
For an alternative way of accomplishing the example given take a look at multitail [1]. Hitting return will insert a line with the current date and time to the file you're tailing.
It also colour codes the output and allows you to tail multiple files simultaneously.
That was funny seeing this here, for a minute I thought someone had posted the now.sh from my dotfiles. But I think it's no longer there. In any case mine wasn't as thoughtful, it was just a shell script to pretty print the current time, so that I could index it with Gnome-do/Kupfer/Synapse and easily call it from there. But I have since moved that responsibility to a key binding in vim, since I'm always inside the editor. All this, of course, so that I could hide the Linux Mint bar on the bottom and still see the time easily through another mean.
How about a script: a wrapper to run any other
script or process, that logs both STDOUT and STDERR in
one file, but prepends a short string of your choice for
lines that are from STDERR.
44 comments
[ 2.8 ms ] story [ 93.7 ms ] thread1) Really? This is on the front page of HN?
2) why aren't you printing to stderr?
(No idea why not stderr however)
2) Ah, pedantic nitpicking, love it. Because the script is meant for interactive use with no streams redirected off the terminal, and because it doesn't output diagnostics or errors, but rather augments the stdout.
Or put differently - show me an example where writing into stderr would make more sense.
(edit) I guess someone can tee the output afterwards. Fine, I'll make it use stderr.
[1] http://gerg.ca/software/tscat/
If you don't know about moreutils check out the collection. I don't know what I'd do without vipe or vidir:
[1] http://joeyh.name/code/moreutils/[2] http://cr.yp.to/daemontools/tai64n.html
[3] http://cr.yp.to/daemontools/tai64nlocal.html
now is different. It re-prints current time once a second while waiting for the input. You basically get the running clock at the last line of output.
> ifdata: get network interface info without parsing ifconfi
If it's Linux, ifconfig isn't maintained anymore and might actually be lying (eg, virtual IPs on vlans on bonded NICs - sounds exotic but almost every trading house uses this config). Use the 'ip' command for most things you would have done with 'ifconfig'.
If it's BSD, ignore that and ifconfig away.
https://github.com/madx/moreutils/blob/master/ifdata.c
It's about as bad as Solaris with their ifconfig/ipadm stuff and changing everything around so that configuration exists in multiple places and one tool doesn't handle the other. ipadm doesn't properly deal with /etc/<hostname>.<interface> files and the two will conflict. Ugh.
Whoa! No kidding? I wrote a program years ago, probably around 2005, also called sponge, that does exactly this[1].
I'm not sure how to feel about this. Obviously the idea was a good one, but it's equally obvious I suck at getting the word out about my creations.
[1] https://github.com/graue/graue-utils/blob/master/sponge.c
That can be said for so many of these programs.
joeyh's example:
My example:If the pipe is an unfulfilled promise (no concurrency) then there's no problem. But if the pipe does what it's designed to do, you will lose the file.
EDIT -- after tinkering around with the console, I see. I'm wiping the file out by writing to it (>) before it's finished reading (<). Neat, TIL!
whatever <file | tee file 1>/dev/null
1. I never thought to try that. How silly of me. OR
2. Perhaps tee behaves differently on OpenBSD (which I was using at the time).
EDIT: this doesn't work for the "sed s/foo/bar/ file|sponge file" case, but it does for certain other usages where you basically want to wait until EOF before outputting
e.g. echo "03/Mar/2013 01:16:52 +0000" | mytz => 02/Mar/2013 17:16:52 -0800
Sun Mar 3 10:05:17 PST 2013
The above converts to the system TZ. Or:
$ echo $( export TZ=CST; date -d "Sun Mar 3 18:05:17 UTC 2013" )
Sun Mar 3 18:05:17 CST 2013
The above converts from any TZ to any other TZ, without resetting your shell's TZ variable.
$ TZ=CST date -d "Sun Mar 3 18:05:17 UTC 2013"
Sun Mar 3 18:05:17 CST 2013
which doesn't invoke a subshell. env vars can always be prepended to the executable name for use with just that program (not sure if that's bash only, though).
It also colour codes the output and allows you to tail multiple files simultaneously.
[1] http://www.vanheusden.com/multitail/