目前我正在编写一个 Bash 脚本,它具有以下要求:
我知道这getopts将是可移植性方面的首选方式,但 AFAIK 它不支持长选项。
getopt支持长选项,但BashGuide强烈建议反对它:
永远不要使用 getopt(1)。getopt 无法处理空参数字符串或带有嵌入空格的参数。请忘记它曾经存在过。
因此,仍然可以选择手动解析。这很容易出错,会产生相当多的样板代码,而且我需要自己处理错误(我想自己getopt(s)进行错误处理)。
那么,在这种情况下,首选是什么?
是否有一些内置工具可以识别-x和--xxxx作为开关,而不是参数,或者您是否必须遍历所有输入变量,测试破折号,然后解析参数?
我有这个代码 -
#getoptDemo.sh
usage()
{
echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
case $option in
(w)
name='1';;
(l)
name='2';;
(h)
name='3';;
(*)
usage
exit;;
esac
done
print 'hi'$name
Run Code Online (Sandbox Code Playgroud)
当我运行bash getoptDemos.sh(不带选项)时,它会打印hi而不是调用函数usage。当给出 w、h 和 l 以外的选项时,它调用用法。那么当没有指定选项时它就不能工作。
我曾尝试使用?, \?,:代替,*但我无法实现我想要的。我的意思是所有的docs上getopt说它使用?。
我究竟做错了什么?
我在一个文件中有一个如下所示的 bash 脚本nepleaks_upd.sh,我想以./nepleaks_upd.sh bootstrap --branch off. 无法接受--branch,但它的作用是./nepleaks_upd.sh bootstrap -b off.
usage() { echo "Usage: $0 [prepare | up | down] [-b <on/off>]" 1>&2; exit 1; }
case "$1" in
bootstrap)
while getopts ":b:" o; do
case "${o}" in
b)
b=${OPTARG}
if [ ${b} == "off" ]; then
echo "git clone https://github.com/iPrayag/dotfiles.git"
## logic
fi
;;
*)
echo ${o}
usage
;;
esac
done
shift $((OPTIND-1))
echo "option1 = ${o}"
echo "option2 = ${b}" …Run Code Online (Sandbox Code Playgroud) 在下面的代码,当我给选项r则getopts需要一个参数:
while getopts ":hr::l:" opt; do
case $opt in
r ) echo "Run Numbers - argument = $OPTARG " ;;
l ) echo "Latency range - argument = $OPTARG" ;;
h ) helptext
graceful_exit ;;
* ) usage
clean_up
exit 1
esac
done
Run Code Online (Sandbox Code Playgroud)
但是我需要在-r选项之后传递两个参数,而不是一个。是否有捷径可寻?
我正在使用一个非常简单的 bash 脚本,但我遇到了一个无法解决的问题:
我有myscript.sh三个参数,-u,-h, 和-p。和-u都是 -h强制性的,需要脚本运行。
我想做的是,如果myscript.sh -u User1仅此而已,它应该以 终止exit 1。
我希望我的脚本能够分析并运行脚本(如果myscript.sh -u User1 -h Localhost有选项),否则它应该退出。
非常感谢
我f根据此处的示例(在“带参数的选项”下)在 Bash 中定义了该函数:
f () {
while getopts ":a:" opt; do
case $opt in
a)
echo "-a was triggered, Parameter: $OPTARG" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
return 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
return 1
;;
esac
done
}
Run Code Online (Sandbox Code Playgroud)
虽然他们使用脚本,但我直接在 shell 中定义函数。
当我第一次启动 Bash 并定义函数时,一切正常:f -a 123prints -a was triggered, Parameter: 123。但是当我第二次运行完全相同的行时,没有打印任何内容。
是什么导致了这种行为?它发生在 Bash 3.2 和 4.3 中,但它在 Zsh 5.1 中工作正常。这令人惊讶,因为该示例应该用于 Bash,而不是用于 Zsh。
我使用 getopts 将 bash 脚本中的参数解析为
while getopts ":hd:" opt; do
case $opt in
d ) echo "directory = $OPTARG"; mydir="$OPTARG"; shift $((OPTIND-1)); OPTIND=1 ;;
h ) helptext
graceful_exit ;;
* ) usage
clean_up
exit 1
esac
done
exeparams="$*"
Run Code Online (Sandbox Code Playgroud)
exeparams将保存任何未解析的选项/参数。因为我想使用 exeparams 来保存要在脚本中执行的命令的选项(它可以与脚本自己的选项重叠),所以我想使用 -- 来结束传递给脚本的选项。如果我通过例如
myscript -d myscriptparam -- -d internalparam
Run Code Online (Sandbox Code Playgroud)
exeparams 将举行
-- -d internalparam
Run Code Online (Sandbox Code Playgroud)
我现在想删除--将这些参数传递给内部命令的前导。有没有一种优雅的方法来做到这一点,或者我可以获得一个只包含其余部分而不--来自 getopts的字符串?
在使用时的选项字符串中getopts,来自http://wiki.bash-hackers.org/howto/getopts_tutorial
如果选项字符串的第一个字符是 :(冒号),这通常是无意义的,因为它前面没有选项字母,getopts 会切换到“静默错误报告模式”。在生产脚本中,这通常是您想要的,因为它允许您自己处理错误而不会被烦人的消息打扰。
我想知道以下是什么意思:
“静默错误报告模式”
“它允许您自己处理错误而不会被烦人的消息打扰”?
你能举一些例子吗?
我正在尝试构建一个接受各种选项的 shell 脚本,这getopts似乎是一个很好的解决方案,因为它可以处理选项和参数的可变排序(我认为!)。
我只会使用短选项,每个短选项都需要一个相应的值,例如:./command.sh -a arga -g argg -b argb但我希望允许以非特定顺序输入选项,这是大多数人习惯使用 shell 命令的方式.
另一点是我想自己检查选项参数值,最好是在case语句中。这样做的原因是我:)在case声明中的测试产生了不一致的结果(可能是由于我缺乏理解)。
例如:
#!/bin/bash
OPTIND=1 # Reset if getopts used previously
if (($# == 0)); then
echo "Usage"
exit 2
fi
while getopts ":h:u:p:d:" opt; do
case "$opt" in
h)
MYSQL_HOST=$OPTARG
;;
u)
MYSQL_USER=$OPTARG
;;
p)
MYSQL_PASS=$OPTARG
;;
d)
BACKUP_DIR=$OPTARG
;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 2;;
:)
echo "Option -$OPTARG requires an argument" >&2
exit 2;; …Run Code Online (Sandbox Code Playgroud)