防止在 echo 参数中扩展 \c
Prevent expansion of \c in echo argument
我正在用 echo 构建一个 shell 脚本。我有类似的东西:
echo "sed -i \"\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}\" foo.conf" >> bar.sh
即替换 foo.conf 中包含当前 charlie.url 的行(不一定在开头,因为该行可能是评论)换行新 url.
我希望bar.sh的输出是
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf
然而,c\charlie
被解释为 c
\c
harlie
, 代替
c\
charlie
,生成以下输出:
sed -i "\|charlie\.url\s*=\s*.*|c
我发现我可以通过使用单引号而不是双引号来防止这种情况发生,但在那种情况下 ${CHARLIE_URL}
(我确实需要展开)不会展开。
我的 echo 参数应该是什么样的?
我正在使用 破折号(Ubuntu 下的#!/bin/sh),但我也可以使用 bash 或 zsh.
代替echo
,您可以尝试cat
:
cat << EOF >> bar.sh
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf
EOF
#!/bin/bash
# bash will expand content within "" and stuff like $URL gets expanded
# also double-backslash reduces to a single; bash wouldn't expand stuff within ''
URL="https..."
echo double: "c\charlie.url, URL $URL"
echo single: 'c\charlie.url, URL $URL'
# if you need to output a \
echo "\\"
命令行使用第一个斜杠引用第二个斜杠。如果CHARLIE_URL=foo
,你的echo实际上输出的是
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = foo" foo.conf
尝试使用单引号,但 close/open 它们围绕变量。
echo 'sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = '"${CHARLIE_URL}"'" foo.conf'
这会产生
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = foo" foo.conf
如前所述,您也可以引用引用斜杠的斜杠,然后引用另一个斜杠引用的斜杠,以便后续迭代将它们归结为您想要的...但这通常是一团糟,并导致倾斜牙签综合症。
有人已经在 here-doc 中提出了很好的建议,所以我不再重复,但您也可以使用我通常更喜欢的 "here string"。
cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}' foo.conf"
我将你脚本中的双引号换成了单引号,假设你想要的是将 $CHARLIE_URL 的字面值输出到你的脚本中。如果您希望脚本使用变量,无论在运行时分配什么值,那么也引用它 -
cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}' foo.conf"
我正在用 echo 构建一个 shell 脚本。我有类似的东西:
echo "sed -i \"\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}\" foo.conf" >> bar.sh
即替换 foo.conf 中包含当前 charlie.url 的行(不一定在开头,因为该行可能是评论)换行新 url.
我希望bar.sh的输出是
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf
然而,c\charlie
被解释为 c
\c
harlie
, 代替
c\
charlie
,生成以下输出:
sed -i "\|charlie\.url\s*=\s*.*|c
我发现我可以通过使用单引号而不是双引号来防止这种情况发生,但在那种情况下 ${CHARLIE_URL}
(我确实需要展开)不会展开。
我的 echo 参数应该是什么样的?
我正在使用 破折号(Ubuntu 下的#!/bin/sh),但我也可以使用 bash 或 zsh.
代替echo
,您可以尝试cat
:
cat << EOF >> bar.sh
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}" foo.conf
EOF
#!/bin/bash
# bash will expand content within "" and stuff like $URL gets expanded
# also double-backslash reduces to a single; bash wouldn't expand stuff within ''
URL="https..."
echo double: "c\charlie.url, URL $URL"
echo single: 'c\charlie.url, URL $URL'
# if you need to output a \
echo "\\"
命令行使用第一个斜杠引用第二个斜杠。如果CHARLIE_URL=foo
,你的echo实际上输出的是
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = foo" foo.conf
尝试使用单引号,但 close/open 它们围绕变量。
echo 'sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = '"${CHARLIE_URL}"'" foo.conf'
这会产生
sed -i "\|charlie\.url\s*=\s*.*|c\charlie.url = foo" foo.conf
如前所述,您也可以引用引用斜杠的斜杠,然后引用另一个斜杠引用的斜杠,以便后续迭代将它们归结为您想要的...但这通常是一团糟,并导致倾斜牙签综合症。
有人已经在 here-doc 中提出了很好的建议,所以我不再重复,但您也可以使用我通常更喜欢的 "here string"。
cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}' foo.conf"
我将你脚本中的双引号换成了单引号,假设你想要的是将 $CHARLIE_URL 的字面值输出到你的脚本中。如果您希望脚本使用变量,无论在运行时分配什么值,那么也引用它 -
cat <<< "sed -i '\|charlie\.url\s*=\s*.*|c\charlie.url = ${CHARLIE_URL}' foo.conf"