Bash 脚本空参数测试

Bash 脚本空参数测试

我正在尝试编写一个具有以下逻辑的简单脚本:如果第一个参数是有效的常规文件,则运行 for 循环;如果没有提供参数,则运行“code2”;除此之外,运行“code3”。下面的脚本对我来说似乎没问题,但如果不带参数运行它就会卡住。

#!/bin/bash

if [ -f $1 ]; then
  for i in `cat $1`
  do
    <something>
  done
elif [ $# -eq 0 ]; then
  "code2"
else
  "code3"
fi

这是调试输出,最后卡住了。

bash -x myscript
+ '[' -f ']'
++ cat

既然我没有提供任何参数,为什么它仍然会遇到第一个 if-then 流程?我是 bash 脚本新手。任何帮助将不胜感激。

答案1

如果你不引用该变量,"$1"那么它就什么都没有并消失。然后执行的代码是(如 shell-x选项所报告的):

[ -f ]

其中,-f长度不为零的字符串会导致真正的测试并运行该then部分。

你需要写(至少):

[ -f "$1" ]

如果有一个空的论证,它将变成

[ -f "" ]

并报告文件匹配失败""

另一种替代方法是使用参数扩展(不需要外部引用):

[ -f ${1:-""} ]

""如果 的值为$1null 或空,它将扩展到。

并且请不要执行 for 循环来遍历文件的行。你应该考虑使用while read循环

#!/bin/sh

if [ -f ${1:-""} ]; then
  while read -r line; do
      echo '<something>'
  done <"$1"
elif [ "$#" -eq 0 ]; then
  echo "code2"
else
  echo "code3"
fi

答案2

简单的答案是因为对于不存在的$1,它也没有被引用(也是问题的一部分),shell将表达式视为[ -f ]并且这里看到-f[不被识别为标志,而只是一个单一的“表达式”。它实际上与:

$ [ abracadabra  ] && echo "success"
success

并引用手册test(如果您不知道它是 的别名[):

   An  omitted  EXPRESSION  defaults  to false.  Otherwise, EXPRESSION is true or false and sets exit
   status.  It is one of:

   ( EXPRESSION )
          EXPRESSION is true

请注意,如果您确实引用了该表达式,那么在跟踪输出时它看起来会像这样,即它实际上会尝试将空字符串计算为现有文件名:

$ (set -x; [ -f "$this_var_doesnt_exist"  ] && echo "hi" )
+ '[' -f '' ']'

相关内容