假设我有一个可执行的 bash 文件script.sh
。
我想用它作为
./script.sh p1 p2
p1
和p2
是该命令的两个必要参数。如果缺少其中任何一个,该命令就会失败。
所以我需要在继续执行之前检查它们script.sh
。我如何检查它们都已设置?
更新:
我试过这个:
# this is a comment line
if [ -n "$1" ] || [ -n "$2" ]; then
then echo 'haha'
fi
但得到:
./_scp.sh: line 3: syntax error near unexpected token `then'
./_scp.sh: line 3: ` then echo 'haha''
答案1
在 POSIX shell 中,如果您只想检查是否设置了两个参数,请尝试:
if [ "$#" -lt 2 ]; then
echo >&2 'Need 2 parameter'
exit 1
fi
如果您想要两个非空参数,则应该使用-z
代替-n
。-n
测试长度是否非零,-z
测试长度是否为零。
if [ -z "$1" ] || [ -z "$2" ]; then
echo >&2 'Need 2 parameters which are not empty'
exit 1
fi
通过bash
(andksh
和zsh
),您可以使用:
[ -v var ] && echo var was set
检查变量是否var
已设置。
$ [ -v var ] && echo var was set
$ var=
$ [ -v var ] && echo var was set
var was set
但请注意$1
,$2
不是变量,它们是一种不同类型的参数,称为位置参数。[ -v 1 ]
检查第一个位置参数是否设置在zsh
or中有效mksh
,但在bash
nor中无效ksh93
。
答案2
您可以让它们使脚本失败:
#!/bin/bash
: "${2:?} ${1:?}"
#If either one of the above is unset or null the
#script will have already exited with a meaningful
#diagnstic message written to standard error.
shell 退出时出现错误,并自动生成消息:确切地说,它与 shell 相关,但通常如下所示:
(set --; ${1:?})
sh: 2: 1: parameter not set or null
...在哪里第一个冒号分隔字段:是$0
,接下来是$LINENO
;其次是变量名称,最后诊断消息。您过去可能见过类似的消息。
您可以获取有关诊断消息的具体信息:
(set --; ${1:?Hi there!})
sh: 3: 1: Hi there!
此外,它是一个内联、隐式测试。如果目标参数是设置且不为空:
(或者如果从:?
参数扩展语法中删除冒号,则可能为 null ),它们正常扩展:
(set param; echo "${1:?This better not be empty!}")
param
这和其他形式的修改一样参数扩展,可以应用于其他类型的参数,而不仅仅是你的位置:
param= bash -c '
printf "Sure hope this works...\n" "${param:?Not a chance!}"
echo ... but what about me\?
' newzero
echo "RETURN: $?"
...打印到我的终端...
newzero: line 1: param: Not a chance!
RETURN: 127
可选的诊断消息本身就是一个扩展 - 无论它扩展成什么,shell 都会写出到 stderr。--help
当我向脚本添加选项解析时,我几乎总是将它用于消息。我只是做了一个小函数,并在遇到问题时将我期望的编号参数传递给它:
#script and more script
help(){ eval "\${$param:?\$(cat)}"; } <<HELP
Usage [ and the usual ... ]
HELP
while getopts ....
do case $opt in ($myopts) :;;
(*) param=$OPTIND help;;esac
done