Most shells provide functions like &&
and ;
to chain the execution of commands in certain ways. But what if a command is already running, can I still somehow add another command to be executed depending on the result of the first one?
Say I ran
$ /bin/myprog some output...
but I really wanted
/bin/myprog && /usr/bin/mycleanup
. I can’t kill myprog
and restart everything because too much time would be lost. I can Ctrl+Z it and fg
/bg
if necessary. Does this allow me to chain in another command?
I’m mostly interested in bash, but answers for all common shells are welcome!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You should be able to do this in the same shell you’re in with the wait
command:
$ sleep 30 & [1] 17440 $ wait 17440 && echo hi ...30 seconds later... [1]+ Done sleep 30 hi
excerpt from Bash man page
wait [n ...]
Wait for each specified process and return its termination status. Each n
may be a process ID or a job specification; if a job spec is given, all
processes in that job's pipeline are waited for. If n is not given, all
currently active child processes are waited for, and the return status is
zero. If n specifies a non-existent process or job, the return status is
127. Otherwise, the return status is the exit status of the last process
or job waited for.
Method 2
fg
returns with the exit code from the program it resumes. You can therefore suspend your program with ^Z and then use fg && ...
to resume it.
$ /bin/myprog some output... <kbd>^Z</kbd> [1]+ Stopped /bin/myprog $ fg && /usr/bin/mycleanup
Method 3
Not sure if what you’re asking for is possible, but if you still have the shell you started the program from, you can always check $?
for the last process’ exit status:
$ /bin/myprog some output... $ if [ $? -ne 0 ];then echo "non-zero exit status";else echo "0 exit status";fi
Method 4
If the job is in the foreground, either of these commands would have the same behavior as you expect.
[ $? -eq 0 ] && prog2 (( $? )) || prog2
NOTE: $? will contain the return status of the running program when it exits.
This is explicitly stating what the shell would do if you had originally entered the command.
prog1 && prog2
If the first command is not reading from
stdin
and is running in the foreground, the new command can be entered while the first command is running. The shell will read and execute it when the first command executes. If the command will run in the background, it is unlikely it is reading stdin
.
EDIT: Putting the job in the background and using the WAIT
command could also be used. This must be done with care if other jobs have also been run in the background. A job specification is required to have the WAIT
command return the status of the job waited on.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0