Bash

如何正確轉義這個長 su + sed 命令?

  • May 21, 2015
#!/bin/bash
wineuser=tom
su $wineuser -c "sed -i '$ialias ptgui "wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe\"' /usr/people/$wineuser/config/cshrc.csh"

插入到 tom 的 cshrc.csh 的實際行應該看起來像

alias ptgui 'wine ~/.wine/drive_c/Program\ Files/PTGui/PTGui.exe'

sed 命令’ $ ialias…’ $ i 在文件的最後一行之前插入,它不是定義的變數。

也歡迎解釋多級轉義的提示或手冊。

理論

規則是:

  • '分隔的字元串中,什麼都不會被解釋,除了 a 之外的任何東西'都沒有特殊含義。這意味著只'需要轉義,但這也意味著,為了逃避它,您需要'\''構造。(第一個'結束字元串,下面\'添加一個文字'(轉義防止新字元串的開始),最後一個 '開始一個新字元串。由於這三個字元串沒有用分隔符(通常是空格)分隔,它們將是視為一個連續的字元串。
  • "字元串內部,會發生變數擴展並解釋轉義。因此,如果你想要一個文字\,你需要轉義它。此外,如果你想要一個文字$,你還需要轉義它(否則它將被解釋為變數擴展)。

您可以通過根據需要組合這兩種引用樣式來以不同的方式轉義您的命令。下面列出了針對您的特定問題的一種可能的解決方案。

另外,請記住,它sed也解釋為轉義字元,這意味著在腳本中\按字面意思使用該字元時,您還需要轉義該字元。sed

例子

就個人而言,我發現從最裡面的程式碼單元開始並向外工作更容易,每次在內部程式碼單元中引用外部引用方法所使用的特殊字元。

例如,如果您想在文件It's a test中替換字元串並將結果放入文件中,您可以使用引號來使其更容易,如下所示:It's my test``/home/user/I have spaces in my name.txt``/home/user/NoSpaces.txt``"

sed "s/It's a test/It's my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt

現在,如果您想將其儲存在變數中,則必須添加另一個引用級別。

  • 您可以使用'(這意味著只需轉義'目前字元串中的其他字元):
myvar='sed "s/It'\''s a test/It'\''s my test/" "/home/user/I have spaces in my name.txt" >/home/user/NoSpaces.txt'
  • 您也可以使用"樣式引號來做到這一點:
myvar="sed \"s/It's a test/It's my test/\" \"/home/user/I have spaces in my name.txt\" >/home/user/NoSpaces.txt"

經驗法則是始終使用對您來說看起來最乾淨的解決方案。

一個辦法

話雖如此,對於您的具體問題,您可以嘗試以下操作:

cmd="sed -i '\$ialias ptgui '\\''wine ~/.wine/drive_c/Program\\\\ Files/PTGui/PTGui.exe'\\' /usr/people/$wineuser/config/cshrc.csh"
su "$wineuser" -c "$cmd"

請注意,我建議使用append 而不是insert 命令 for sed,但這超出了問題的範圍。

引用自:https://unix.stackexchange.com/questions/204691