检查Bash shell脚本中是否存在输入参数

use*_*187 1223 bash shell

我需要检查输入参数是否存在.我有以下脚本

if [ "$1" -gt "-1" ]
  then echo hi
fi
Run Code Online (Sandbox Code Playgroud)

我明白了

[: : integer expression expected
Run Code Online (Sandbox Code Playgroud)

如何首先检查输入参数1以查看它是否存在?

pho*_*xis 2114

它是:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi
Run Code Online (Sandbox Code Playgroud)

$#变量将告诉您脚本传递的输入参数的数量.

或者您可以检查参数是否为空字符串或不是:

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi
Run Code Online (Sandbox Code Playgroud)

-z开关是检验的"$ 1"的扩张是一个空字符串或没有.如果它是一个空字符串,则执行正文.

  • 当脚本运行需要参数时,您可能希望在if块内的回声末尾添加`exit 1`.显而易见,但值得注意的是完整性. (153认同)
  • 和可选的args`如果[!-z"$ 1"]; 然后......` (70认同)
  • 我喜欢这样做,用简洁的语法,仍然可以接受POSIX.`[-z"$ 1"] && echo"没有提供参数"`我更喜欢单行,因为它们对我来说更容易; 与使用`if`相比,检查退出值也更快 (55认同)
  • 对于一个菜鸟,特别是来自非脚本背景的人,提及这些事情的一些特点也很重要.您还可以提到我们在打开和关闭支撑后需要一个空格.否则事情不起作用.我自己是一个脚本菜鸟(我来自C背景)并且发现它很难.只有当我决定按照"原样"复制整个事情时,事情才适合我.就在那时我意识到我必须在开口支架之后和关闭之前留出空间. (31认同)
  • 尽管很少有用,但第一个参数可以初始化但是空的; `programname""secondarg third`.`$ #`检查明确地检查参数的数量. (14认同)
  • @HighOnMeat没有提到的原因是因为必须在每个使用if语句的地方提及它.这太过分了.但是,像你这样评论这样的人就是优秀的,正如你所看到的,看起来你帮助了4个人学习这个. (5认同)
  • 我喜欢将错误消息回显到stderr:`echo“未提供参数”>&2` (3认同)
  • 我对此有些迷恋。请注意,[和之前]后的空格至关重要。if [$#-eq 0]不起作用,但是if [$#-eq 0]则不起作用。 (2认同)
  • @gcb你必须使用“-n”选项代替“!-z”,正如你可以在这里看到的:https://github.com/koalaman/shellcheck/wiki/SC2236 (2认同)

小智 313

最好以这种方式进行演示

if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

如果参数太少,通常需要退出.

  • 不,不是:这有你通常想要的`退出1',并使用`[[]]`测试,其中(iirc)通常更合理.因此,对于盲目复制粘贴代码的人来说,这是更好的答案. (71认同)
  • 要了解有关[]和[[]]之间差异的更多信息,请参阅http://stackoverflow.com/questions/3427872/whats-the-difference-between-and-in-bash (36认同)
  • 这个答案比接受的答案更好,因为 1. 退出时出现错误代码比继续使用无效数据更好,并且 2. `[[` 通常比 `[` 更合理。 (5认同)

Ale*_* N. 94

如果您只想检测是否缺少特定参数,则参数替换很好:

scale=${2:-1}
emulator @$1 -scale $scale
Run Code Online (Sandbox Code Playgroud)

在某些情况下,您需要检查用户是否将参数传递给脚本,如果没有,则返回默认值.如下面的脚本:

scale=${2:-1}
emulator @$1 -scale $scale
Run Code Online (Sandbox Code Playgroud)

这里如果用户没有scale作为第二个参数传递,我-scale 1默认启动Android模拟器.${varname:-word}是一家扩张运营商.还有其他扩展运营商:

  • ${varname:=word}其中设置所述未定义varname的而不是返回word值;
  • ${varname:?message}varname如果它被定义并且不为null则返回,或者打印message并中止脚本(如第一个例子);
  • ${varname:+word}返回word如果只varname被定义并且不为空; 否则返回null.

  • Eki,":"是本例中的内置命令和/ bin/true的简写.它表示一个do-nothing命令,它基本上忽略了它提供的参数.在此测试中必不可少的是为了防止解释器尝试执行"$ varname"(您当然不希望发生)的内容.还值得注意; 您可以根据需要使用此方法测试尽可能多的变量.并且都有特定的错误消息.即`:$ {1?"第一个参数为空"} $ {2?"请提供超过1个参数"}` (6认同)

Ran*_*r T 39

尝试:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi
Run Code Online (Sandbox Code Playgroud)

  • 为什么你需要`$ #`和`0`的双引号? (4认同)
  • 这个答案为我刚制作的剧本提供了很好的起点.感谢您展示'else`. (2认同)
  • bash中的@ user13107用双引号引起来的变量可以防止乱序(例如,扩展文件名,如foo *)和单词拆分(即,如果值包含空格,则拆分内容)。在这种情况下,不必引用$$,因为这两种情况都不适用。也不用用引号'0'表示,但是有些人更喜欢用引号引起来,因为它们实际上是字符串,这使它更加明确。 (2认同)

dev*_*ull 36

另一种检测参数是否传递给脚本的方法:

((!$#)) && echo No arguments supplied!
Run Code Online (Sandbox Code Playgroud)

请注意,这(( expr ))会导致根据Shell算法的规则计算表达式.

为了在没有任何论据的情况下退出,可以说:

((!$#)) && echo No arguments supplied! && exit 1
Run Code Online (Sandbox Code Playgroud)

另一种(类似的)说上述方式是:

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!
Run Code Online (Sandbox Code Playgroud)

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.
Run Code Online (Sandbox Code Playgroud)

  • -1 如果验证参数的存在,这可能是最糟糕的方法......而且它可以触发历史替换并可能做坏事。 (2认同)
  • 而不是杀死我的zsh进程的`exit`,我使用不会杀死它的`return` (2认同)

小智 22

我经常将此代码段用于简单脚本:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)


Ser*_*ndt 22

更现代

#!/usr/bin/env bash

if [[ $# -gt 0 ]]
  then echo Arguments were provided.
  else echo No arguments were provided.
fi
Run Code Online (Sandbox Code Playgroud)

  • @AlJohri 以下是您问题的一些答案:/sf/ask/46861671/ 和 https://superuser.com/q/1533900/219226。 (2认同)

小智 16

只是因为有更多的基点要指出我会添加你可以简单地测试你的字符串为null:

if [ "$1" ]; then
  echo yes
else
  echo no
fi
Run Code Online (Sandbox Code Playgroud)

同样,如果你期待arg计数只是测试你的最后一次:

if [ "$3" ]; then
  echo has args correct or not
else
  echo fixme
fi
Run Code Online (Sandbox Code Playgroud)

等等任何arg或var


Bra*_*rks 8

如果您想检查参数是否存在,您可以检查参数# 是否大于或等于您的目标参数编号。

以下脚本演示了这是如何工作的

测试文件

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi
Run Code Online (Sandbox Code Playgroud)

产生以下输出

$ ./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
Run Code Online (Sandbox Code Playgroud)