Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Is there any way to make a bash script enter a certain keystroke? What I'm trying to accomplish here is a script that will run Ctrl+B to exit tmux.

EDIT: I see that several people are saying that it's better to use a program - specific command. What if I wanted to edit a text file (in this case the bash_aliases file) using a bash script?

share|improve this question
    
If you're working in X, the following may be useful: unix.stackexchange.com/questions/111007/… –  brm Feb 1 at 7:06
1  
If you want to edit a file in a script, use a scriptable text editor like ed/ex. If it's a separate question, start a new question. –  Stéphane Chazelas Feb 1 at 21:59

5 Answers 5

up vote 5 down vote accepted

If you want to interact with tmux in a script, that's where you want to use tmux ... tmux-command. Like:

tmux kill-session

To exit the current session.

tmux kill-server

To exit the server (kills all sessions).

tmux detach-client

to detach a client (exit, but you can reattach later).

share|improve this answer
    
I'm using SSH with tmux; when I run tmux kill-session, would it kill my end, or the Raspberry Pi's (what I'm SSH'ing to) end? –  evamvid Feb 1 at 17:17
    
@evamvid, tmux talks to the tmux server via a unix domain socket (whose path is in $TMUX), so it can only talk to a tmux server on the same machine, so a process can only kill the tmux session that is running on the same machine. –  Stéphane Chazelas Feb 1 at 18:58

You can use xdotool to send keystrokes, if really necessary.

xdotool search "Konsole" windowactivate --sync key --clearmodifiers ctrl+b
share|improve this answer

You can easily close tmux by executing:

pkill -term tmux

This will send tmux: "Please close yourself"

share|improve this answer

To answer the question in the title.

The way to simulate a key press in a terminal is via the TIOCSTI

For instance:

insert() {
  perl -le 'require "sys/ioctl.ph";
            ioctl(STDIN, &TIOCSTI, $_) or
              die "$!\n" for split "", join " ", @ARGV' "$@"
}

However, in the case of tmux, if you do:

insert $'\02'

within a tmux pane, that will insert the ^B character in the input buffer of the terminal of that pane, not any of the terminals attached to the current session tmux is reading its input from.

The solution would be to do:

insert $'\02' < "$(tmux lsc -F '#{client_tty}' -t '' | head -n 1)"

Where:

tmux lsc -F '#{client_tty}' -t ''

reports the terminal(s) attached to the running session.

But on modern Linux systems, that won't work (you'll get a Operation not permitted error) because, for security reasons, the TIOCSTI ioctl can only be issued to your controlling terminal (and the controlling terminal of a shell interpreting a script in a tmux pane would be the pane's terminal).

You'd have to ask tmux to do that, and I'm not sure that is possible.

share|improve this answer

Another useful *NIX tool for automating interactions with terminal programs is Expect:

http://www.nist.gov/el/msid/expect.cfm

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.