理论

理论
#!/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 插入到文件最后一行之前,它不是已定义的变量。

也欢迎解释多级逃生的提示或手册。

答案1

理论

规则是:

  • '分隔字符串内,不会解释任何内容,并且除了 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"

请注意,我建议使用apend 而不是insert 命令 for sed,但这超出了问题的范围。

相关内容