我刚接触Unix中的编程,并且有一个小问题,我不确定如何解决。我的这个脚本的目的是为用户提供各种选项,使他们想要使用的扫描类型。此扫描会检测具有指定变量的重复文件,具体取决于所选的选项。
我根本无法让它工作,我不确定为什么?
另外,如果可能的话,请您就如何更好地显示选择屏幕向我提供建议。我只粘贴了部分代码,因为我想自己弄清楚其余的目标。
#!/bin/bash
same_name="1"
filesize="2"
md5sum="3"
different_name="4"
echo "The list of choices are, same_name=1, filesize=2, md5sum=3 and different name=4"
echo "Search for files with the:"
read choice
if [$choice == "$same_name" ];then
find /home/user/OSN -type f -exec basename '{}' \; | sort > filelist.txt
find /home/user/OSN -type f -exec basename '{}' \; | sort | uniq -d > repeatlist.txt
else
ls -al /home/user/OSN >2filelist.txt
fi
答案 0 :(得分:5)
shell命令[
也称为test
,需要一个空格才能使shell正确解析。例如:
if [ "x$choice" == x"$same_name" ] ; then
相当于
if test "x$choice" == "x$same_name" ; then
在变量前加上“x”是一种习惯用法,可以防止test
看到过少的参数。如果调用test 5 ==
,测试会抱怨,如果$choice
和$same_name
为空,则对expr的调用在语法上是正确的。
您还可以使用构造${choice:-default}
或${choice:=default}
来防止未设置或null的shell变量。
答案 1 :(得分:3)
如果您收到了收到的错误消息,这将有所帮助。当我尝试这个时,我收到了错误:
./foo: line 9: [1: command not found
这使问题相当清楚。 [
语句中的if
运算符,在Unix中“从不使用复杂的东西,当一些简单的黑客将起作用”的风格时,只是另一个程序。 (请参阅ls /bin/[
以获取证明!)因此,需要将其视为具有命令行选项的任何其他程序;你用空格将它与它的选项分开。否则,bash会认为“[$ choice”,连接,是要执行的程序的名称,并将尝试执行它。因此,该行必须是:
if [ $choice == "$same_name" ];then
在我改变之后,它起作用了。
另外,作为样式建议,我注意到当你有多个测试时,case
构造是一种比使用if
语句更容易编写代码的方法。并且,正如其他答案中所述,您应该在"
周围放置$choice
标记,以防止用户输入为空或包含空格的情况 - $choice
,未加引号,将展开到由空格分隔的零个或多个标记的列表,而"$choice"
总是扩展为单个标记。
答案 2 :(得分:1)
Bash的双方括号对引用以及null或unset变量更加宽容。
if [[ $choice == "$same_name" ]]; then
你应该看一下Bash的select
和case
陈述:
choices="same_name filesize md5sum different_name exit"
PS3="Make a selection: " # this is the prompt that the select statement will display
select choice in $choices
do
case $choice in
same_name)
find ...
;;
filesize)
do_something
;;
.
.
.
exit)
break
;;
esac
done
答案 3 :(得分:1)
无法相信没有人收到此错误:如果您使用[
(或test
),字符串相等的运算符为=
而非==
。
答案 4 :(得分:1)
while true
do
cat <<EOF
The list of choices are:
1) same name
2) filesize
3) md5sum
4) different name
5) exit
EOF
read -r -p "Enter your choice: " choice
case "$choice" in
1)
find /home/user/OSN -type f -exec basename '{}' \; | sort > filelist.txt
find /home/user/OSN -type f -exec basename '{}' \; | sort | uniq -d > repeatlist.txt
5) exit;
*) ls -al /home/user/OSN >2filelist.txt
esac
done