我有这个问题,我正在做一个菜单式的程序,用户应根据想要做的操作输入不同的数字。 现在我需要在命令中放入多个标志,但我似乎无法让它工作。 Catch:我不能直接在一个变量中输入标志,我可能必须让这个案例列表能够随意退出)
function fileCpy {
printf "Choices:\n1. Interactive copy, answer yes/no before doing the copy: \n2. Make backups of existing destination files\n3. Preserve file attributes\n4. Do a recursive copy\n0. Return to main menu\n"
#read choices
read $a
read $b
read $c
for choices in $choice ; do
case "$choices" in
1)
a=-i ;;
2)
b=--backup ;;
3)
c=-p ;;
#4)
#4= -R -v;;
0)
main;;
esac
echo "$a"
echo "$b"
echo "$c"
printf "\nType the name of the file you wish to copy/backup: "
read $fl1
printf "\nType the destination file: "
read $des1
cp $a $b $c $fl1 $des1
done
}
答案 0 :(得分:1)
一个问题是read $a
等错误:如果您需要阅读,则应编写read a
。就目前而言,读取的值存储在变量中,其名称存储在$a
。
另一个问题是,对于无辜的用户来说,他们应该在脚本继续之前输入3行信息,但是三条read
行迫使这些信息强制显示。
另一个问题是您没有阅读$choice
(通过read choice
),因此for
循环无关。
另一个问题是您的脚本将继承任何环境变量的值,这些变量恰好与您正在使用的变量的名称相同。
另一个问题是您没有引用文件名。除非你的名字包含空格或其他类似的尴尬字符,否则它们无关紧要。
化妆品问题是printf
声明非常长。每行使用一个printf
。或者使用echo
。滚动页面的RHS的东西很糟糕(虽然我不认为80个字符是行的固定长度,但是对于长度超过80的行有一个二次惩罚 - 如(长度-80) 2 < / sup>增加,较长线的疼痛增加。
在另一个层面上,界面显得格外怪诞。作为shell脚本的练习,它是有道理的。作为如何设计好的shell脚本的练习,这是一个非常糟糕的设计。
可能有意义的设计是:
a=""; b=""; c="";
等。请注意,您应该检查read
命令是否有效;如果他们不这样做,则不安全(不要损坏任何东西)。
将所有这些放在一起(略有不同,但总体效果相同 - 见证了local
对变量的使用):
fileCpy()
{
local a b c file dest
echo "Choices:"
echo "0. Return to main menu"
echo "1. Interactive copy, answer yes/no before doing the copy"
echo "2. Make backups of existing destination files"
echo "3. Preserve file attributes"
echo "4. Do a recursive copy"
echo "5. Execute the copy"
while printf "Your choice: " && read choice
do
[ -z "$choice" ] && return 1 # Empty input - failure
case "$choice" in
(0) return 0;;
(1) a="-i";;
(2) b="--backup";;
(3) c="-p";;
(4) d="-R";;
(5) break;;
(*) echo "Unrecognized response ($choice); please enter 0..5";;
esac
done
[ "$choice" != 5 ] && return 1 # EOF - failure
printf "Type the name of the file you wish to copy/backup: "
read file
[ -z "$file" ] && return 1 # Empty file name - failure
printf "Type the name of the destination file/directory: "
read dest
[ -z "$dest" ] && return 1 # Empty file name - failure
cp $a $b $c "$file" "$dest"
}
测试代码:
echo "a=$a b=$b c=$c file=$file dest=$dest"
if fileCpy
then : OK
else echo "Failed"
fi
echo "a=$a b=$b c=$c file=$file dest=$dest"
最后一个块是一个简单的测试工具。它报告函数内部使用的变量的值,运行函数,报告函数是否失败,并重新回显变量以证明它们尚未设置。
除非你付钱让我这样做,否则我不会使用该界面,但它或多或少都符合训练目标。
答案 1 :(得分:0)
如果你想做菜单,你可以使用select
构造(或case/esac
)。有关信息,请参阅here