在我的上一篇文章
Linux的shell编程易错点解析(for循环和ls命令)
提到了如果文件名含有空格,则会在对文件的操作中可能出错。
同理,除了循环遍历文件名,在复制文件时,如果带有空格和短横线,也可能出错。
[root@db01 scripts]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
[root@db01 scripts]# uname -r
3.10.0-862.el7.x86_64
首先创建一个符合要求的文件
touch "01 - Don't Eat the Yellow Snow.mp3"
然后利用脚本复制文件
错误案例如下:
#!/bin/bash
file="01 - Don't Eat the Yellow Snow.mp3"
target="/tmp"
cp $file $target
这样复制的file
实际上是空格拆分的单词,复制实际不存在的文件,所以报错。
正确的做法是,加上双引号,将字符串括起来的变量当作一个整体。
正确案例如下:
[root@db01 scripts]# cat test.sh
#!/bin/bash
file="01 - Don't Eat the Yellow Snow.mp3"
target="/tmp"
cp "$file" "$target"
同样是上面的案例,我们可以重复使用。
错误已经清楚,直接说解决方法。
方法一:在命令和参数之间加上--
cp -- "$file" "$target"
这个符号的作用是,告诉不要对符号后面内容进行命令行参数解析
缺点在于,如果命令不是以上述方式呈现,方法无效。
方法二:让文件名以相对路径或绝对路径表示
#!/bin/bash
for i in ./*.mp3;
do
cp "$i" /target
...
done
个人推荐尽可能使用绝对路径表示文件名。
因为Linux的定时任务crontab -e
中的命令都必须用绝对路径表示,为方便记忆,所有涉及参数的表示都使用绝对路径,出错的概率更低。