我有一个存储在变量中的命令,然后运行:
[root@cxpxwly01wel001 init.d]# cat test
#!/bin/bash
command="su - root -c 'java -Xms16m -the_rest_of_my_java_command'"
echo $command
$command
[root@cxpxwly01wel001 init.d]# ./test
su - root -c 'java -Xms16m -the_rest_of_my_java_command'
su: invalid option -- 'X'
Try `su --help' for more information.
如果单引号不存在,则会出现su错误:
[root@cxpxwly01wel001 init.d]# su - root -c java -Xms16m -the_rest_of_my_java_command
su: invalid option -- 'X'
Try `su --help' for more information.
使用单引号,命令按预期工作:
[root@cxpxwly01wel001 init.d]# su - root -c 'java -Xms16m -the_rest_of_my_java_command'
-bash: java: command not found
这告诉我,当将变量作为命令运行时,单引号不会被保留。我该如何保存它们?
注意:我正在编辑现有脚本(在java命令中插入su),所以我希望尽可能少地更改以使其靠近源。
让我在使用set -x
:
+ command='su - root -c '\''java -Xms16m -the_rest_of_my_java_command'\'''
+ echo su - root -c ''\''java' -Xms16m '-the_rest_of_my_java_command'\'''
su - root -c 'java -Xms16m -the_rest_of_my_java_command'
+ su - root -c ''\''java' -Xms16m '-the_rest_of_my_java_command'\'''
su: invalid option -- 'X'
Usage: su [options] [LOGIN]
Options:
-c, --command COMMAND pass COMMAND to the invoked shell
-h, --help display this help message and exit
-, -l, --login make the shell a login shell
-m, -p,
--preserve-environment do not reset environment variables, and
keep the same shell
-s, --shell SHELL use SHELL instead of the default in passwd
答案 0 :(得分:1)
我用来避免“引用内引号”问题的技术是在数组中构建命令。例如,而不是:
command="su - root -c 'java -Xms16m -the_rest_of_my_java_command'"
我会用:
declare -a command=(su - root -c 'java -Xms16m -the_rest_of_my_java_command')
您仍然可以回显命令(使用数组扩展):
echo "${command[@]}"
或者运行它:
"${command[@]}"
数组扩展的双引号很重要:它们告诉shell扩展项而不进行任何单词拆分,因此包含空格的项将其标识保持为单个字符串。
通过这种方式,最后一个参数(在引号内)将保持为单个字符串,su
命令不会将-Xms16m
视为(无效)选项。
另外,[@]
中的"${command[@]}"
表示“数组中的所有元素”。然而,在"${command[1]}"
这样的表达式中,[1]
意味着“只有索引1处的元素”。