Is it possible to pause a command running under screen? - unix

I'm running a long executing command (currently on day 7) under screen. I would like to temporarily suspend this command to perform some other computationally expensive operation and then resume the screened command afterwards.
Is this even possible?

OK. I figured it out.
To Pause:
screen -r attaches to the screened command:
CTRL+z suspends the process.
CTRL+A d detaches from the screened command. (Do not exit.)
To Resume:
screen -r attaches to the paused screen.
fg continues the previously suspended command.
CTRL+A d detaches from the screened command, leaving it running in the background.

Related

What does “&” mean in “linkerd viz dashboard &”? [duplicate]

How can I run a shell script and immediately background it, however keep the ability to inspect its output any time by tailing /tmp/output.txt.
It would be nice if I can foreground the process too later.
P.S.
It would be really cool if you can also show me how to "send" the backgrounded process in to a GNU screen that may or may not have been initialized.
To 'background' a process when you start it
Simply add an ampersand (&) after the command.
If the program writes to standard out, it will still write to your console / terminal.
To foreground the process
Simply use the fg command. You can see a list of jobs in the background with jobs.
For example:
sh -c 'sleep 3 && echo I just woke up' & jobs
To background a currently running process
If you have already started the process in the foreground, but you want to move it to the background, you can do the following:
Press Ctrl+z to put the current process to sleep and return to your shell. This process will be paused until you send it another signal.
Run the bg command to resume the process, but have it run in the background instead of the foreground.
Another way is using the nohup command with & at the end of the line.
Something like this
nohup whatevercommandyouwant whateverparameters &
This will run it in the background and send its output to a nohup.log file.
One easy to use approach that allows managing multiple processes and has a nice terminal UI is hapless utility.
Install with pip install hapless (or python3 -m pip install hapless) and just run
$ hap run my-command # e.g. hap run python my_long_running_script.py
$ hap status # check all the launched processes
$ hap logs 4 # output logs for you 4th background process
$ hap logs -f 2 # continuously stream logs for the 2nd process
See docs for more info.

How to use xterm to launch screen with arguments

I'm currently using mobaxterm to launch xterms to connect to a remote server. I use...
xterm screen
I use screen because the connection is unreliable so screen allows me to recover sessions.
What I really want is to call "screen -RR" to reconnect sessions if there, or start a new one, but xterm doesn't allow command line arguments.
I've played around with -e, -ls, -hold, etc but I can't get it to work.
Any ideas?
[Edit]
Additional information...
I've tried...
xterm ./script.sh
with screen -RR in it, but that runs, then exits. -l or -hold doesn't help.
xterm -e /bin/bash -c screen -RR
same problem, exits without giving me a prompt.
My current hack is...
xterm ./mybash
where mybash a sym-link to /bin/bash, and I have a check in .bashrc looking for XTERM_SHELL = mybash, then launching screen -RR, but that runs 2 bash shells, so I have to exit twice to close the window.
xterm -e should work. It takes one or more arguments specifying a command (plus its arguments) to execute under xterm (so it must be the last option).
For example, this should work
xterm -e screen -RR
There's no need to invoke /bin/bash to invoke screen.

Opening a program and then waiting for it

Is there a general way to wait for an executed process that backgrounds in fish (like open "foo")? As far as I can tell, $! (the PID of the last executed child process in bash) is not present in fish, so you can't just wait $!.
1) The fish idiom is cmd1; and cmd2 or if cmd1; cmd2; end.
2) You should find that bash and zsh also don't block if you execute open ARG. That's because open will normally background the program being run then open exits. The shell has no idea that open has put the "real" program in the background. Another example of that behavior is launching vim in GUI mode via vim -g. Add the -W flag on macOS or -w on Linux to the open command and -f to the vim command.
The key here is that open, even if it backgrounds, won't return a signal that fish will use to evaluate the and operator until something happens to the opened process. So you get the behavior you're looking for.

How do you stop the current foreground process and re-execute it?

