什么可以解释下面的例子,我该如何解决这个问题,最好不要大量引用杂技?我正在使用$n
来模拟多行命令字符串,以防它分散您对真正问题的注意力。
~$ n=$'\n'; sudo -i echo "line1${n}line2${n}"
line1line2
~$
但
~$ n=$'\n'; sudo echo "line1${n}line2${n}"
line1
line2
~$
什么可以解释下面的例子,我该如何解决这个问题,最好不要大量引用杂技?我正在使用$n
来模拟多行命令字符串,以防它分散您对真正问题的注意力。
~$ n=$'\n'; sudo -i echo "line1${n}line2${n}"
line1line2
~$
但
~$ n=$'\n'; sudo echo "line1${n}line2${n}"
line1
line2
~$
在 strace 下运行
sudo -i echo $'line1\nline2'
显示 Bash 是这样启动的:现在,
strace
在显示字符串时显示带有反斜杠转义的特殊字符,因此 Bash 实际上作为参数得到的-c
是,对于 shell,行尾的反斜杠标记续行并删除反斜杠和以下换行符.echo line1[backslash][newline]line2[backslash][newline]
没有
-i
,直接sudo
运行echo
,不经过外壳:在这里,这是一个字面的换行符
echo
,并echo
适当地打印出来。这里的想法必须是
sudo
尝试添加一层外壳转义以适应sh -c
采用单个字符串的事实,而sudo
它本身将命令作为不同的参数。比较以下情况:
sudo
转义空格(这只是命令的名称,没有参数!):sudo
转义反斜杠,因此这实际上有效(Bashecho
不处理反斜杠):与选项卡相同:
在这里,反斜杠上没有额外的引号,因此 Bash 在处理 shell 命令行时将其删除(
b
不是 shell 的特殊字符,不需要引号。这与 基本相同bash -c 'echo foo"b"ar'
):问题只是你不能用反斜杠转义换行符,而且
sudo
似乎没有考虑到这一点。无论如何,如果您将所需的命令存储在一个文件中并将其作为脚本运行,那么引用此类问题可能会变得相当容易。
您可以更改命令的结构:
这种方式
sudo
看不到论点,因此不能把它搞砸。