Watch Command – How to Reload Variable

quotingshellvariable substitutionwatch

Part of my job involves some data handling. One of the tasks is to 'flatten' a set of directories (which we'll call Dir for now), and copy them to a new location called DirFlat.

This can take a long time (30 minutes ->2-3 hours)! I'd like to be able to watch the progress, so I use find Dir -type f|wc -l to get the number of files (lets call this $Filenum, and then I run a very short command that I wrote (retyping from my notebook, may have copied it wrong, I hope you get the gist):

echo $(echo "($ls DirFlat |wc -l)*100/$FileNum"|bc) "%" $(date)

However, if I run watch -n 100 "!!" it takes the output of the echo, and keeps printing that (even the date doesn't change).

Can I get this to refresh the variable/re-run the assignment of the internal variables in BASH? Hopefully this will help me in automating some of my tasks.

Best Answer

Contrast:

$ watch -n 1 "echo $(date)"
Every 1.0s: echo Sat Apr 27 03:10:50 CEST 2013

$ watch -n 1 'echo $(date)'
Every 1.0s: echo $(date)

What you've done is to run echo "($ls DirFlat |wc -l)*100/$FileNum"|bc and date, substitute the output of each command into the shell command watch -n 100 "echo $(…) % $(…)", and run that. You need to prevent the expansion of the command in the parent shell, and instead pass it as a string to watch for it to run. This is a simple matter of using single quotes around the command instead of double quotes.

Related Question