我正在创建一个非常简单的sh文件来执行某些操作,但我想传递一个没有值的参数,例如:
./fuim -l
Run Code Online (Sandbox Code Playgroud)
但我收到以下消息:
./fuim: option requires an argument -- l
Run Code Online (Sandbox Code Playgroud)
如果我传递一个随机值,就像./fuim -l 1它完美无缺.我怎样才能做到这一点?
这是我到目前为止所拥有的:
while getopts e:f:l:h OPT
do
case "$OPT" in
h) print_help ;;
e) EXT=$OPTARG ;;
f) PROJECT_FOLDER=$OPTARG ;;
l) LIST_FILES=1 ;;
?) print_help ;;
esac
done
shift $((OPTIND-1))
if [ -z "$EXT" ] || [ -z "$PROJECT_FOLDER" ]; then
print_help
fi
Run Code Online (Sandbox Code Playgroud) 我使用以下行(希望这是最好的做法,如果不能纠正我)来处理命令行选项:
#!/usr/bin/bash
read -r -d '' HELP <<EOF
OPTIONS:
-c Enable color output
-d Enable debug output
-v Enable verbose output
-n Only download files (mutually exclusive with -r)
-r Only remove files (mutually exclusive with -n)
-h Display this help
EOF
# DECLARE VARIABLES WITH DEFAULT VALUES
color=0
debug=0
verbose=0
download=0
remove=0
OPTIND=1 # Reset in case getopts has been used previously in the shell
invalid_options=(); # Array for invalid options
while getopts ":cdvnrh" opt; do
echo "Actual opt: …Run Code Online (Sandbox Code Playgroud) 我试图理解为什么getopts如果“未命名”参数在任何命名参数之前似乎会忽略所有参数。
使用http://wiki.bash-hackers.org/howto/getopts_tutorial中的示例,
#!/bin/bash
while getopts ":a" opt; do
case $opt in
a)
echo "-a was triggered!" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
并观察结果:
$ ./opt_test
$ ./opt_test -a
-a was triggered!
$ ./opt_test -a -f
-a was triggered!
Invalid option: -f
$ ./opt_test a -a -f
$ ./opt_test a -a
$ ./opt_test a -f
$ ./opt_test lala -f
$
Run Code Online (Sandbox Code Playgroud)
因此,在前面添加一个未命名的参数(没有破折号的参数)似乎会getopts忽略所有参数。
这是为什么?我该如何解决这个问题?我希望我的程序能够捕获此类内容并打印使用屏幕。
我正在创建一个基本脚本,该脚本应该采用3个强制命令行选项,每个选项必须后跟一个值.像这样:
$ myscript.sh -u <username> -p <password> -f <hosts.txt>
Run Code Online (Sandbox Code Playgroud)
我正在尝试确保用户正在传递那些确切的3个选项及其值,而不是其他内容,否则我想打印使用消息并退出.
我一直在阅读getopts并想出了这个:
usage () { echo "Usage : $0 -u <username> -p <password> -f <hostsFile>"; }
if [ $# -ne 6 ]
then
usage
exit 1
fi
while getopts u:p:f: opt ; do
case $opt in
u) USER_NAME=$OPTARG ;;
p) USER_PASSWORD=$OPTARG ;;
f) HOSTS_FILE=$OPTARG ;;
*) usage; exit 1;;
esac
done
echo "USERNAME: $USER_NAME"
echo "PASS: $USER_PASSWORD"
echo "FILE: $HOSTS_FILE"
Run Code Online (Sandbox Code Playgroud)
我希望如果我没有通过任何我的3个"强制"选项(即:-u -p -f),Optargs验证将通过" *)"情况捕获.虽然对于其他选项来说也是如此,例如"-a"," - b"等......在这种特殊情况下似乎并非如此:
$ myscript.sh …Run Code Online (Sandbox Code Playgroud) 我正在尝试将 getopts 用于 bash 脚本。该脚本可以有标志,所有这些标志都是强制性的,并且需要包含一个值。当应该包含值的强制标志之一为空时,getopts 使用下一个行标志作为其内容。我该如何防止这种情况?
这是我的例子:
#!/bin/bash
while getopts "A:B:" OPTION
do
case $OPTION in
A)
GILIA="$GILIA $OPTARG"
echo GILIA $GILIA
;;
B)
GILIB="$GILIB $OPTARG"
echo GILIB $GILIB
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
当使用两个带有值的标志时:
./test_opt2 -A aaa -B bbb
GILIA aaa
GILIB bbb
Run Code Online (Sandbox Code Playgroud)
当使用“-A”标志为空时:
./test_opt2 -A -B bbb
GILIA -B
Run Code Online (Sandbox Code Playgroud)
我知道这是 getopts 的正常/典型行为,并且我确信有一种方法可以解决这个问题......
有任何想法吗?
我有以下简单的代码:
#!/usr/bin/env bash
while getopts :f arg; do
case $arg in
f) echo Option $arg specified. ;;
*) echo Unknown option: $OPTARG. ;;
esac
done
Run Code Online (Sandbox Code Playgroud)
它适用于简单的场景,例如:
$ ./test.sh -f
Option f specified.
$ ./test.sh -a -f
Unknown option: a.
Option f specified.
Run Code Online (Sandbox Code Playgroud)
但是它不适用于以下情况:
$ ./test.sh foo -f
$ ./test.sh -a abc -f
Unknown option: a.
Run Code Online (Sandbox Code Playgroud)
如何修复上述代码示例以支持无效参数?
为什么此选项仅在第一次使用时有效,然后每隔一次就被忽略?就像不使用该选项时正在重置一样。
这是我的功能:
testopts() {
local var="o false"
while getopts "o" option; do
case "${option}" in
o)
var="o true"
;;
esac
done
echo $var
}
Run Code Online (Sandbox Code Playgroud)
运行它时,它仅在第一次传递选项时返回 true。
Run Code Online (Sandbox Code Playgroud)$ testopts o false $ testopts -o o true $ testopts -o o false
是否可以将命令行参数从bourne脚本中传递到函数中,以便允许getopts处理它们.
我的其余部分很好地打包到函数中,但它开始看起来我必须将参数处理移动到主逻辑中.
以下是它现在的编写方式,但它不起作用:
processArgs()
{
while getopts j:f: arg
do
echo "${arg} -- ${OPTARG}"
case "${arg}" in
j) if [ -z "${filename}" ]; then
job_number=$OPTARG
else
echo "Filename ${filename} already set."
echo "Job number ${OPTARG} will be ignored.
fi;;
f) if [ -z "${job_number}" ]; then
filename=$OPTARG
else
echo "Job number ${job_number} already set."
echo "Filename ${OPTARG} will be ignored."
fi;;
esac
done
}
doStuff1
processArgs
doStuff2
是否有可能以一种可以读取脚本args的方式定义函数?这可以通过其他方式完成吗?我喜欢getopts的功能,但看起来在这种情况下,我将不得不牺牲代码之美来获得它.
可以使用getopts拾取全字标志吗?
如下所示:
while getopts ":abc --word" opt; do
case ${opt} in
a) SOMETHING
;;
...
--word) echo "Do something else."
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
试图拿起那些双破折号。
这是我的脚本。我根据本教程对其进行了改编,因此它不会是脚本本身的错误。(原始脚本也有同样的问题。)
#!/bin/bash
while getopts "a:" opt; do
case $opt in
a)
echo "-a was triggered, Parameter: $OPTARG"
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
这是我的输出:
bash-3.2$ source getopt.sh
bash-3.2$ source getopt.sh -a /dev/null
-a was triggered, Parameter: /dev/null
bash-3.2$ source getopt.sh -a /dev/null
bash-3.2$
Run Code Online (Sandbox Code Playgroud)
我已经梳理了互联网,找不到对这种行为的任何解释。
getopts ×10
bash ×9
shell ×3
linux ×2
arguments ×1
command-line ×1
sh ×1
syntax ×1
ubuntu-14.04 ×1
unix ×1