How to include SPACEBAR click on bash script to unpause a rosbag? - bash

I have a script that needs to start a few ros nodes including a rosbag. Within those nodes, I need to start the rosbag with the --pause flag. Normally, I would need to press the spacebar to unpause the bag and get my script running after ~5 second. My question is, how can I get this done on a bash script?
I have tried a few different things like:
... &
(sleep 5; echo -e ' ';) & ...
or echo '\s' or echo '\r'. I know the echo command happens but that doesn't quite give the signal to the bag to start playing (unpause). If I press the spacebar even while using the script, the bag will play. How can I recreate this spacebar from my bash script?

solved this with:
xte 'key space'

Related

Execute command on second terminal in bash script

I am writing a bash script to execute 2 commands at a time on 2 different terminal & original terminal wait for both 2 terminal to finish & then continue with remaining script.
I am able to open a different terminal with required command, however the original terminal seems not waiting for the 2nd one to complete & auto close before proceeding with remaining of the script.
#!/bin/bash
read -p "Hello"
read -p "Press enter to start sql installation"
for i in 1
do
xterm -hold -e mysql_secure_installation &
done
echo "completed installation"
Use the Bash wait command to cause the calling script to wait for a background process to complete. Your for loop implies that you may be launching multiple background processes in parallel even though in your question there's only one. Without any options wait will wait for all of them.
I wonder why you're launching the processes in xterm instead of directly.

Pause script by keyboard input

(Sorry for my bad english.) I would like to pause a running script by pressing the [SPACE] bar. The script must run, until the user not press the [SPACE] bar, then pause 20 seconds, and run forth. How can i continuously watch the keyboard input while the script is running?
One way to do it:
#!/bin/bash -eu
script(){ #a mock for your script
while :; do
echo working
sleep 1
done
}
set -m #use job control
script & #run it in the background in a separate process group
read -sd ' ' #silently read until a space is read
kill -STOP -$! #stop the background process group
sleep 2 #wait 2 seconds (change it to 20 for your case)
kill -CONT -$! #resume the background process group
fg #put it in the forground so it's killable with Ctrl+C
I think the most simple way is to implement a script with checkpoints, which tests if a pause is required. Of course, it means your code never call 'long' running command...
A more complex solution is to use SIGPAUSE signal. You can have the main process that execute the script and the side process that catches [SPACE] and emit SIGPAUSE to the main process. Here I see at least two issues:
- how to share the terminal/keyboard between the 2 process (simple if your main script don't expect input from keyboard),
- if the main script starts several processes, you will have to deal with process group...
So it really depends on the complexity of your script. You may consider to rely only on regular Job control provided by Bash.
I suggest to use a controlling script that freezes you busy script:
kill -SIGSTOP ${PID}
and then
kill -SIGCONT ${PID}
to allow the process to continue.
see https://superuser.com/questions/485884/can-a-process-be-frozen-temporarily-in-linux for more detailed explanation.

Wait new terminals until die from original terminal using bash shell

I making CI build program.
I using three script
first is for build. second is for asset build. The last is for running the first and second scripts.
I want to wait for the first and second script until they done in The last script.
Here is the test script.
The first script
#!/bin/sh
sleep 1
echo test2
exit 0
The second script
#!/bin/sh
sleep 1
echo test3
exit 0
The last script
#!/bin/sh
open -a /Applications/Utilities/Terminal.app ./screenTest2.sh &
open -a /Applications/Utilities/Terminal.app ./screenTest3.sh &
wait
echo test
how can I wait new terminals die or scripts. I'm newly in OS X. So can you explain easily that solution?
Bash instructions are sequential just remove '&' character at the end of each line. Each instruction will execute one after the other. You can safely remove wait as well it will not be necessary to wait.

Bash script that will survive disconnection, but not user break

I want to write a bash script that will continue to run if the user is disconnected, but can be aborted if the user presses Ctrl+C.
I can solve the first part of it like this:
#!/bin/bash
cmd='
#commands here, avoiding single quotes...
'
nohup bash -c "$cmd" &
tail -f nohup.out
But pressing Ctrl+C obviously just kills the tail process, not the main body. Can I have both? Maybe using Screen?
I want to write a bash script that will continue to run if the user is disconnected, but can be aborted if the user presses Ctrl+C.
I think this is exactly the answer on the question you formulated, this one without screen:
#!/bin/bash
cmd=`cat <<EOF
# commands here
EOF
`
nohup bash -c "$cmd" &
# store the process id of the nohup process in a variable
CHPID=$!
# whenever ctrl-c is pressed, kill the nohup process before exiting
trap "kill -9 $CHPID" INT
tail -f nohup.out
Note however that nohup is not reliable. When the invoking user logs out, chances are that nohup also quits immediately. In that case disown works better.
bash -c "$cmd" &
CHPID=$!
disown
This is probably the simplest form using screen:
screen -S SOMENAME script.sh
Then, if you get disconnected, on reconnection simply run:
screen -r SOMENAME
Ctrl+C should continue to work as expected
Fact 1: When a terminal (xterm for example) gets closed, the shell is supposed to send a SIGHUP ("hangup") to any processes running in it. This harkens back to the days of analog modems, when a program needed to clean up after itself if mom happened to pick up the phone while you were online. The signal could be trapped, so that a special function could do the cleanup (close files, remove temporary junk, etc). The concept of "losing your connection" still exists even though we use sockets and SSH tunnels instead of analog modems. (Concepts don't change; all that changes is the technology we use to implement them.)
Fact 2: The effect of Ctrl-C depends on your terminal settings. Normally, it will send a SIGINT, but you can check by running stty -a in your shell and looking for "intr".
You can use these facts to your advantage, using bash's trap command. For example try running this in a window, then press Ctrl-C and check the contents of /tmp/trapped. Then run it again, close the window, and again check the contents of /tmp/trapped:
#!/bin/bash
trap "echo 'one' > /tmp/trapped" 1
trap "echo 'two' > /tmp/trapped" 2
echo "Waiting..."
sleep 300000
For information on signals, you should be able to man signal (FreeBSD or OSX) or man 7 signal (Linux).
(For bonus points: See how I numbered my facts? Do you understand why?)
So ... to your question. To "survive" disconnection, you want to specify behaviour that will be run when your script traps SIGHUP.
(Bonus question #2: Now do you understand where nohup gets its name?)

Detect mouse click in bash script

I'm wondering how to run a bash script in the background that will do something (i.e. run a script, or a command, or whatever) whenever a user clicks the mouse. I'd like this to continue running even if the terminal is closed. Any ideas? Thanks!
If you are using X11, you can try xdotool to catch mouse events
It would be something like:
xdotool search --onlyvisible . behave %# mouse-click getmouselocation
xdotool manual
If you want to run the script in background you can use:
./myscript.sh &>/dev/null &
if you just want to run bash command in xterm on mouse click (or wheel event) you can try this example:
$ echo -e "\e[?1000h"
$ while read -n 6; do echo hellowworld; done
this is for wheel event (for click set 12 instead)
To keep the script running even when terminal is closed you may try nohup.

Resources