在POSIX sh或Bourne shell(如Solaris 10的/bin/sh
)中,可能具有以下内容:
a='some var with spaces and a special space'
printf "%s\n" $a
并且,使用默认值IFS
,获取:
some
var
with
spaces
and
a
special space
也就是说,保护之间的空间special
,并space
通过引用或逃逸的某种组合?
输入的字数a
事先未知,或者我会尝试类似的方法:
a='some var with spaces and a special\ space'
printf "%s\n" "$a" | while read field1 field2 ...
上下文是在Cassandra中报告的此错误,其中OP尝试设置环境变量以指定JVM的选项:
export JVM_EXTRA_OPTS='-XX:OnOutOfMemoryError="echo oh_no"'
在执行Cassandra的脚本中,该脚本必须支持POSIX sh和Solaris sh:
JVM_OPTS="$JVM_OPTS $JVM_EXTRA_OPTS"
#...
exec $NUMACTL "$JAVA" $JVM_OPTS $cassandra_parms -cp "$CLASSPATH" $props "$class"
IMO唯一的解决方法是使用包装echo oh_no
命令的脚本。还有另一种方法吗?
并不真地。
一种解决方案是保留字符作为字段分隔符。显然,不可能在选项中包括该字符。如果源语言易于插入,Tab和换行符是很明显的候选者。如果您希望具有可移植性,则应避免使用多字节字符(例如,破折号和BusyBox不支持多字节字符)。
如果您依赖IFS拆分,请不要忘记使用关闭通配符扩展set -f
。
tab=$(printf '\t')
IFS=$tab
set -f
exec java $JVM_EXTRA_OPTS …
另一种方法是引入引号语法。一个非常常见的引用语法是反斜杠保护下一个字符。使用反斜杠的不利之处在于,有许多不同的工具将其用作引号字符,有时可能很难弄清您需要多少个反斜杠。
set java
eval 'set -- "$@"' $(printf '%s\n' "$JVM_EXTRA_OPTS" | sed -e 's/[^ ]/\\&/g' -e 's/\\\\/\\/g') …
exec "$@"
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句