The backtick syntax substitutes the output of the given command; when that command returns a filename, you get something like:
tail -3 nnnn01.whatever
But if there are no matches, there is nothing to substitute, so you effectively run:
tail -3
If we look at the summary under man tail
, we see the behaviour if tail
is not given a filename:
With no FILE, or when FILE is -, read standard input.
So tail
is waiting for some input to be piped in, and it will then display the last 3 lines of that input. You can actually type a few lines of text, and press Ctrl-D ("end of file"), and you'll see it happen.
This may seem pointless, but the command doesn't know (or care) that it's been invoked directly, and not as part of a pipeline. So the head -1
in your inner query is actually doing the same thing: reading standard input because you didn't give a file name.
To avoid this, you should test that your file exists first, before running tail. A non-elegant way of writing that on one line would be to capture the filename in a variable, and use [
(aka test
) to assert that it is non-empty:
(file=`ls -1t nnnn* | head -1`; [ -n "$file" ] && tail -3 $file)
This will still give you the warning from ls
that the glob failed, but will skip the hanging tail
.