Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么不是';t sed';在bash中存储的输出及其多个反斜杠?_Bash_Sed_Output_Backslash - Fatal编程技术网

为什么不是';t sed';在bash中存储的输出及其多个反斜杠?

为什么不是';t sed';在bash中存储的输出及其多个反斜杠?,bash,sed,output,backslash,Bash,Sed,Output,Backslash,我试图将sed的输出存储到一个变量中,但是输出与我期望的不同 我的测试如下 $ foo="this is (foo)" $ x="$(sed 's/(/\\\\(/g' <<< $foo)" 我得到的结果是: $ echo $x this is \(foo) 但是,当我没有将输出分配给变量时,结果就是预期的结果: $ sed 's/(/\\\\(/g' <<< $foo this is \\(foo) $sed's/(/\\\\(/g'不要信任echo:

我试图将sed的输出存储到一个变量中,但是输出与我期望的不同

我的测试如下

$ foo="this is (foo)"
$ x="$(sed 's/(/\\\\(/g' <<< $foo)"
我得到的结果是:

$ echo $x
this is \(foo)
但是,当我没有将输出分配给变量时,结果就是预期的结果:

$ sed 's/(/\\\\(/g' <<< $foo
this is \\(foo)

$sed's/(/\\\\(/g'不要信任
echo
:POSIX规范在其实现中留下了足够的余地,您无法信任其输出来正确表示手头的值。相反,请使用
printf

foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"

从中,强调补充道:

应支持以下操作数:

要写入标准输出的字符串。如果第一个操作数是
-n
,或者任何操作数包含反斜杠('\')字符,则结果由实现定义

同样,从同一文档的应用程序使用部分:

除非省略了
-n
(作为第一个参数)和转义序列,否则不可能在所有POSIX系统中使用echo可移植

printf
实用程序可移植地用于模拟echo实用程序的任何传统行为[…]


不要信任
echo
:POSIX规范在其实现中留下了足够的余地,您无法信任其输出来正确表示手头的值。相反,请使用
printf

foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"

从中,强调补充道:

应支持以下操作数:

要写入标准输出的字符串。如果第一个操作数是
-n
,或者任何操作数包含反斜杠('\')字符,则结果由实现定义

同样,从同一文档的应用程序使用部分:

除非省略了
-n
(作为第一个参数)和转义序列,否则不可能在所有POSIX系统中使用echo可移植

printf
实用程序可移植地用于模拟echo实用程序的任何传统行为[…]


顺便说一句,反斜杠会消耗你的文字反斜杠,所以对于那些(但不是
$(…)
),你有一个额外的失败模式。这不是回答你的问题(因此有一个注释;),但我喜欢为sed测试做的是
[vim]diff-infle,这是一种有趣的方式:)引用你的变量(
“$x”
,而不是
$x
),除非您有非常具体的理由不完全理解您通过不这样做调用的行为。顺便说一句,反勾号将消耗您的文字反斜杠,因此对于那些(但不是
$(…)
),您有一个额外的故障模式。这并不是回答您的问题(因此有一个注释;),但是我喜欢为sed测试做的是
[vim]diff-infle,这是一种有趣的方式:)引用变量(
“$x”
,而不是
$x
),除非您有非常具体的理由不这样做,并且不完全理解您正在调用的行为。因此,我想,没有更多的
echo
用于调试。。。谢谢其他函数(如
scp
)的错误输出(
STDERR
)不显示额外的反斜杠,这正常吗?
scp
是一种特殊情况,因为它通过远程端上的部分shell扩展传递来运行远程文件名。委婉地说,这不是一个好的做法,但在不做大量额外工作的情况下远程进行通配符扩展是必要的……因此,对于大多数以比
scp
更好/更合理的方式实现的命令来说,这将是不正常的,但具体情况是另一个问题。顺便说一句,关于调试,请使用
set-x
,或者
bash-xyourscript
;这将为您提供在stderr上引用的命令shell——无论如何,它比
echo
有用得多;你无法区分
echo“foo-bar”
echo-foo-bar
之间的区别,这种区别是巨大而重要的!您还可以使用类似于
PS4=':$LINENO+'
set-x
的方法来打印每个命令执行时的行号。(另一方面,
printf“%q”
是另一个有用的工具,可以放在你的武器库中——使用ksh或bash之类的派生工具,它对引用的输入进行求值,从而使其
eval
安全……不过避免任何数据在shell中被解析为代码的情况,总比使用反斜杠或其他方式转义要好解析是安全的,如果确实需要转义,最好知道如何正确地进行)。因此,我想调试时不再使用
echo
,谢谢!那么这比其他函数(例如
scp
)的错误输出(
STDERR
)正常吗不显示额外的反斜杠?
scp
是一种特殊情况,因为它通过远程端上的部分外壳扩展过程来运行远程文件名。说得委婉一点,这不是一种好的做法,但需要在不做大量额外工作的情况下远程进行通配符扩展……因此,对于大多数命令,在n比
scp
更好/更明智的方法,这可能是不正常的,但具体情况是不同的。顺便说一句,re:调试,使用
set-x
,或
bash-x您的脚本
;这将给您在stderr上引用的命令shell——无论如何比
echo
有用得多;您无法区分
echo“foo bar”
echo foo bar
,这两个命令之间的差异是巨大而重要的!您还可以使用类似于
PS4=':$LINENO+'
的命令和
set-x
一起打印每个命令执行时的行号。(另一方面,
printf“%q”
是另一个有用的工具,可以放在你的武器库中——使用ksh或bash之类的衍生工具,它对引用的输入进行求值,从而使
eval
-安全
foo="this is (foo)"
x="$(sed 's/(/\\\\(/g' <<<"$foo")"
printf '%s\n' "$x"
this is \\(foo)