我需要检查输入参数的存在性。我有下面的剧本
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"的扩展是否为空字符串。如果是空字符串,则执行正文。
我喜欢这样做,用简洁的语法,仍然可以接受POSIX。[ -z"$1" ] && echo"No argument supplied"我更喜欢一个衬垫,因为它们对我来说比较容易;与使用if相比,检查出口值也更快。
当脚本运行需要参数时,您可能希望在if块内的echos末尾添加一个exit 1。很明显,但值得注意的是完整性。
虽然很少有用,但第一个参数可能被初始化,但却是空的;programname"" secondarg third。$#检查明确检查参数的数量。
对于一个noob,特别是来自非脚本背景的人来说,提到这些东西的一些特性也是很重要的。你也可以提到,我们需要一个空间后,开幕和闭幕撑。否则事情就不起作用了。我自己就是一个编写脚本的noob(我来自C背景),并且发现这是一个困难的方法。只有当我决定复制整个"原样"的时候,事情才对我起作用。那时候我意识到我必须在开口支撑后和关闭支撑前留一个空间。
对于可选的args if [ ! -z"$1" ]; then ...
@重要的是,没有提到的原因是,在使用if语句的每个地方都必须提到它。那就太过分了。然而,像你这样的人这样的评论是非常好的,正如你所看到的,看起来你已经帮助了4个人来学习这个。
我喜欢将错误信息回送到stderr:echo"No argument supplied">&2。
@当然,这只是一个示范。
我对这件事有点犹豫不决。请注意,后面[之前]的空格至关重要。如果[$-eq 0]不起作用,但如果[$-eq 0]起作用。
你好!我正在检查传递给脚本的参数是否等于"var1"和"var2",因此我执行了流操作,但它不起作用:如果[[$1-ne'var1'$1-ne'var2']]则返回"bad argument"fi
最好这样示范
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
如果参数太少,通常需要退出。
这是已接受答案的副本,因此我认为应该删除它。
不,它不是:这有你通常想要的exit 1,并且使用了[[ ]]测试,这(iirc)通常更合理。所以对于盲目复制粘贴代码的人来说,这是更好的答案。
要了解更多关于[]和[]之间差异的信息,请参阅/questions/3427872/…
我认为指向[[]]和出口1的指针是有用的。
在某些情况下,您需要检查用户是否向脚本传递了参数,如果没有,则返回到默认值。就像下面的脚本:
scale=${2:-1}
emulator @$1 -scale $scale
这里,如果用户没有将scale作为第二个参数传递,那么我默认使用-scale 1启动android模拟器。${varname:-word}是一个扩展运算符。还有其他扩展运营商:
${varname:=word}设置未定义的varname而不是返回word值;
${varname:?message},如果定义了varname且不为空,则返回varname,或者打印message并中止脚本(如第一个示例);
${varname:+word},仅当varname已定义且不为空时才返回word;否则返回空。
上面的示例似乎使用了${varname?message}。额外的:是打字错误,还是改变了行为?
eki,在本例中":"是一个内置命令和/bin/true的缩写。它表示一个基本上忽略所提供参数的"不做任何事情"命令。为了防止解释器尝试执行"$varname"的内容(您当然不希望这样做),在这个测试中是非常重要的。同样值得注意的是,您可以使用此方法测试任意多个变量。所有这些都带有特定的错误消息。即: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}。
尝试:
#!/bin/bash
if ["$#" -eq "0" ]
then
echo"No arguments supplied"
else
echo"Hello world"
fi
为什么您需要对$#和0进行双报价?
如果我们不使用像$和0这样的双引号就没问题了
在窗户上,明格这是唯一的方法。
这个答案为我刚写的剧本提供了很好的起点。谢谢你也给我看了else。
@bash中的user13107双引号变量可防止全局化(即扩展文件名,如foo*)和分词(即如果值包含空格,则拆分内容)。在这种情况下,没有必要引用$#,因为这两种情况都不适用。引用0也是不必要的,但有些人更喜欢引用值,因为它们实际上是字符串,这使得它更加明确。
另一种检测参数是否传递到脚本的方法:
((!$#)) && echo No arguments supplied!
注意,(( expr ))使表达式按照shell算法的规则进行计算。
为了在没有任何论据的情况下退出,可以说:
((!$#)) && 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.
-1如果验证参数的存在,这可能是最糟糕的方法。另外,它可以触发历史替换,并可能做坏事。
我使用的不是杀死我的zsh进程的exit,而是不杀死它的return。
我经常将这段代码用于简单的脚本:
#!/bin/bash
if [ -z"$1" ]; then
echo -e"
Please call '$0 ' to run this command!
"
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等等
如果要检查参数是否存在,可以检查参数的是否大于或等于目标参数号。
下面的脚本演示了这是如何工作的试验室
#!/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
作为一个小提示,bash中的数值测试操作符只对整数(-eq、-lt、-ge等)起作用。
我想确保我的$vars
var=$(( var + 0 ))
在测试它们之前,只是为了防御"[:integer arg required"错误。
技巧很巧妙,但请注意:由于bash无法处理算术中的浮点,此方法可能导致语法错误并返回非零,这将成为启用errexit的障碍。var=$(printf"%.0f""$var")可以处理浮动,但在给定字符串时会遇到非零退出。如果您不介意使用awk,我使用的这个方法对于强制使用整数来说似乎是最健壮的:var=$(<