簡體   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