Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 18, 2024
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.
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?
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.
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 COMMANDroot 12754 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.
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.
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.
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.