我确信之前已经问过,但我老实说不知道该搜索什么。所以请考虑这个小小的脚本:
#!/bin/sh
test="\"Hello\" \"World\""
set -x
echo $test
结果将是:
+ echo '"Hello"' '"World"'
"Hello" "World"
但那不是我想要的!我不希望在echo
个参数周围有单引号。我想要的是这个:
+ echo "Hello" "World"
Hello World
我怎样才能实现这一目标?
*编辑*
以下是上图中背后真正问题的一个更具体的例子:
#!/bin/sh
alldirs=
for d in */ ; do
dir=${d%?}
alldirs+=" \"$dir\""
done
set -x
tar cvf test.tar.gz $alldirs
我们的想法是将脚本目录中的所有目录存档在tar存档中。由于目录名称可能包含空格,因此我将它们的名称括在双引号中。
上面的脚本不起作用。 tar
抱怨由于双引号而无法在各个目录上运行stat
。
答案 0 :(得分:6)
我窥探了你的历史,发现你熟悉类C语言:
int main() {
char *s = "\"hello\", \"world\"";
printf("First: %s, second: %s\n", s);
}
您希望这相当于
printf("First: %s, second: %s\n", "hello", "world);
相反,它写道:
first: "hello", "world", second:
那么为什么printf
会添加额外的引号?答案很明显,事实并非如此。解释引号不是printf
的工作。文字引号不会影响C函数接收字符串的方式。
同样,解释引号不是echo
或tar
的工作。文字引号不会影响shell命令接收字符串的方式。
C和bash中的解决方案是将值放在数组中,而不是尝试创建一个带有嵌入引号的字符串:
#!/bin/bash
alldirs=()
for d in */ ; do
dir=${d%?}
alldirs+=("$dir")
done
set -x
tar cvf test.tar.gz "${alldirs[@]}"
这当然只是为了说明。真实的脚本会将此简化为tar cvf test.tar.gz */
答案 1 :(得分:0)
我不确定这是否适用于您的确切脚本,但您不需要使用双引号。
你可以试试这个:
#!/bin/sh
test=Hello\ World
set -x
echo $test