在Bash脚本中传递带空格参数的命令

12

我正在尝试将两个参数传递给一个命令,每个参数都包含空格,我尝试在参数中转义空格,尝试用单引号包裹,尝试转义\",但都不起作用。

这里是一个简单的例子。

#!/bin/bash -xv

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

ARG_BOTH="\"$ARG\" \"$ARG2\""
cat $ARG_BOTH

当运行时,我得到以下结果:

ARG_BOTH="$ARG $ARG2"
+ ARG_BOTH='/tmp/a\ b/1.txt /tmp/a\ b/2.txt'
cat $ARG_BOTH
+ cat '/tmp/a\' b/1.txt '/tmp/a\' b/2.txt
cat: /tmp/a\: No such file or directory
cat: b/1.txt: No such file or directory
cat: /tmp/a\: No such file or directory
cat: b/2.txt: No such file or directory
3个回答

13

请访问http://mywiki.wooledge.org/BashFAQ/050

简短总结

将您的参数放入数组中,并将您的程序调用为myutil "${arr[@]}"

#!/bin/bash -xv

file1="file with spaces 1"
file2="file with spaces 2"
echo "foo" > "$file1"
echo "bar" > "$file2"
arr=("$file1" "$file2")
cat "${arr[@]}"

输出

file1="file with spaces 1"
+ file1='file with spaces 1'
file2="file with spaces 2"
+ file2='file with spaces 2'
echo "foo" > "$file1"
+ echo foo
echo "bar" > "$file2"
+ echo bar
arr=("$file1" "$file2")
+ arr=("$file1" "$file2")
cat "${arr[@]}"
+ cat 'file with spaces 1' 'file with spaces 2'
foo
bar

是否有正常 posix shell(如 dash)的解决方案? - maep

6
这可能是通用的"set"命令的一个好的使用案例,它将顶级shell参数设置为单词列表。也就是说,$1、$2等以及$*和$@也会被重置。这样做可以使你获得一些数组的优点,同时保持所有Posix shell的兼容性。因此:
set "arg with spaces" "another thing with spaces"
cat "$@"

5
您好,以下是您需要翻译的内容:

最简单的修订示例shell脚本,以确保其正常工作的方法如下:

#! /bin/sh

ARG="/tmp/a b/1.txt"
ARG2="/tmp/a b/2.txt"

cat "$ARG" "$ARG2"

然而,如果你需要将一大堆参数包装在一个shell变量中,那么你就会遇到麻烦了;没有可移植、可靠的方法来完成这个任务。(数组是Bash特有的;唯一可移植的选项是seteval,但它们都会带来麻烦。)我认为,如果有这种需求,那么说明是时候用更强大的脚本语言(比如Perl或Python)重写了。


你介意说一下为什么“set”可能会成为一个麻烦的源吗? - Dennis Williamson
只有一个"$@",因此一次不能用于多个事情。而且set -- $VARIABLE; cmd "$@"的字分割与cmd $VARIABLE完全相同,所以不好。您必须确保您没有偶然获取set执行的其他许多事情之一。 - zwol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接