我在将“发送密钥”放入bash函数时遇到问题。这是一个最小的例子:
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
这里的keys参数正是我在命令行上键入的tmux send-keys
的参数。它几乎可以工作,但剥离空格,所以我将ls-latr
全部视为一个单词。但是如果我在函数中的$*
周围加上引号,它只会在一行上输出整个键参数(将c-m
视为文字字符)。我怎么能让它执行send-keys参数,就像我从命令行输入它一样?
答案 0 :(得分:13)
您应该在shell函数中使用"$@"
(引号很重要)而不是$*
;它将保留与函数调用中提供的位置参数完全相同的位置参数。
function keys {
tmux send-keys -t work:1 "$@"
}
使用"$@"
,最后一个命令将获得四个原始参数:
tmux send-keys -t work:1 'pwd' 'c-m' 'ls -latr' 'c-m'
而不是来自不带引号的$*
中的五个:
tmux send-keys -t work:1 pwd c-m ls -latr c-m
或来自"$*"
的那个:
tmux send-keys -t work:1 'pwd c-m ls -latr c-m'
如果不加引号,$*
和$@
实际上是相同的,但在双引号中使用时它们会有很大不同。
$*
和$@
与$1 $2 $3 …
结果值受到单词拆分和文件名扩展(也称为通配)的影响,因此通常 不想要使用这些(或任何其他参数扩展)双引号。
额外的单词拆分是您"ls -ltr"
(key
的一个参数)变为ls -ltr
(tmux send-keys
的两个参数)的原因。
"$*"
与"$1 $2 $3…"
所有位置参数值都连接成一个单词“word”(字符串),以防止进一步的单词拆分和通配。
每个位置参数值之间放置的字符实际上是IFS中的第一个字符;这通常是一个平坦的空间。
"$@"
与"$1" "$2" "$3" …
每个位置参数都会扩展为一个单独的单词,并且可以防止进一步的单词拆分和通配。