![我可以改进这段代码吗?](https://linux22.com/image/149710/%E6%88%91%E5%8F%AF%E4%BB%A5%E6%94%B9%E8%BF%9B%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%E5%90%97%EF%BC%9F.png)
我想知道这是否可以改进或清理。这个想法是用户选择三个类别之一,然后记录该选择。然后注释将被附加并保存到适当的列表中。
#!/bin/bash
#get the date
date=$(date +%d-%B-%Y)
#save locations
wsave="${HOME}/worknotes.txt"
shsave="${HOME}/shoppingnotes.txt"
scsave="${HOME}/schoolnotes.txt"
#list
while [ true ]
do
read -p "What is this note for?
Work
School
Shopping
> " topic
case $topic in
"Work" )
read -p "
Note
> " wnote
echo "$date: $wnote" >> "$wsave"
echo "Note saved to $wsave"
break
;;
"Shopping" )
read -p "
Note
> " shnote
echo "$date: $shnote" >> "$shsave"
echo "Note saved to $shsave"
break
;;
"School" )
read -p "
Note
> " scnote
echo "$date: $scnote" >> "$scsave"
echo "Note saved to $scsave"
break
;;
*) echo "Error: Selection was not on list, try again.
"
;;
esac
done
答案1
是的,您可以改进代码。
select
中的语句提供bash
了一种显示菜单的方式,并且还提供了基本的输入循环。
#!/bin/bash
menu=(
Work
School
Shopping
)
PS3='What is this note for? '
while true; do
unset outfile
select word in Exit "${menu[@]}"; do
case $REPLY in
1)
echo 'Bye!'
exit ;;
[2-4])
outfile="$HOME/${word,,}-notes.txt" ;;
*)
echo 'Invalid choice, try again' >&2
esac
if [ -n "$outfile" ]; then
break
fi
done
IFS= read -r -p 'Enter note: '
printf '%s:\t%s\n' "$(date +%d-%B-%Y)" "$REPLY" >>"$outfile"
printf 'Note added to "%s"\n' "$outfile"
done
这里的另一个变化是我只要求提供实际的注释一地方。这使得代码更容易阅读并且更容易维护。
如果感觉更好的话,显然可以用一系列陈述来case ... esac
代替。如果做出了有效的选择,if ... then ... elif ... fi
内部break
语句就会跳出循环。select
这将我们带到外部循环,然后外部循环要求用户提供文本并将其保存到文件中,然后再循环回显示菜单。菜单中的选项Exit
提供了退出脚本的方法。
一个小注意事项是
while [ true ]
在你的代码中具有相同的效果
while [ false ]
或者,确实如
while [ bumblebee ]
这是因为当[ ... ]
包含单个单词时,该单词将被解释为字符串。如果字符串非空,则测试为真的。
在我的代码中,我使用
while true
这实际上执行true
实用程序,它总是返回一个真的价值。