我正在编写一个bash脚本,我希望从外部向我的脚本发送一个参数,该参数以连字符( - )开头,如此' -d'。
但是,当我执行脚本
时,我会收到以下警告dirname:无效选项 - ' d'
我正在说警告,因为我可以看到我的脚本尽管如此仍在工作。但我也希望摆脱这些警告。有人可以帮忙吗?
为了进一步澄清,我正在执行这样的脚本 -
sh script.sh <param1> -d <param2>
从正在使用此参数的脚本中附加代码片段
case ${2} in
-d|--days) timeUnit="d";;
-h|--hours) timeUnit="h";;
答案 0 :(得分:2)
这不是警告,这是一个错误。
如果您想将以短划线开头的文件名传递给dirname
,那么您有两种选择:
dirname -- -d
或
dirname ./-d
根据您的调用行,我们可以推断您必须错误地将-d参数从脚本的参数列表中继到为脚本内部调用的dirname
调用提供的参数列表
你可能在你的剧本中做了类似的事情:
dirname "$@"
或者
dirname "$2"
其中任何一个都会将-d参数传递给dirname
。
您需要正确解析脚本的参数,并仅将脚本的-d选项的选项值传递给dirname
调用。此过程通常称为选项处理。
以下是如何进行期权处理的示例:
dir='';
nonOpt=();
for ((i = 1; i <= $#; ++i)); do
arg="${@:$i:1}";
if [[ "$arg" == '--' ]]; then
nonOpt+=("${@:$i+1}");
break;
elif [[ "$arg" == -?* ]]; then
case "${arg:1}" in
(d|dir)
if [[ $i -eq $# ]]; then printf 'error: trailing -d option.\n' >&2; exit 1; fi;
let ++i;
dir="${@:$i:1}";
;;
(h|help)
printf 'script.sh [-h|--help] {param1} -d|--dir {dir}\n' >&2;
exit 1;
;;
(*)
printf "error: invalid option: $arg.\\n" >&2;
exit 1;
;;
esac;
else
nonOpt+=("$arg");
fi;
done;
if [[ ${#nonOpt[@]} -ne 1 ]]; then printf 'error: require 1 non-option argument.\n' >&2; exit 1; fi;
param1="${nonOpt[0]}";
if [[ "$dir" == '' ]]; then printf 'error: missing {dir}.\n' >&2; exit 1; fi;
dirname -- "$dir";
答案 1 :(得分:0)
答案 2 :(得分:0)
问题在于您对内部参数的处理方式。请注意,大多数程序将以连字符开头的参数视为一个选项,因此在传递实际参数之前,使用--
正确结束选项并不重要。
在您的情况下,假设您将$1
传递给dirname
,它应该如下所示:
dir=`dirname -- "$1"`
或者如果它应该是shell的真正选项,那么你必须首先使用它并删除,shift
将完成工作:
while [ $# -ne 0 ]; do
case "$1" in
-d)
myoptionD=true
shift
;;
-*)
echo "Unknown option: $1" >&2
exit 2
;;
*)
break
;;
esac
done
...或者您也可以使用getopt
。