How to use watch command with a piped chain of commands/programs

I usually use watch Linux utility to watch the output of a command repeatedly every n seconds, like in watch df -h /some_volume/.

But I seem not to be able to use watch with a piped series of command like:

$ watch ls -ltr|tail -n 1

If I do that, watch is really watching ls -ltr and the output is being passed to tail -n 1 which doesn’t output anything.

If I try this:

$ watch (ls -ltr|tail -n 1)

I get

$ watch: syntax error near unexpected token `ls'

And any of the following fails some reason or another:

$ watch <(ls -ltr|tail -n 1)

$ watch < <(ls -ltr|tail -n 1)

$ watch $(ls -ltr|tail -n 1)

$ watch `ls -ltr|tail -n 1)`

And finally if do this:

$ watch echo $(ls -ltr|tail -n 1)

I see no change in the output at the given interval because the command inside $() is run just once and the resulting output string is always printed (“watched”) as a literal.

So, how do I make the watch command work with a piped chain of commands [other that putting them inside a script]?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

watch 'command | othertool | yet-another-tool'

Method 2

watch -n 1 "ls -lrt | tail -n20; date"

let’s you pipe and run in a row.

Method 3

Use a combination of single quotes (') and double quotes ("). For example:

watch -n 1 "links -dump 127.0.0.1/server-status | grep -e 'S' -Fe 'www.'"

Method 4

If you would like to list all files in subdirectories too, you can use find command with exec option.

watch will update every 30 seconds and find will search for all *.log files in current dir (subdirs included) and will print filenames and their last 10 line:

watch -n30 'find . -name "*.log" -print -exec tail -n10 {} ; '

Method 5

I have just made a little bit more complex pipe chain for watching ElasticSearch nodes’ performance. It requires handling variables as well as variable escaping. Hope it may be helpful to others.

watch -dn1 'kubectl exec elasticsearch-master-0 -c elasticsearch -- 
  curl -s XGET "localhost:9200/_cat/nodes?h=hp,hc,hm,rp,r,rm,cpu,dup,du,dt,m,n&v" |
  (read -r; printf "%sn" "$REPLY"; awk "{print $NF,$0}" |
  sort | cut -f2- -d" ")'

Method 6

The simplest way is using inbuilt option -x,

watch -n 5 -x tail -4 output.log  
watch -n 2 -x ls

The first eg. will display the last 4 lines of output.log file every 5 sec., second eg list content every 2 sec.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x