1. Overview

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    PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

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.

8. Conclusion

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.