Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果没有双引号变量,BASH脚本mv命令将无法工作。为什么?_Bash_Variables_Double Quotes - Fatal编程技术网

如果没有双引号变量,BASH脚本mv命令将无法工作。为什么?

如果没有双引号变量,BASH脚本mv命令将无法工作。为什么?,bash,variables,double-quotes,Bash,Variables,Double Quotes,我今天写了一个剧本如下: echo "Enter a directory path" read dir for file in $dir/[!.]*; do f=`echo $file | sed 's/ /_/g'` mv "${file}" "${f}" done 最初,mv命令编写为: mv ${file} ${f} 但那条线太长了 usage: mv [-f | -i | -n] [-v] source target mv

我今天写了一个剧本如下:

echo "Enter a directory path"

read dir

for file in $dir/[!.]*;
    do
        f=`echo $file | sed 's/ /_/g'`
        mv "${file}" "${f}"  
    done
最初,mv命令编写为:

mv ${file} ${f}
但那条线太长了

usage: mv [-f | -i | -n] [-v] source target
   mv [-f | -i | -n] [-v] source ... directory
我能够使用google找出变量需要用双引号括起来,但我仍然不明白为什么这样做可以解决问题?

谢谢

在shell中引用可以防止字符串拆分和全局扩展。如果不双引号引用变量,则不知道在运行这些解析步骤后,每个变量可能扩展为多少个参数

即:

mv $foo $bar
…可能会变成

mv ./first word second word third word destination-file
如果


类似地,考虑有一个包含GROB表达式的文件名的情况:

foo='hello * world'
在这种情况下,您的
mv
命令将获得当前目录中所有文件的列表


…或者,考虑一个参数为空的情况:

foo='hello world'
bar=''

在这种情况下,您将尝试将名为
hello
的文件重命名为
world
$bar
将消失。

使用“bash-x”调用脚本,您将获得大量调试输出,帮助您了解发生了什么。BTW,
echo$file | sed's//\ug'
有很多相同的原因,但速度非常非常慢。改为使用参数扩展:
f=${file///}
——与
echo“$file”
或(甚至更少的错误)
printf'%s\n'$file'
@CharlesDuffy+1进行优化相比,使用
echo$file
既更快,又避免了所有隐含的错误。这是非常有帮助和有趣的。另一方面,
${foo}
本身没有比
$foo
更大的优势。如果要执行参数扩展--
${foo%bar}
或类似操作,请确定;如果您需要消除字符串连接的歧义--
${foo}bar
,那么请确定;否则呢?纯粹是一种风格偏好。@CharlesDuffy我被指示这是一种良好的实践。思想?
foo='hello world'
bar=''