Bash 如何改进此脚本?
我正在学习shell脚本,发现很难找到一个好的学习方法。我在下面创建了一个脚本,它允许用户通过选项搜索各种不同的互联网引擎。如果有人能看穿这一点,指出我做错了什么,如何改进,等等,我将不胜感激Bash 如何改进此脚本?,bash,shell,Bash,Shell,我正在学习shell脚本,发现很难找到一个好的学习方法。我在下面创建了一个脚本,它允许用户通过选项搜索各种不同的互联网引擎。如果有人能看穿这一点,指出我做错了什么,如何改进,等等,我将不胜感激 #!/bin/bash ## Get user search-engine option while getopts aegwy: OPTIONS ; do case "$OPTIONS" in a) ENGINE="http://www.amazon.com/s/ref=nb_sb_no
#!/bin/bash
## Get user search-engine option
while getopts aegwy: OPTIONS ; do
case "$OPTIONS" in
a) ENGINE="http://www.amazon.com/s/ref=nb_sb_noss/?field-keywords";;
e) ENGINE="http://www.ebay.com/sch/i.html?_nkw";;
g) ENGINE="http://www.google.com/search?q";;
w) ENGINE="http://en.wikipedia.org/wiki/?search";;
y) ENGINE="http://www.youtube.com/results?search_query";;
?) ERRORS=true;;
esac
done &>/dev/null
## Ensure correct command usage
[ $# -ne 2 ] || [ $ERRORS ] && printf "USAGE: $(basename $0) [-a Amazon] [-e eBay] [-g Google] [-w Wikipedia] [-y YouTube] \"search query\"\n" && exit 1
## Ensure user is connected to the Internet
ping -c 1 209.85.147.103 &>/dev/null ; [ $? -eq 2 ] && printf "You are not connected to the Internet!\n" && exit 1
## Reformat the search query
QUERY=`printf "$2" | sed 's/ /+/g'`
## Execute the search and exit program
which open &>/dev/null ; [ $? -eq 0 ] && open "$ENGINE"="$QUERY" &>/dev/null && exit 0 || xdg-open "$ENGINE"="$QUERY" &>/dev/null && exit 0 || printf "Command failed!\n" && exit 1
提前谢谢大家,意义重大 是提高bash脚本编写技能的绝佳资源
这是另一个伟大的文件
希望这能有所帮助。最好在codereviews中发布,如上所述,但这里有一些主要的风格评论。我要强调的是,剧本很好;这些只是一些小的改进,我认为这将有助于使代码更易于阅读/维护,在一些情况下更健壮,等等 您不需要仅仅因为环境变量都是大写而对变量名使用所有大写;shell变量和环境变量不是一回事 由于您的
$OPTIONS
变量一次只保存一个选项,因此最好使用单数名称(例如$option
)。或者您可以选择$opt
,这在这里有点传统
getopts字符串(aegwy:
)中的:
表示-y
选项需要一个参数,如-y
中的某个参数,而不仅仅是-y
。既然您没有使用$OPTARG
做任何事情,我猜这不是故意的
正如其他人所说,一个如果
/那么
/elif
/否则
可能比&
和|
的链条更清晰
测试[$ERRORS]
有些不清楚,因为根据$ERRORS
参数的内容,它可能意味着许多不同的事情。一个更明确的指示是,您只关心是否设置了它,[-n“$ERRORS”]
像[-ne]
和friends这样的比较大多是在shell内置整数算法之前留下的;更现代的成语应该是($#!=2))
您的用法消息意味着-a、-e、-g、-w和-y选项采用亚马逊、易趣、谷歌等形式的参数。如果不添加这些参数,命令的实际语法将更加清晰;您可以在帮助文本中添加一个额外的段落,列出每个选项的含义
通常,错误消息应该转到stderr而不是stdout(&2
)
可以使用basename$0
来保持输出的一致性,但是要说的是不要使用$0
,因为这将反映用户实际调用命令的方式。需要考虑的事情。< /P>
如果不使用格式字符串,则使用printf
没有多大意义;只需使用echo
,它会自动添加换行符。使用信息传统上也不包括引号;用户是否引用arg取决于是否需要
如果工作,则检查命令是否成功正是的工作方式,因此无需对$?
进行显式检查,除非您真正关心确切的退出值。在连接ping的情况下,您可能不关心它失败的原因,只关心它失败了:
if ! ping -c 1 209.85.147.103 >/dev/null; then
echo >&2 "$0: You are not connected to the Internet!"
exit 1
fi
您的搜索查询重新格式化可能需要做的不仅仅是将空格变成加号;如果它有一个符号怎么办?但是,如果您只是在执行空格到加号的操作,那么可以使用bash参数扩展,而不使用sed:QUERY=“${QUERY///+}”
如果您的程序依赖于open/xdg open等,您可能应该在顶部检查其可用性;如果您知道自己无论如何都不可能执行请求的操作,那么做任何其他事情都没有意义。您可以使用一个变量,这样就不会在多个子句中重复自己:
open=
for cmd in open xdg-open; do
if type -p "$cmd" >/dev/null; then
open="$cmd"
break
fi
done
if [ -z "$open" ]; then
echo >&2 "$0: open command not found."
exit 1
fi
然后你可以用这一行来结束:
“$open”“$ENGINE=$QUERY”&>/dev/null它是否按预期工作?“代码>……& &……/代码>有点难读,也许可以考虑使用<代码>如果。除此之外,这似乎还可以…它工作得很好,但我不知道是否有更好的方法,谢谢你的回答。一位大师可能会想出一些办法,但这看起来是对的。您的y
选项看起来需要一个值,[…]和&
的内容将更易于阅读,因为if[…]
,但在其他方面它看起来很好。我现在可能会改为if语句,您认为y选项需要一个值是什么意思?再次感谢这类问题更适合解释为什么这个答案被否决。最初的海报上写着“我正在学习shell脚本,很难找到一个好的学习方法。”这些都是值得学习的优秀资源。因此,如果这不是一个好的答案,我想知道为什么。只有几个链接的答案是不鼓励的;这可能是一个评论。撇开这个问题在StackOverflow上有点离题不谈,海报要求对他们的代码发表评论,而不仅仅是编程指南的链接。顺便说一句,我不是反对者:)不幸的是,我还不能添加评论,所以回答问题是目前提供反馈的唯一方式。只要你提供几个正确的主题答案或提出一些有趣的问题,这种情况就会改变:你需要评论。我建议在此期间不要发表类似评论的回答:人们会在不考虑你是否可以发表评论的情况下否决投票。祝你好运:)另外,请参阅上的本指南。非常感谢你提供了极其详细的答案。这肯定会让你受益匪浅。我特别喜欢参数展开,它比使用sed容易得多。再次感谢!