I have several Linux (Ubuntu 10.04) processes running on my computer. If I start one of them, I can see the verbose of it on my terminal. I have an other process that start a dozen of those processes so that they run in background. However, I would like to watch the output of one of these processes to see if the output is still ok and there are no error message. I know I could send everything into a log message, however, this would just use too much disk space. So, is there a way to "catch" the output of a running process in Linux using it's process Id?
You can attach gdb to your running process and redirect stdout/err or both to some log file whenever you feel like looking at the output (make sure the files exist before redirecting):
gdb attach PID
(gdb) p dup2(open("/tmp/mylogfile-stdout", 0), 1)
(gdb) p dup2(open("/tmp/mylogfile-stderr", 0), 2)
(gdb) detach
(gdb) quit
When you want them to go back to being silent just do:
gdb attach PID
(gdb) p dup2(open("/dev/null", 0), 1)
(gdb) p dup2(open("/dev/null", 0), 2)
(gdb) detach
(gdb) quit
The 'detach' part is important, otherwise you will kill the process you're attached to when gdb exits. For more details see this question.
Use redirection like
yourprogram arg1 arg2 > yourprog.out
or probably even (to redirect both stderr & stdout and run in the background)
yourprogram arg1 arg2 > yourprog.out 2>&1 &
In a different terminal, do
tail -f yourprog.out
With the -f option, the tail command will notice when the file is growing and will display its newest lines
But I can't see portable way to redirect after. Maybe screen, batch, at, cron might help you. Or opening the /proc/1234/fd/1 ...
BTW, I am surprised you don't have enough temporary disk space for your output...
And I do like running M-x shell under emacs, and running my programm there.
Best way to do is to check fd folder in /proc/<PID>/fd
in my case I have a python running on the system with a different terminal
I can see its logs by :
1. Get Process ID
ps -aux | grep python
2. CD into /proc/504951/fd and view all/needed files
cd /proc/504951/fd && tail -f *
Related
What I know and what I've tried: I have a script in R (called GAM.R) that I want to run in the background that outputs .rdata, .pdf, and .jpg files. Running this from the command line is relatively simple:
$ Rscript GAM.R
However, this code takes a very long time to run so I would love to send it to the background and let it work even after I have logged out and turned the computer off. I understand this is pretty easy, as well, and my code would look like this:
$ nohup Rscript GAM.R >/dev/null 2>&1 &
I used this to see if it was working:
$ fg
nohup Rscript GAM.R > /dev/null 2>&1
The problem: I don't know how to check if the code is working (is there a way I can see its progress?) and I don't know where the outputs are going. I can see the progress and output with the first code so I must not be too far off. It doesn't seem that the second code's outputs are going where the first code's outputs went.
Your command line is diverting all output to /dev/null aka, The Bit Bucket.
Consider diverting it to a temporary file:
$ nohup Rscript GAM.R >/tmp/GAM.R.output 2>&1 &
Then you can tail /tmp/GAM.R.output to see the results, it will show the last 10 lines of the file by default. You can use tail -f to show the end of the file, plus new output in real time.
Note, the /tmp/ filesystem is not guaranteed to exist between reboots. You can put the file somewhere else (like ~/GAM.R.output if you need to be sure.
Note, however, that if you turn your computer off, then all processing gets aborted. For this to work your machine must continue to run and not go to sleep, or shutdown.
What you are doing is that with the > you are redirecting the output of your script to /dev/null and by doing 2>&1 you are redirecting the error output to the same place. Finally nohup executes your process and detach it from the current terminal.
So to sum up what you are doing is creating a process and redirecting its output and error output to a file called null that is stored under /dev.
To answer your question I suggest you redirect your outputs to a folder that you can access as normal user and not super user. Then to make sure that everything is ok you can print this file.
For example you can do :
nohup Rscript GAM.R >/home/username/documents/output_file 2>&1 &
and then to see the file from a terminal you can do:
cat /home/username/documents/output_file
Lastly I don't think that your program will keep on running if your turn off your pc and I don't think there is a way to do that.
If you want to run your program in the background and access the output of the program you can easily do that by writing
exec 3< <(Rscript GAM.R)
And then when you wish to check the output of the program run
cat <&3 # or you can use 'cat /dev/fd/3'
Excellent! Thanks everyone for your helpful answers, particularly #Greg Tarsa. Ultimately I needed to use:
$ nohup Rscript GAM.R >/usr/emily/gams/2017_03_14 2>&1 &
The above is used to run the script and save the screen output to emily/gams (called "2017_03_14", a file to be made by the command, not a folder as I had origionally thought). This also outputs my .rdata, .pdf, and .jpg output filesf from the script to usr/emily.
Then I can see progress and running programs using:
$ tail -f 2017_03_14 #Shows the last 10 lines of the program's progress
$ ps #shows your running projects
$ ps -fu emily #see running projects regardless of session, where username==emily
In the spirit of completeness, I can also note here that to cancel a process, you can use:
$ kill -HUP processid #https://kb.iu.edu/d/adqw
So, I have this interactive program that is running on an embedded linux ARM platform with no screen and that I cannot modify. To interact with it I have to ssh into the embedded linux distro, and run the program which is some sort of custom command line with builtin commands, and it does not exit, only SIGINT will quit the program.
I'm trying to automate it by letting it run in the background and communicate with it using pipes by sending SSH commands like this ssh user#host echo "command" > stdinpipe. This part works, I've been provided with an example like this in a shell script (I cannot use bash, I only have ash installed on the machine) :
#!/bin/sh
mkfifo somePipe
/proc/<PID>/exe < somePipe 2>&1 &
I can now easily command the program by writing to the pipe like
echo "command" > somePipe
and it outputs everything inside the terminal. The problem is that while it works if I have an SSH session open, it won't if I only send commands one by one as I said earlier (I'm using paramiko in python with the exec_command() method, just in case, but I don't think that is relevant, I could use invoke_session() but I don't want to have to deal with recv())
So I figured out I'd redirect the output of the program to a pipe. That's where problems arise. My first attempt was this one (please ignore the fact that everything is run as root and stored in the root home folder, that's how I got it and I don't have the time to make it cleaner now, plus I'm not the one managing the software) :
cd /root/binary
mkfifo outpipe
mkfifo inpipe
./command_bin &
# find PID automatically
command_pid=$(ps -a | egrep ' * \.\/command_bin *' | grep -v grep | awk '{print $1}')
/proc/${command_pid}/exe < inpipe 2>&1 &
echo "process ./command_bin running on PID ${command_pid}"
That alone works within the terminal itself. Now if I leave the SSH session open and open another terminal and type ssh root#host "echo command > /root/binary/inpipe" the code gets executed, but then it outputs the command I just typed and its result into the other terminal that stayed open. So it is obviously not an option, I have to capture the output somehow.
If I change ./command_bin & for ./command_bin >outpipe & the program never starts, I have no idea why, I know that because $command_pid is empty and I cannot find the process with ps -A
Now if instead I replace /proc/${command_pid}/exe < inpipe 2>&1 & with /proc/${command_pid}/exe < inpipe &>outpipe & the program starts, I can write to inpipe just fine with echo "command" > inpipe when the script finished running, however if I try any of cat < outpipe, tail outpipe it just hangs, and does nothing. I've tried using nohup when starting the command but it doesn't really help. I've also tried using a normal file for redirecting the output instead of a fifo, but with the exact same results.
I've spent the entire day on this thing and I cannot get it to work. Why is this not working ? Also I am probably just using an awful way to do this, is there any other way ? The only thing that's mandatory here is that I have to connect through ssh to the board and the command line utility has to stay open because it is communicating with onboard devices (using I2C, OneWire protocols etc).
To keep it simple I want to be able to write to the program's stdin whenever I want, get its stdout to go somewhere else (some file, buffer, I do not care) that I can easily retrieve later after an arbitrary amount of time with cat, tail or some other command with ssh.
Is there a way to automatically start a process under gdb on Linux? An equivalent of setting the Image File Execution Options on Windows.
I am trying to debug start-up phase of a process that is launched from another one.
I would normally move the real program out of the way, and replace it with a script that launches the program under GDB with the same parameters.
#!/bin/bash
exec gdb -args <realprog> "$#"
If that doesn't work due to the output being redirected to file, or something, then try this:
#!/bin/bash
exec xterm -e gdb -args <realprog> "$#"
That should give you a pop-up terminal with GDB running inside.
You don't have to go through all that registry voodoo on Linux :)
Simply:
1) Rename your program
2) Write a shell script that calls gdb with your (renamed) program and passes any arguments you want. Make sure you "chmod +rx" your script.
3) Name the shell script the original name of your program, and put it in the same directory as your program
4) Execute!
Program is dumping to stdout and while I try to type new commands I can't see what I'm writing because it gets thrown along with the output. Is there a shell that separates commands and outputs? Or can I use two shells where I can run commands on one and make it dump to the stdout of another?
You can redirect the output of the program to another terminal window. For example:
program > /dev/pts/2 &
The style of terminal name may depend on how your system is organized.
There's 'more' to let you pageinate through output, and 'tee' which lets you split a programs output, so it goes to both stdout and to a file.
$ yourapp | more // show in page-sized chunks
$ yourapp | tee output.txt // flood to stdout, but also save a copy in output.txt
and best of all
$ yourapp | tee output.txt | more // pageinate + save copy
Either redirect standard output and error when you run the program, so it doesn't bother you:
./myprog >myprog.out 2>&1
or, alternatively, run a different terminal to do your work in. That leaves your program free to output whatever it likes to its terminal without bothering you.
Having said that, I'd still capture the information from the program to a file in case you have to go back and look at it.
I've got a program running in a GNOME Terminal, but the screensaver is acting up and won't let me back in with my password. While waiting for a fix for the gnome-screensaver bug, is there some way to see the output (or even take over the process) in a virtual console (Ctrl-Alt-F1) without being able to interact with the GNOME Terminal?
Clarification: The original issue was the screensaver, but the question I'd like answered is how to see the output from a process running in another terminal, after starting the process without any logging to file. I'm guessing it should be possible to set the output device of a process from a different shell? Or is it possible to put a process in another shell into background mode, and get it into the foreground in the current shell? Or even ask GNOME Terminal to redirect or copy the output?
I've had luck in the past killing the screensaver from a virtual console, unlocking X session.
# Get the pid (xscreensaver, gnome-screensaver, etc.)
ps -f -u $(whoami) | grep screensaver
kill -9 12345 # Replace 12345 with the real pid
EDIT: Seems like this has been thought of, and you should use one of these commands, depending on which screensaver program you use:
xscreensaver-command -exit
gnome-screensaver-comand --exit
See the man page for those commands for more details.
Usual way is to pipe the output to a file, like program > program.log
Do tail -f program.log in another tab of Gnome console, and the same in the non-X console.
Alternatively, use tee to duplicate the output in the same console: program | tee program.log
ssh in to the box. kill the screensaver. su to become root and kill -9 if it's really acting up.
Usually Gnome-Terminal displays the output of one vty out of /dev. So just connect your console to that vty.
Launch program with screen.
Open another terminal, launch screen -x and you have two terminals acting like one. Try it, it's fun :)