The problem is that when you run simply
Code:
loop ls -al stuff/ | wc -l
the pipe is not passed as argument to the function but it is resolved in the parent shell. This means the command at right hand side of the pipe waits for the completion of the input before giving the result. Since you have an infinite loop in the function, the wc -l command waits forever without being executed.
However, if you have a command capable of taking buffered input on the right hand side of the pipe, it works. An example is grep
Code:
loop ls -al stuff/ | grep -v drwx
If you want to monitor the number of files continuously, you have to pass a literal pipe as argument by protecting it from the shell using quotes, as you already noticed. The problem now is the way you run that string as a command inside the function. First of all you don't really need
echo, nor back ticks. Instead it has the side effect of displaying the output in a single line. If you want to run a command which is stored in a variable or in the arguments of the script, just do
or
respectively. Moreover if you have some special characters (like a pipe) that needs to be evaluated by the shell and not interpreted literally, just use
eval. In conclusion - to work with pipes, the way you expect - your function should be
Code:
loop ()
{
while true
do
clear
date
eval $@
sleep 1
done
}
Edit: Beaten by the more concise post by ta0kira!
Hko, good advice! I always forget the watch command.