There are occasional times when we run commands or scripts, and we need to observe their output in real-time. However, that output might not have been directed to our current terminal.
In this tutorial, we’ll look at how to view command output in another Bash session. We’ll do this without interrupting the process.
2. Example Long Running Script
Imagine we had a script called Baeldung_Categorization.sh that organizes Baeldung articles into directories according to topic:
#!/bin/bash grep -riH 'java' ~/articles/* >> Java grep -riH 'kotln' ~/articles/* >> Kotlin grep -riH 'scala' ~/articles/* >> Scala grep -riH 'computer science' ~/articles/* >> Computer_Science grep -riH 'linux' ~/articles/* >> Linux
Given the volume of articles in the Baeldung archive, this process might run for quite some time. Running the script ($ ./Baeldung_Categorization.sh) will not display any output to our terminal.
How can we observe the script’s progress?
3. Using tail or cat on an Output File
With this method, we redirect the script’s output to a file:
$ ./Baeldung_Categorization.sh > file1
Next, in the new Bash session, we run the tail command on that output file:
$ tail -f file1
We should see a stream of the running command’s output.
Let’s try replacing tail with cat:
$ cat file1
Unlike tail, cat doesn’t stream all the data as it arrives but prints out the progress so far and then ends. cat is useful when we’re primarily interested in a snapshot of the running process’s output. Conversely, tail -f follows the running process until we hit CTRL-C to stop it.
4. Using strace
In a separate Bash session, we must first run ps to list the running processes:
$ ps -ef
From here, we locate the process ID of the running command. This would be under the PID column of the record of the command statement:
USER <strong>PID</strong> %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root <strong>12754</strong> 0.0 0.0 48304 1344 pts/0 S+ 17:12 0:00 Baeldung_Categorization.sh
strace then tracks system calls and signals:
$ sudo strace -p12754 -s9999 -e write
With this command, we use its -p option for the process ID. We also use the -s9999 option to indefinitely expand the string size output. The default string size is 32 characters. Finally, we use the -e write option to allow ASCII and hexadecimal characters.
This method is commonly used as we don’t need to set up any redirection to a file, and we can choose to do it after the process is started.
5. Using nohup
nohup enables us to run commands without hangups, and it posts the output to a non-tty:
$ sudo nohup Baeldung_Categorization.sh
Next, in the new Bash session, we can use tail on nohup.out. This is a file that contains the command statements output:
$ tail -f nohup.out
This yields a stream of the running command’s output.
As we observed in section 3, we can also substitute tail with cat.
6. Observing the Output via /proc
We can view the output using the Linux /proc directory. This method is one we can use if the process itself is already redirecting to a file in its core operation:
$ ./Baeldung_Categorization.sh > file1
Next, we use the tail command to display the process’s output as the file grows.
$ sudo tail -f /proc/12754/fd/1
A constant stream of the process’s output will appear on our new Bash session.
This method works because /proc folder hosts subdirectories with virtual streams of each running process. The subdirectories are named after the process IDs. The /fd folder after process ID is the file descriptor. It logs the streams for the processes, i.e., stdout, stderr, and other outputs. stdout is the output stream of our interest which is /fd file 1.
As in the previous sections, we can replace tail with cat.
7. Using watch (Specific to BSD)
If we’re running a BSD platform, we could use the watch command to observe the script’s output. Therefore, after running the script in one session, on the new session, we can run watch:
$ watch /dev/pts/0
/pts stands for pseudo terminal slave. This is a folder that the kernel produces to list the contents of running processes. In that /dev/pts folder, file 0 is that file with the virtual stream of the script.
In this article, we have seen a few ways to observe a running process’s output in a separate Bash session.
First, we looked at how to tail or cat a file to which the process was actively writing. Then, we used the strace command, which follows after system calls and signals.
We used the nohup command, which funnels the output of a running process to nohup.out. We also explored displaying the output using the /proc folder.
Finally, we used the watch command to display the running process’s output.