繁体   English   中英

转义bash别名中的字符

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM