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