Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BASH function with tmux send-keys

Tags:

bash

tmux

I'm having problems putting "send-keys" into a bash function. Here's a minimal example:

function keys {
  tmux send-keys -t work:1 $*
}

tmux new-session -d -s work
keys "pwd" c-m "ls -latr" c-m
tmux attach-session -t work

The keys argument here is exactly what I'd type on the command-line as an argument to tmux send-keys. It almost works, but strips spaces, so I see ls-latr all as one word. But if I put quotes around the $* in the function, it just outputs the entire keys argument on one line (treating the c-m as literal characters). How could I make it execute the send-keys argument as if I'd typed it from command-line?

like image 870
mahemoff Avatar asked Dec 09 '22 16:12

mahemoff


1 Answers

You should use "$@" (the quotes are important) instead of $* in your shell function; it will preserve the positional parameters exactly as they are supplied in the function invocation.

function keys {
  tmux send-keys -t work:1 "$@"
}

With "$@", the final command will get the four original arguments:

tmux send-keys -t work:1 'pwd' 'c-m' 'ls -latr' 'c-m'

Instead of the five from unquoted $*:

tmux send-keys -t work:1 pwd c-m ls -latr c-m

Or the one from "$*":

tmux send-keys -t work:1 'pwd c-m ls -latr c-m'

When unquoted, $* and $@ are effectively identical, but they are significantly different when unsed in double quotes.

  • $* and $@ are like $1 $2 $3 …

    The resulting values are subject to word splitting and filename expansion (a.k.a. globbing), so you usually do not want to use these (or any other parameter expansions) without double quotes.

    The additional word splitting is why your "ls -ltr" (one argument to key) becomes ls -ltr (two arguments to tmux send-keys).

  • "$*" is like "$1 $2 $3…"

    All the positional parameter values are joined into a single “word” (string) that is protected from further word splitting and globbing.

    The character that is put between each positional parameter value is actually the first character from IFS; this is usually a plain space.

  • "$@" is like "$1" "$2" "$3" …

    Each positional parameter is expanded into a separate word and they are protected from further word splitting and globbing.

like image 170
Chris Johnsen Avatar answered Dec 28 '22 15:12

Chris Johnsen