I often have to relaunch a server to see if my changes are fine. I keep this server opened in a shell, so I have a quick access to current logs. So here is what I type in my shell: ^C!!⏎. That is send SIGINT, and then relaunch last event in history.
So what I would like is to type, say ^R, and have the same result.
(Note: I use zsh)
I tried the following:
relaunch-function() {
kill -INT %% && !!
}
zle -N relaunch-widget relaunch-function
bindkey "^R" relaunch-widget
But it seems that while running my server, ^R won't be passed tho the shell but to the server which doesn't notice the shell. So I can't see a generic solution, while testing return value and process name should be feasible.
As long as the job is running in the foreground, keys will not be passed to the shell. So setting a key binding for killing a foreground process and starting it again won't work.
But as you could start your server in an endless loop, so that it restarts automatically. Assuming the name of the command is run_server you can start it like this on the shell:
(TRAPINT(){};while sleep .5; do run_server; done)
The surrounding parentheses start a sub-shell, TRAPINT(){} disables SIGINT for this shell. The while loop will keep restarting run_server until sleep exits with an exit status that is not zero. That can be achieved by interrupting sleep with ^C. (Without setting TRAPINT, interrupting run_server could also interrupt the loop)
So if you want to restart your server, just press ^C and wait for 0.5 seconds. If you want to stop your server without restarting, press ^C twice in 0.5 seconds.
To save some typing you can create a function for that:
doloop() {(
TRAPINT(){}
while sleep .5
do
echo running \"$#\"
eval $#
done
)}
Then call it with doloop run_server. Note: You still need the additional surrounding () as functions do not open a sub-shell by themselves.
eval allows for shell constructs to be used. For example doloop LANG=C locale. In some cases you may need to use (single):
$ doloop echo $RANDOM
running "echo 242"
242
running "echo 242"
242
running "echo 242"
242
^C
$ doloop 'echo $RANDOM'
running "echo $RANDOM"
10988
running "echo $RANDOM"
27551
running "echo $RANDOM"
8910
^C

Shell script task status monitoring

I'm running an ANT task in background and checking in 60 second intervals whether that task is complete or not. If it is not, every 60 seconds, a message should be displayed on screen - "Deploy process is still running. $slept seconds since deploy started", where $slept is 60, 120, 180 n so on.
There's a limit of 1200 seconds, after which the script will show the log via 'ant log' command and ask the user whether to continue. If the user chooses to continue, 300 seconds are added to the time limit and the process repeats.
The code that I am using for this task is -
ant deploy &
limit=1200
deploy_check()
{
while [ ${slept:-0} -le $limit ]; do
sleep 60 && slept=`expr ${slept:-0} + 60`
if [ $$ = "`ps -o ppid= -p $!`" ]; then
echo "Deploy process is still running. $slept seconds since deploy started."
else
wait $! && echo "Application ${New_App_Name} deployed successfully" || echo "Deployment of ${New_App_Name} failed"
break
fi
done
}
deploy_check
if [ $$ = "`ps -o ppid= -p $!`" ]; then
echo "Deploy process did not finish in $slept seconds. Here's the log."
ant log
echo "Do you want to kill the process? Press Ctrl+C to kill. Press Enter to continue."
read log
limit=`expr ${limit} + 300`
deploy_check
fi
Now, the problem is - this code is not working. This looks like a perfectly good code and yet, this is not working. Can anyone point out what is wrong with this code, please.
If the user chooses to continue, deploy_check gets run again, but there's never another opportunity for the user to continue or cancel (although Ctrl-C could be pressed at any time). So you may want to wrap that in a while loop.
Also, pressing Ctrl-C is probably not going to kill the child process. You need to prompt for yes or no and if yes do a kill $!.
Edit:
Here is how your code flows:
Call deploy_check
Loop until slept exceeds limit (it will be 1260 at that point)
Break if deployed successfully
If it's still running, prompt the user
If the user presses Ctrl-C, the script exits but ant deploy is left running (unless you have a trap set elsewhere in your script that processes the Ctrl-C and does a kill on the ant deploy process)
If the user presses enter, the limit is raised to 1500
Call deploy_check testing slept==1260 against limit==1500
Loop until slept exceeds limit (it will be 1560 at that point)
Break if deployed successfully
The script (or this section of it) ends without prompting the user again
You would need a loop to cause the prompt to occur again.

Resources