Reputation: 77
Hi i run a command on Linux server.
tail -3 `ls -1t nnnn* | head -1`
When nnnn file exist, all good.
When nnnn file not exist the tty is hanged until ^C
nt-home-stg>> tail -3 `ls -1t nnnn* | head -1`
ls: No match.
After the ls: No match.
it hangs until ctrl c (^c) is pressed.
I've searched the web and could not find an answer.
Already tried the traditional suppress >& /dev/null
and 2>/dev/null
. Did not help.
Is there a way for the command to end and not hang?
Upvotes: 1
Views: 256
Reputation: 97638
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
.
Upvotes: 2