![为什么行尾的反斜杠会放置过多的空格?](https://linux22.com/image/226545/%E4%B8%BA%E4%BB%80%E4%B9%88%E8%A1%8C%E5%B0%BE%E7%9A%84%E5%8F%8D%E6%96%9C%E6%9D%A0%E4%BC%9A%E6%94%BE%E7%BD%AE%E8%BF%87%E5%A4%9A%E7%9A%84%E7%A9%BA%E6%A0%BC%EF%BC%9F.png)
我想了:
#!/bin/bash
cmd --options \
option=value,\
option=value,\
option=value,\
option=value
但运行后bash -x
我得到了:
cmd --options option=value, option=value, option=value, option=value
这会导致错误。
我怎样才能做到这一点,这样 bash 就不会自动放置这个空格?
答案1
嗯,每行的开头确实有空格。尽管它被压缩到一个空格中,但 bash 不会自动删除它。
为了完全避免这种情况,请将脚本编写为
#!/bin/bash
command --options \
opt1=val1,\
opt2=val2,\
opt3=val3
答案2
如果您需要将字符串opt1=val1,opt2=val2,...
作为单个参数传递给命令,但希望将其放在脚本中的多行中以实现可编辑性,则可以使用数组作为中间步骤,然后在运行命令时连接所有数组元素。
例如
opts=(
opt1=val1 # no commas here
opt2=val2 # but comments also work
etc.
)
(IFS=,
echo somecmd --options "${opts[*]}" # echo for demonstration
)
那打印somecmd --options opt1=val1,opt2=val2,etc.
(第一对括号是数组赋值语法的一部分,第二对括号启动一个子 shell,以保护脚本的其余部分免受修改IFS
。该子 shell 可能不是必需的,特别是如果脚本之后不执行任何操作,或者如果您IFS
稍后重置或根本不使用它。)
显然,这需要一个功能丰富且支持数组的 shell。除了 Bash 之外,zsh 也可以。在 ksh 中,您需要引用字符串(或至少是等号),因此它不会将其变成类似结构体复合变量。
如果您需要 POSIX sh 兼容的解决方案,最接近数组的等效项将是位置参数列表,但它们只有一组,并且由于set
其行为或多或少类似于常规命令,因此您仍然需要记住反斜杠 (并且不能使用注释)。
相反,这样的事情应该有效:
args=$( <<EOF sed -e 's/^[[:space:]]*//' | tr '\n' ,
opt1=val1
opt2=val2
etc.
EOF
)
args=${args%,}
echo somecmd --options "$args" # echo for demonstration
答案3
另外一个选择:
#!/bin/bash
cmd --options "$(printf "%s" \
"option=value," \
"option=value," \
"option=value," \
"option=value"
)"
printf "%s"
打印没有任何空格的参数,因此结果是:
cmd --options option=value,option=value,option=value,option=value
某些命令还能够完全自行删除空格,只要它作为单个参数传递即可。因此简单的引用(以防止分词)就足够了,例如ffmpeg
似乎可以这样:
ffmpeg -i somefile.mp4 -vf "
hflip,
vflip,
hue=s=0
" result.mp4
但这取决于您使用的命令如何处理这些选项。
还有一个选项可能会--options
多次使用自身(如果您的命令允许),以防万一ffmpeg
不起作用,但有时也没关系。
答案4
如果您希望能够将每个选项放在自己的行中,您可能需要尝试另一种方法:
options="opt1=val1,"
options+="opt2=val2,"
options+="opt3=val3"
your_command --options "${options}"
# note: "command" being a bash builtin, I replaced it by "your_command"
# (command foo : bypasses any alias/function "foo" and instead launches "foo" from $PATH)