I've heard that the shift + tilda + period is supposed to close a hanging ssh pipe, but I can not simply ever get it to work. So my question to stackoverflow is, how do I gracefully close a broken SSH pipe on OSX?
When I type <enter> ~ . I leave the ssh session. This is on a German keyboard where I have to type <alt>+n <space> (where <alt>+n means to press n while holding down the alt key) to get a tilde. So the key sequence is for me: <enter> <alt>+n <space> ..
Related
I've been setting up my terminal and I have zsh-vi-mode which gives me modal editing at the command line. I live in tmux, and I recently had the idea of replacing the tmux prefix with my vim leader key (space) when in normal mode in zsh.
Essentially, what I'd like to be able to do is alias space to ctrl+b (the tmux prefix) only when in normal mode.
I've been able to somewhat accomplish this with the following in my .zshrc:
function vim_to_tmux_leader() {
osascript -e 'tell application "System Events" to keystroke "b" using {control down}'
}
# The plugin will auto execute this zvm_after_lazy_keybindings function
function zvm_after_lazy_keybindings() {
zvm_define_widget vim_to_tmux_leader
# In normal mode, press Ctrl-B to access tmux
zvm_bindkey vicmd ' ' vim_to_tmux_leader
}
This is clearly an ugly hack as I use apple script to send the ctrl b keystrokes to my terminal. Although it works, there's significant latency such that I have to wait ~0.5s after pressing space before I can press any tmux hotkey for them to register correctly.
I feel like there has to be a better way to do this. Is there a way to (1) send key combinations back to the terminal from zsh natively or (2) somehow buffer any subsequent keypresses after space to wait until the osascript command has finished executing?
Well... a simple solution is to use tmux from the command line and directly create the commands I want:
function tmux_vsplit() {
tmux split-window -v
}
function tmux_hsplit() {
tmux split-window -h
}
function zvm_after_lazy_keybindings() {
zvm_define_widget tmux_vsplit
zvm_define_widget tmux_hsplit
zvm_bindkey vicmd ' v' tmux_vsplit
zvm_bindkey vicmd ' h' tmux_hsplit
}
This doesn't give the freedom of being able to properly enter the prefix combo, but it gets the job done!
Try this in a bash:
while true; do sudo ls; done
If not enter the correct password, this loop can not be stopped by Ctrl+C, Ctrl+\ and Ctrl+D.
Edit: This should not happen in a carefully-written realworld script. I am just curious that if there is a way to escape the loop just with some keyboard shortcuts.
In order to use keyboard shortcut other than Ctrl+C, Ctrl+\ and Ctrl+D.
just use ctrl-z tp pause the process to send it to background and then kill it.
in your command while true; do sudo ls; done
i paused it using ctrl-z and then tried to brought it in foreground using fg.It exits even without killing because when i brought it to foreground only sudo ls was executed..
I am currently writing a Dockerfile, and I one of the commands I want to execute requires the user to press [ENTER], for example:
Press [ENTER] to continue or Ctrl-c to cancel adding it.
I know that on some commands when it requires a [Y/n] the -y flag will suffice; however, in some commands such as this one, it requires a physical key press. Therefore, I would like you to please help me solve this issue.
How does one send a [ENTER] key press as a flag in a Dockerfile?
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 want to make a script that starts a program and then sends it key input. In psuedo-script:
#!/bin/bash
./program << (PRESS CONTROL-Z)
The program is running so if there were additional commands in the script they will not be reached unless say control-z terminates the program.
Is this possible? From what I've found I thought it might require key codes but I could be wrong.
This I think is probably a better solution than "expect" since it can be executed in native bash script, I'll be interested to see what you think.
Use
`printf "character code here"`
note the backticks
So for instance I have written a script that controls a remote gnu screen session, the following line opens window 2 and issues the ctrl-c key combo
ssh -t user#$host screen -p 2 -X stuff `printf "\003"`
The -t option simulates terminal input on the remote machine
-p allows us to specify the name or number of the window we are connecting to within the screen session.
\003 is the bash format of character code 0x03
See here for a complete reference of codes.
To find the code of some key input you can use
printf "%#x\n" "'X"
0x58
Were X is the key you want to find the code of
To find codes of non literals you can use ctrl-v (makes bash append the next key to the command line rather than intepret it) and then type the key combo, so if I wanted to find the key code for ctrl-c I would delete the X press ctrl-v and then press ctrl-c.
One last thing the ascii code reference mentioned above lists 0x13 as the carriage return, but in the screen manual they list 0x15 as the enter key code, does anyone know why? Ive tested in a local screen and when I press enter 0x13 is produced, but when sending commands via ssh to a remote screen 0x13 doesn't work but 0x15 does.
Hope that helps
Piers
You might be looking for expect (from http://expect.nist.gov/). This deals with the complexities of pseudo-ttys that make it appear to the program that the input from the script (in this scenario, the expect program) is coming from a terminal.
Alternatively, you might be able to use echo or cat and pipe the output of that into the program - it depends on the program.
If you just want the program to start in the background, just do
#!/bin/bash
./program&
If your intent is to background the program, use:
./program & # The & sends the command to the background
echo commands here are executed while program is in the background
…
wait # Wait for the completion of background commands
echo commands here are executed after background program has completed
Edit: If your intent is to stop the program (as ctrl-Z often does in *nix shells), you can send it the STOP signal:
kill -STOP pid
To resume the execution, send it the CONT signal:
kill -CONT pid
In each of these examples pid is the process id of the program. If you launch it in a script, it's easy to get with the variable $!, e.g.
./prog &
echo prog started in the background
pid_of_prog=$!
kill -STOP $pid_of_prog
echo prog stopped
kill -CONT $pid_of_prog
echo prog continues
wait
echo prog finished
Edit 2: If your program is one that exits when it receives a ctrl-Z character, then remember that the control characters have the numerical value of the position letter in the alphabet (i.e. Ctrl-A is 1, Ctrl-B is 2, etc.). To send this character to a program you can:
echo -e "\032" | ./prog
(032 is 26, i.e. ^Z, in octal. Of course you can produce the same character by any means, perhaps adding it to the end of other input like ( cat inputfile ; echo -e "\032" ) | ./prog.
But this may not necessarily work; the program must be designed to recognise this character from the input (which it probably won't); usually the shell catches it. Then again, most programs reading input from stdin just exit when the input ends, so redirecting any finite input (even </dev/null) should cause it to terminate.
And, finally, if the intent was to stop the execution of the program when some other event (detected elsewhere in the script) has occurred, you can just kill it…