我目前有这个bash脚本(位于我的主目录,即/home/fusion809/
,我以root身份运行它,因为图标复制行是必需的):
cd /home/fusion809/Pictures/Icon*
declare -a A={Arch,Debian,Fedora,Mageia,Manjaro,OpenSUSE}
declare -a B={Adwaita,Faenza,gnome,Humanity}
for i in $A; do
for j in $B; do
if test -e /usr/share/icons/$j/scalable ; else
mkdir /usr/share/icons/$j/scalable/
fi
if test -e /usr/share/icons/$j/scalable/$i.svg ; else
cp -a $i*.svg /usr/share/icons/$j/scalable/$i.svg
fi
done
done
我希望此脚本执行的操作是将Pictures/Icons and logos
目录中的图标复制到scalable
中的$B
主题(在/usr/share/icons
中指定)子目录中。但是,在它执行此操作之前,我希望在这些主题子目录中创建一个scalable
目录(如果它尚不存在)。问题是条件的else部分没有被正确读取,因为我一直收到这个错误:
./copyicon.sh: line 8: syntax error near unexpected token `else'
./copyicon.sh: line 8: ` if test -e /usr/share/icons/$j/scalable ; else'
如果您想知道为什么条件中test -e ...
基于bash脚本的教科书,我一直在关注。
答案 0 :(得分:7)
要检查bash中是否存在文件,请使用-f
运算符。对于目录,请使用-d
。用法示例:
$ mkdir dir
$ [ -d dir ] && echo exists!
exists!
$ rmdir dir
$ [ -d dir ] && echo exists!
$ touch file
$ [ -f file ] || echo "doesn't exist..."
$ rm file
$ [ -f file ] || echo "doesn't exist..."
doesn't exist...
有关更多信息,请执行man test
。
关于-e
的注释,此测试操作员检查文件是否存在。虽然这似乎是一个不错的选择,但最好使用-f
,如果文件不是常规文件,它将返回false。 /dev/null
例如是文件,但也不是常规文件。在这种情况下,检查返回true是不受欢迎的。
关于变量的说明
一定要引用变量,一旦变量中包含空格或任何其他特殊字符,就会产生不良副作用。因此,当您测试文件和目录是否存在时,请将文件/目录用双引号括起来。如果[ -f "/path/to/some/${dir}/" ]
dir
中有空格,则[ -f /path/to/some/${dir}/ ]
之类的内容会有效,而以下内容会失败。
您在控制语句中遇到语法错误。 bash if
子句的结构如下:
if ...; then
...
fi
或者else
子句可选:
if ...; then
...
else
...
fi
您不能省略then
子句。如果您只想使用else
条款,则应该否定条件。导致以下代码:
if [ ! -f "/usr/share/icons/$j/scalable" ]; then
mkdir "/usr/share/icons/$j/scalable/"
fi
这里我们添加一个感叹号(!
)来翻转表达式的评估。如果表达式的计算结果为true,则!
前面的相同表达式将返回false,反之亦然。
答案 1 :(得分:4)
您无法跳过 if 语句的然后部分,最简单的解决方案就是取消测试
if [[ ! -e /usr/share/icons/${j}/scalable ]] ; then
mkdir /usr/share/icons/${j}/scalable/
fi
if [[ ! -e /usr/share/icons/${j}/scalable/${i}.svg ]] ; then
cp -a ${i}*.svg /usr/share/icons/${j}/scalable/${i}.svg
fi
我把它留给-e(存在),但你可能会考虑使用-d作为目录或-f用于文件和一些错误处理来捕获内容(例如 / usr / share / icons / $ j / scalable / 存在,但无论出于何种原因,它都是文件而不是目录。) 我还注意到,在您的原始代码中,您可能会尝试将多个文件复制到一个文件中:
cp -a $i*.svg /usr/share/icons/$j/scalable/$i.svg
我在我的示例中保留了这种方式,以防您确定它始终只有一个文件并且故意重命名它。如果不是,我建议只指定目标目录。