处理未使用的 getopts 参数
Handling unused getopts argument
我有一个以 getopts 开头的脚本,如下所示:
USAGE() { echo -e "Usage: bash [=10=] [-w <in-dir>] [-o <out-dir>] [-c <template1>] [-t <template2>] \n" 1>&2; exit 1; }
if (($# == 0))
then
USAGE
fi
while getopts ":w:o:c:t:h" opt
do
case $opt in
w ) BIGWIGS=$OPTARG
;;
o ) OUTDIR=$OPTARG
;;
c ) CONTAINER=$OPTARG
;;
t ) TRACK=$OPTARG
;;
h ) USAGE
;;
\? ) echo "Invalid option: -$OPTARG exiting" >&2
exit
;;
: ) echo "Option -$OPTARG requires an argument" >&2
exit
;;
esac
done
more commands etc
echo $OUTDIR
echo $CONTAINER
我对 getopts 还很陌生。我正在对该脚本进行一些测试,在某个阶段,我没有 need/want 使用 -c 参数 [-c ]。换句话说,我试图测试脚本的另一个完全不涉及 $CONTAINER 变量的特定部分。因此,我简单地在所有带有 $CONTAINER 的命令前添加了 # 并做了一些测试,这很好。
在不使用 $CONTAINER 测试脚本时,我输入了:
bash script.bash -w mydir -o myoutdir -t mywantedtemplate
但是,我想知道,根据我的 getopts 命令,我没有收到警告。换句话说,为什么我没有收到要求 -c 参数的警告。这可能吗?警告是否仅在我键入时出现:
bash script.bash -w mydir -o myoutdir -t mywantedtemplate -c
更新
经过一些测试,我认为是这样:
- 如果你没有明确地写“-c”,getopts 不会 "ask" 你并给你一个错误(除非你的脚本正在用它做一些事情 - 即如果你没有使用此参数将 # 放在每个命令的前面)
- 只有输入“-c”才会出现错误
这是正确的吗?
getopts
不会在某些选项未使用时发出警告(即它们是 可选的 )。通常这是一件好事,因为某些选项(例如 -h
)不与其他选项一起使用。无法直接使用 Bash 内置 getopts
指定强制选项。如果您想要强制选项,那么您将需要编写代码来检查它们是否已被使用。参见 bash getopts with multiple and mandatory options。此外(如您所见),如果您未能编写代码来处理 getopts
.
的 optstring
(第一个)参数中指定的选项,则不会出现错误
通过在 Bash 代码中使用 nounset
设置(使用 set -o nounset
或 set -u
),您可以获得一种针对强制参数的自动警告。如果未指定 -c
选项,因此未设置 $CONTAINER
,这将导致针对 echo $CONTAINER
之类的代码发出警告。但是,使用 nounset
选项意味着需要更仔细地编写 all 代码。有关详细信息,请参阅 ,包括评论和 "Linked" 答案。
您可能会使用这个脚本:
printf
捕获stdout
并放入stderr
然后返回stdout
也捕获exit
代码,所以我们可以处理如果代码大于 0
.
some_command() {
echo 'this is the stdout'
echo 'this is the stderr' >&2
exit 1
}
run_command() {
{
IFS=$'\n' read -r -d '' stderr;
IFS=$'\n' read -r -d '' stdout;
(IFS=$'\n' read -r -d '' _ERRNO_; exit ${_ERRNO_});
} < <((printf '[=10=]%s[=10=]%d[=10=]' "$(some_command)" "${?}" 1>&2) 2>&1)
}
echo 'Run command:'
if ! run_command; then
## Show the values
typeset -p stdout stderr
else
typeset -p stdout stderr
fi
只需将 some_command
替换为 getopts ":w:o:c:t:h"
我有一个以 getopts 开头的脚本,如下所示:
USAGE() { echo -e "Usage: bash [=10=] [-w <in-dir>] [-o <out-dir>] [-c <template1>] [-t <template2>] \n" 1>&2; exit 1; }
if (($# == 0))
then
USAGE
fi
while getopts ":w:o:c:t:h" opt
do
case $opt in
w ) BIGWIGS=$OPTARG
;;
o ) OUTDIR=$OPTARG
;;
c ) CONTAINER=$OPTARG
;;
t ) TRACK=$OPTARG
;;
h ) USAGE
;;
\? ) echo "Invalid option: -$OPTARG exiting" >&2
exit
;;
: ) echo "Option -$OPTARG requires an argument" >&2
exit
;;
esac
done
more commands etc
echo $OUTDIR
echo $CONTAINER
我对 getopts 还很陌生。我正在对该脚本进行一些测试,在某个阶段,我没有 need/want 使用 -c 参数 [-c ]。换句话说,我试图测试脚本的另一个完全不涉及 $CONTAINER 变量的特定部分。因此,我简单地在所有带有 $CONTAINER 的命令前添加了 # 并做了一些测试,这很好。
在不使用 $CONTAINER 测试脚本时,我输入了:
bash script.bash -w mydir -o myoutdir -t mywantedtemplate
但是,我想知道,根据我的 getopts 命令,我没有收到警告。换句话说,为什么我没有收到要求 -c 参数的警告。这可能吗?警告是否仅在我键入时出现:
bash script.bash -w mydir -o myoutdir -t mywantedtemplate -c
更新
经过一些测试,我认为是这样:
- 如果你没有明确地写“-c”,getopts 不会 "ask" 你并给你一个错误(除非你的脚本正在用它做一些事情 - 即如果你没有使用此参数将 # 放在每个命令的前面)
- 只有输入“-c”才会出现错误
这是正确的吗?
getopts
不会在某些选项未使用时发出警告(即它们是 可选的 )。通常这是一件好事,因为某些选项(例如 -h
)不与其他选项一起使用。无法直接使用 Bash 内置 getopts
指定强制选项。如果您想要强制选项,那么您将需要编写代码来检查它们是否已被使用。参见 bash getopts with multiple and mandatory options。此外(如您所见),如果您未能编写代码来处理 getopts
.
optstring
(第一个)参数中指定的选项,则不会出现错误
通过在 Bash 代码中使用 nounset
设置(使用 set -o nounset
或 set -u
),您可以获得一种针对强制参数的自动警告。如果未指定 -c
选项,因此未设置 $CONTAINER
,这将导致针对 echo $CONTAINER
之类的代码发出警告。但是,使用 nounset
选项意味着需要更仔细地编写 all 代码。有关详细信息,请参阅
您可能会使用这个脚本:
printf
捕获stdout
并放入stderr
然后返回stdout
也捕获exit
代码,所以我们可以处理如果代码大于 0
.
some_command() {
echo 'this is the stdout'
echo 'this is the stderr' >&2
exit 1
}
run_command() {
{
IFS=$'\n' read -r -d '' stderr;
IFS=$'\n' read -r -d '' stdout;
(IFS=$'\n' read -r -d '' _ERRNO_; exit ${_ERRNO_});
} < <((printf '[=10=]%s[=10=]%d[=10=]' "$(some_command)" "${?}" 1>&2) 2>&1)
}
echo 'Run command:'
if ! run_command; then
## Show the values
typeset -p stdout stderr
else
typeset -p stdout stderr
fi
只需将 some_command
替换为 getopts ":w:o:c:t:h"