目录名称Bash中的空格

时间:2014-10-26 15:38:29

标签: linux bash directory

我是bash的新手,我正在编写遍历tar.gz文件存档的脚本,并在每个文件中更改指定给另一个字符串的字符串。脚本的参数:归档的名称,搜索的字符串,目标词。 我的问题是当存档名称包含空格时(例如我运行带有以下args的脚本:> change_strings.sh" /tmp/tmp.m7xYn5EQ2y/work/data txt" a A)我有以下错误: 在行if [ ! -f $filename ] ; then [:data:二元运算符期望,dirname:额外的操作数`txt'。 这是我的代码:

  #!/bin/bash 
  filename="${1##*/}"
  VAR="$1"
  DIR=$(dirname ${VAR})
  cd "$DIR"


if [ ! -f $filename ] ; then
echo "no such archive" >&2
exit 1
fi


if ! tar tf $filename &> /dev/null; then
echo "this is not .tar.gz archive" >&2
exit 1
fi


dir=`mktemp -dt 'test.XXXXXX'`
tar -xf $filename -C $dir  #extract archive to dir
cd $dir #go to argument directory

FILES=$dir"/*"

for f in $FILES
do
sed -i "s/$2/$3/g" "$f"
done

tar -czf $filename * #create tar gz archive with files in current directory
mv -f $filename $cdir"/"$filename #move archive
rm -r $dir #remove tmp directory

2 个答案:

答案 0 :(得分:1)

处理此问题的正确方法是用双引号括住变量。

var=/foo/bar baz
CMD $var # CMD /foo/bar baz

上面的代码将在/ foo / bar和baz

上执行CMD
CMD "$var"

这将在“/ foo / bar baz”上执行CMD。在大多数地方,最好用双引号括起变量。

答案 1 :(得分:1)

欢迎来到stackoverflow!

为了方便当前和未来的读者,这里有small, self contained example显示问题:

filename="my file.txt"
if [ ! -f $filename ]
then
    echo "file does not exist"
fi

以下是我们获得的输出:

$ bash file
file: line 2: [: my: binary operator expected

这是我们期望获得的输出:

file does not exist

为什么他们不一样?


以下是shellcheck对此的评价:

$ shellcheck file
In file line 2:
if [ -f $filename ]
        ^-- SC2086: Double quote to prevent globbing and word splitting.

事实上,如果我们加倍引用它,我们得到预期的输出:

$ cat file
filename="my file.txt"
if [ ! -f "$filename" ]
then
    echo "file does not exist"
fi

$ bash file
file does not exist

你应该是double quoting all your variables

但是,您必须注意$FILES,因为它包含您想要展开的glob /通配符以及您不希望使用wordsplit的潜在空格。最简单的方法是不要将它放在一个变量中,而是写出来:

for f in "$dir"/*
do
  ...