[英]Escaping characters in bash alias
这是别名:
# make a tmux session in working dir with the name of the dir
alias th='tmux new -s $(pwd | tr '\/' '\n' | tail -n 1)'
由于转义字符或别名内的'
,单引号,它不起作用。 打印出来
$ type --all th
th is aliased to `tmux new -s $(pwd | tr / n | tail -n 1)'
看起来它只是剥离了'
和\\
。
我最终通过将单引号更改为双引号来修复它。
# make a tmux session in working dir with the name of the dir
alias th='tmux new -s $(pwd | tr "\/" "\n" | tail -n 1)'
我的问题是以前的工作怎么样? 不应该bash抛出解析错误。
改为使用函数:
th() { tmux new -s "${PWD##*/}" "$@"; }
${PWD##*/}
是一个参数扩展 ,它会删除所有内容,包括最后一个/
来自$PWD
的内容。
原始代码中的问题是它包含语法引号 - 由shell解析以确定单引号解析规则的开始和结束位置 - 在实际需要的地方是文字引号,被视为数据的地方(因此成为别名的一部分)。
使这些引号文字的一种方法是使用$''
引用形式,它允许你使用文字反斜杠来转义内部引号,使它们成为字面而不是语法:
alias th=$'tmux new -s $(pwd | tr \'\\\/\' \'\\n\' | tail -n 1)'
请注意,使用$''
,文字反斜杠也需要进行转义(因此,写为\\\\
而不是\\
)。
POSIX shell语言中字符串的引用是逐个字符确定的。 因此,在以下情况下:
'$foo'"$((1+1))"baz
... $foo
是单引号,因此被视为文字字符串, $((1+1))
是双引号,因此有资格被视为算术扩展,并且baz
是不加引号的 - 即使所有三个这些被连接起来形成一个单词( $foo2baz
)。
这些引用都是语法 - 它们是shell的指令 - 不是文字 (这意味着它们是该字符串计算的数据的一部分)。
在
alias th='tmux new -s $(pwd | tr '\/' '\n' | tail -n 1)'
... tr
的参数中的单引号结束了在别名开头处开始的单引号。 因此, \\/
和\\n
在一个不带引号的上下文中进行评估(其中\\/
变为/
,并且\\n
变为n
) - 并且因为,如上所述,多个不同引用的子串可以被连接成一个更大的字符串,你得到你以前的命令,而不是别名。
您的嵌入式单引号未被视为嵌入式,它们会终止先前的字符串并盯着新字符串。 您的第一次尝试被视为tmux new -s $(pwd | tr
, \\/
,'', \\n
和| tail -n 1)
的串联。 把它们放在一起并处理转义,你就会得到你在type
命令的输出中看到的内容。
另外值得考虑: https : //unix.stackexchange.com/questions/30925/in-bash-when-to-alias-when-to-script-and-when-to-write-a-function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.