【发布时间】:2011-09-22 20:48:51
【问题描述】:
我需要检查输入参数是否存在。我有以下脚本
if [ "$1" -gt "-1" ]
then echo hi
fi
我明白了
[: : integer expression expected
如何先检查输入参数 1 是否存在?
【问题讨论】:
我需要检查输入参数是否存在。我有以下脚本
if [ "$1" -gt "-1" ]
then echo hi
fi
我明白了
[: : integer expression expected
如何先检查输入参数 1 是否存在?
【问题讨论】:
它是:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
$# 变量将告诉您脚本传递的输入参数的数量。
或者您可以检查参数是否为空字符串:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
-z 开关将测试"$1" 的扩展是否为空字符串。如果是空字符串,则执行正文。
【讨论】:
[ -z "$1" ] && echo "No argument supplied" 我更喜欢单线,因为它们对我来说更容易;与使用 if 相比,检查退出值也更快
exit 1。显而易见,但值得注意的是完整性。
programname "" secondarg third。 $# 检查明确检查参数的数量。
if [ ! -z "$1" ]; then ...
另一种检测参数是否传递给脚本的方法:
((!$#)) && echo No arguments supplied!
请注意,(( expr )) 会导致表达式按照 Shell Arithmetic 的规则进行评估。
为了在没有任何参数的情况下退出,可以说:
((!$#)) && echo No arguments supplied! && exit 1
另一种 (类似的) 说法是:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let 说:
let: let arg [arg ...]Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
【讨论】:
exit 杀死我的 zsh 进程,我使用 return 不会杀死它
((!$#)) 会触发历史记录替换?
试试:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
【讨论】:
$# 和0 需要双引号?
else。
foo*)和分词(即,如果值包含空格,则拆分内容)。在这种情况下,没有必要引用$#,因为这两种情况都不适用。引用 0 也不是必须的,但有些人更喜欢引用值,因为它们实际上是字符串,这使得它更加明确。
提醒一下,Bash 中的数字测试运算符仅适用于整数(-eq、-lt、-ge 等)
我喜欢确保我的 $vars 是整数
var=$(( var + 0 ))
在我测试它们之前,只是为了防止出现“[: integer arg required”错误。
【讨论】:
var=$(printf "%.0f" "$var") 可以处理浮点数,但在给定字符串时会出现非零退出。如果您不介意 awk,我使用的这种方法似乎是执行整数的最可靠的方法:var=$(<<<"$var" awk '{printf "%.0f", $0}')。如果 var 未设置,则默认为“0”。如果 var 是浮点数,则四舍五入到最接近的整数。负值也可以使用。
最好这样演示
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
如果参数太少,通常需要退出。
【讨论】:
exit 1,并使用通常更合理的[[ ]] 测试。所以对于盲目复制粘贴代码的人来说,这是更好的答案。
在某些情况下,您需要检查用户是否向脚本传递了参数,如果没有,则回退到默认值。就像在下面的脚本中一样:
scale=${2:-1}
emulator @$1 -scale $scale
如果用户没有将scale 作为第二个参数传递,我默认使用-scale 1 启动Android 模拟器。 ${varname:-word} 是扩展运算符。还有其他扩展运算符:
${varname:=word} 设置未定义的 varname 而不是返回 word 值;${varname:?message} 如果已定义且不为空,则返回 varname 或打印 message 并中止脚本(如第一个示例);${varname:+word} 仅当 varname 已定义且不为空时才返回 word;否则返回 null。【讨论】:
${varname?message}。额外的: 是拼写错误,还是会改变行为?
: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
如果您想检查参数是否存在,您可以检查参数的数量是否大于或等于您的目标参数数。
以下脚本演示了它是如何工作的
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
产生以下输出
$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments
【讨论】:
我经常将这个 sn-p 用于简单的脚本:
#!/bin/bash
if [ -z "$1" ]; then
echo -e "\nPlease call '$0 <argument>' to run this command!\n"
exit 1
fi
【讨论】:
只是因为有一个更基点要指出,我要补充一点,你可以简单地测试你的字符串是否为空:
if [ "$1" ]; then
echo yes
else
echo no
fi
同样,如果您期望 arg 计数,只需测试您的最后一个:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
任何 arg 或 var 以此类推
【讨论】:
单行 bash 函数验证
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
添加函数名称和用法
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
添加验证以检查是否为整数
要添加额外的验证,例如检查传递的参数是否为整数,修改验证一行以调用验证函数:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
然后,构造一个验证函数来验证参数,成功时返回 0,失败时返回 1,失败时中止脚本的 die 函数
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
更简单 - 只需使用 set -u
set -u 确保在使用时设置每个引用的变量,所以只需设置它并忘记它
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
【讨论】:
在我的情况下,检查 last arguments 是否存在的唯一可行解决方案是:
if [[ "$7" == '' ]] ; then
echo "error"
exit
fi
【讨论】:
$7 是第 7 个参数(如果算上脚本名称 $0,则为第 8 个),所以这不会检查最后一个参数是否存在,它会检查第 7 个参数是否存在。
exit 会返回echo "error" 的退出状态,我预计是零。推荐shellcheck 和set -euo pipefail。我现在要停下来......