1. Introduction
In essence, watch takes a command as its argument and runs it at given intervals, refreshing the screen with the result, possibly alongside some additional data.
In this tutorial, we look at ways to capture the stream of output watch generates and store it in a file. First, we explore the output of the command. Next, we delve into two methods for capturing parts of that output. Finally, we discuss an alternative approach, providing an example.
We tested the code in this tutorial on Debian 11 (Bullseye) with GNU Bash 5.1.4 and procps-ng watch 3.3.17. It should work in most POSIX-compliant environments.
2. watch Output
The main idea of watch boils down to showing snapshots of the command output:
$ watch date
Every 2.0s: date xost: Thu Mar 03 00:06:56 2023
Thu 03 Mar 2023 00:06:56 AM EDT
Notably, we can see a default header, which we can dissect left-to-right:
- rerun and refresh interval (Every 2.0s)**
- command to run (date)
- hostname (xost)
- current date and time (Thu Mar 03 00:06:56 2023)
The rest of the screen comprises the results from the given command run. In fact, to leave only the command output on each refresh, we can use the –no-title or -t flag.
3. Store watch Output
Depending on our needs, we can use two main techniques to preserve data from each watch screen. In particular, both leverage tee:
$ watch date | tee --append output
The tee command directs output to the screen and appends it to a provided file at the same time via the –append or -a flag.
3.1. Whole Screen
Notably, watch formats via control characters. In fact, we can get a sense of that with a simple experiment:
$ watch date | tee --append watch_output
[...]
[Ctrl+C]
$ cat --show-all watch_output
^[[?1049h^[[22;0;0t^[[1;36r^[(B^[[m^[[4l^[[?7h^[[H^[[2JEvery 2.0s: date^[[1;42Hxost:
Thu Mar 03 00:06:56 2023^[[3;1HThu 03 Mar 2023 00:06:56 AM EDT^
[[36;71H^[[1;65H31^[[3;23H31^[[36;71H^[[1;66H3^[[3;24H3^[[36;71H^[[1;66H5^
[[3;24H5^[[36;71H^[[?1049h^[[22;0;0t^[[1;36r^[(B^[[m^[[4l^[[?7h^[[H^[[2J[...]
Here, the cat –show-all or -A switch allows us to see all special characters:
- line endings are $ dollar signs like with the –show-ends or -E flag
- tabs are ^I like with the –show-tabs or -T flag
- all other special characters use the –show-nonprinting or -v notation
Notably, watch doesn’t constantly clear and refresh the whole screen. On the contrary, to optimize, it uses a series of operations:
- character changes
- caret relocations
- formatting
Thus, we get the initial screen and then only append atomic corrections.
Because of this, preserving the output as watch generates it is rarely as useful unless we then stream the resulting file to basically “replay” the process. The same holds true when we use the –no-title flag.
3.2. Command Output
To avoid the control characters from watch, we can put quotes around its argument and redirect output there:
$ watch 'date | tee --append output'
Every 2.0s: date | tee --append output xost: Thu Mar 03 00:06:56 2023
Thu 03 Mar 2023 00:06:56 AM EDT
[...]
[Ctrl+C]
$ cat --show-all output
Thu 03 Mar 2023 00:06:56 AM EDT$
Thu 03 Mar 2023 00:06:58 AM EDT$
Thu 03 Mar 2023 00:07:00 AM EDT$
[...]
Now, we see only the output of data, line by line. Furthermore, as a side effect, the whole date | tee –append output command is part of the watch header.
However, we can bypass watch altogether if we don’t require the header.
4. Watch Script Alternative
Of course, we can usually leverage the shell to create a simple script that mimics watch and capture its output:
while true; do clear; date | tee --append output; sleep 2; done
Thu 03 Mar 2023 00:06:56 AM EDT
[...]
[Ctrl+C]
$ cat --show-all output
Thu 03 Mar 2023 00:06:56 AM EDT$
Thu 03 Mar 2023 00:06:58 AM EDT$
Thu 03 Mar 2023 00:07:00 AM EDT$
[...]
Although the script is a bit heavier and perhaps less convenient than watch, the resulting file from both is equivalent.
On the positive side, we can add arbitrary complexity and have much more flexibility with a script when compared with watch alone:
- run multiple commands
- redirect to different files
- replace the true loop-driving expression with conditions more intricate than exit on change
Still, it’s up to each case whether the script replacement is adequate.
5. Summary
In this article, we talked about the output of watch and how to capture that in a file.
In conclusion, there are two main options to redirect data from watch screens to a file, but we can also employ a shell script if more flexibility is needed.