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'
Is it possible to enter keyboard shortcuts into a bash script? For example, I have tried typing in ^d to substitute for control + d (logout) without success.
ubuntu#vfleet:~$ ^d
-bash: :s^d: substitution failed
ubuntu#vfleet:~$ ^D
-bash: :s^D: substitution failed
I am using screen to run a django development server in the background. One of the commands to run a particular screen as a daemon is control + a + d. The goal is to be able to enter in control + a + d into a bash script. For example:
python manage.py runserver
^a + d
Is this possible?
Edit:
A valid method of avoiding the keyboard shortcut in screen is linked by Eric Renouf in the comments below. screen -d -m sh -c "python manage.py runserver" will start a development server as a daemon. This is a great solution for my particular problem, but it would still be nice to have a solution for the original question at hand.
xdotool package is the solution here.
xdotool key ctrl+d
Full reference
You probably should just start the command without attaching to the screen session in the first place, like
screen -d -m python manage.py runserver
but if you can't do that for some reason, you could detach from a screen session you're currently in by doing:
screen -S "$STY" -X detach
screen saves its current session info in STY, so we'll use that to make sure we're interacting with the correct session (in case there are many). Then we'll use -X to send a command to that session, in this case our command will be detach which will detach all the attached sessions, including the one used to execute that command
So while this doesn't actually send key strokes, it does highlight that there is often another command that you can send to accomplish your goals. Here detach takes the place of ctrl+a+d. Sending quit or running exit could often replace ctrl+d.
Another work-around would be to use expect which you could then use to send the strings containing control characters or hex values of them.
I have a shell script that is supposed to run a program on ubuntu. If I double click it, it asks me what I want to do:
Run in terminal, Display, Cancel, Run.
If I choose Run in terminal, it works fine. But if I press Run, nothing happens. Why?
Here's the script:
#!/bin/bash
rlwrap sicstus
Run in terminal - open a new terminal window and execute the given application / script so that you could see the output.
Run - execute the given application / script in background.
So, you won't get any output when running the script.
The script does not start the terminal emulator.
If you choose "Run in terminal", a terminal emulator is started and the executable/script is connected to the terminal.
If you choose just "Run", the script will try to read from stdin and freezes because it is not connected to a terminal.
This might work and if it does it won't matter if you choose "Run in terminal" or just "Run".
#!/bin/sh
if [ -z "$TERM" ]; then
x-terminal-emulator -e "bash -c 'rlwrap sicstus; echo Press any key; read'"
else
rlwrap sicstus
fi
I have a game server running in an xterm window.
Once daily I'd like to send a warning message to any players followed after a delay by the stop command to the program inside the xterm window from a script running on a schedule. This causes the cleanup and save functions to run automatically.
Once the program shuts down I can bring it back up easily but I don't know how to send the warning and stop commands first.
Typed directly into xterm the commands are:
broadcast Reboot in 2 minutes
(followed by a 2 minute wait and then simply):
stop
no / or other characters required.
Any help?
Do you also need to type something from the xterm itself (from time to time) or do you want your server to be fully driven from external commands?
Is your program line-oriented? You may first try something like:
mkfifo /tmp/f
tail -f /tmp/f | myprogram
and then try to send commands to your program (from another xterm) with
echo "mycommand" > /tmp/f
You may also consider using netcat for turning your program to a server:
Turn simple C program into server using netcat
http://lifehacker.com/202271/roll-your-own-servers-with-netcat
http://nc110.sourceforge.net/
Then you could write a shell script for sending the required commands to your "server".
If you know a little about C programming; I remember having once hacked the script program (which was very easy to do: code is short) in order to launch another program but to read commands from a FIFO file (then again a shell script would be easy to write for driving your program).
Something you might try is running your program inside a screen session.
You can then send commands to the session from cron that will be just
as if you typed them.
In your xterm, before launching the program do:
screen -S myscreen bash
(or you can even replace bash by your program). Then from your cron
screen -S myscreen -X stuff 'broadcast Reboot in 2 minutes\n'
sleep 120
screen -S myscreen -X stuff 'stop\n'
will enter that text. You can exit the session using screen -S myscreen -X quit
or by typing ctrl-a \.
screen is intended to be transparent. To easily see you are inside screen, you can
configure a permanent status bar at the bottom of your xterm:
echo 'hardstatus alwayslastline' >~/.screenrc
Now when you run screen you should see a reverse video bottom line. Depending
on your OS it may be empty.
When I'm done with Terminal, I want to exit it. Right now, I have three options:
killall Terminal. It will end the process, but rather abruptly. I don't think this is the best idea.
Call exit. I've changed the settings so exit closes Terminal. The app still appears open in the Dock though, and doesn't do what I want it to do.
Right click>Quit. However, this isn't a Terminal command to exit it.
So now, what is the way I should exit and close Terminal? I've heard something about osascript but I'm not too sure. I want to exit and close, so that Terminal is no longer open, both as a window and as a process.
in Terminal.app
Preferences > Profiles > (Select a Profile) > Shell.
on 'When the shell exits' chosen 'Close the window'
How about the good old Command-Q?
Actually, you should set a config on your Terminal, when your Terminal is up press ⌘+, then you will see below screen:
Then press shell tab and you will see below screen:
Now select Close if the shell exited cleanly for When the shell exits.
By the above config each time with exit command the Terminal will close but won't quit.
In the Terminal app, Preference >> Profiles tab.
Select the Shell tab on the right.
You can choose Never Ask before closing to suppress the warning.
You could use AppleScript through the osascript command:
osascript -e 'tell application "Terminal" to quit'
In a terminal window, you can type:
kill -9 $(ps -p $PPID -o ppid=)
This will kill the Terminal application process, which is the parent of the parent of the current process, as seen by the kill command.
To close a Terminal window from within a running script, you need to go up one more level in the process hierarchy like this:
kill -9 $(ps -p $(ps -p $PPID -o ppid=) -o ppid=)
I 've been using ctrl + d. It throws you out into the destination where You've started the sqlite3 command in the first place.
osascript -e "tell application \"System Events\" to keystroke \"w\" using command down"
This simulates a CMD + w keypress.
If you want Terminal to quit completely you can use:
osascript -e "tell application \"System Events\" to keystroke \"q\" using command down"
This doesn't give any errors and makes the Terminal stop cleanly.
You can also use this convoluted command, which does not trigger a warning about terminating its own process:
osascript -e "do shell script \"osascript -e \\\"tell application \\\\\\\"Terminal\\\\\\\" to quit\\\" &> /dev/null &\""; exit
This command is quite long, so you could define an alias (such as quit) in your bash profile:
alias quit='osascript -e "do shell script \"osascript -e \\\"tell application \\\\\\\"Terminal\\\\\\\" to quit\\\" &> /dev/null &\""; exit'
This would allow you to simply type quit into terminal without having to fiddle with any other settings.
Use the osascript command in your code as icktoofay mentioned: osascript -e 'tell application "Terminal" to quit'
Then, open Terminal preferences, go to Settings > Shell, and set "Prompt before closing:" to "Never." Terminal should now quit completely (not remain open in your dock) and ignore the prompt before quitting. If you have only one Terminal window open and the osascript command is your last line of code, it should wait for whatever command you ran before to finish.
This would not be ideal if you are running scripts in the same window or other windows in the background (for instance, you may run a command in the background and continue using the current window for other commands if the first command is followed by an ampersand); be careful!
If you wrap the osascript code in a shell script file, you can probably call it with whatever pithy file-name you give it---as long as it is in Terminal's search path (run echo $PATH to see where Terminal looks for scripts).
I've been using
quit -n terminal
at the end of my scripts. You have to have the terminal set to never prompt in preferences
So Terminal > Preferences > Settings > Shell
When the shell exits
Close the window
Prompt before closing
Never
Create a script:
cat ~/exit.scpt
like this:
Note: If there is only one window, just quit the application, else simulate command + w to close the tab)
tell application "Terminal"
set WindowNum to get window count
if WindowNum = 1 then
quit
else
tell application "System Events" to keystroke "w" using command down
end if
end tell
Then add a alias in your *shrc
just like vi ~/.bashrc or zshrc (anything else?)
add it:
alias exit="osascript ~/exit.scpt"
And source the ~/.bashrc or reopen your terminal.app
This is what I did for a command I just wrote. I wanted to be able to create a "shortcut" to the Backup directory for Apple Configurator that worked on different computers, but since it's relative to the user's home directory, I needed to make it a .command file. Here are the contents:
#!/usr/bin/env bash
open "${HOME}/Library/Application Support/MobileSync/Backup"
(sleep 0.1 ; osascript -e 'tell application "Terminal" to quit') &
I tried several variations of the answers here. No matter what I try, I can always find a use case where the user is prompted to close Terminal.
Since my script is a simple (drutil -drive 2 tray open -- to open a specific DVD drive), the user does not need to see the Terminal window while the script runs.
My solution was to turn the script into an app, which runs the script without displaying a Terminal window. The added benefit is that any terminal windows that are already open stay open, and if none are open, then Terminal doesn't stay resident after the script ends. It doesn't seem to launch Terminal at all to run the bash script.
I followed these instructions to turn my script into an app: https://superuser.com/a/1354541/162011
If this is a Mac you type 'exit' then press return.