意外的文件结束bash脚本

时间:2013-11-18 12:15:39

标签: bash shell

这只是一个简单的问题,但我不明白为什么我在这里遇到错误。这只是if语句中的for循环。

这是我的代码:

#!/bin/bash
if (!( -f $argv[1])) then
    echo "Argv must be text file";
else if ($#argv != 1) then
    echo "Max argument is 1";
else if (-f $argv[1]) then
    for i in `cut -d ',' -f2 $argv[1]` 
        do
        ping -c 3 $i;
        echo "finish pinging host $i"
    done
fi

错误在第16行,即fi之后的一行,即空行......

有人可以解释为什么我有这个错误????

3 个答案:

答案 0 :(得分:2)

很多很多错误。

如果我试图接近您的示例代码:

#!/bin/sh
if [ ! -f "${1}" ]
then
   echo "Argv must be text file";
else if [ "${#}" -ne 1 ]
     then
        echo "Max argument is 1";
     else if [ -f "${1}" ]
          then
             for i in $(cat "${1}" | cut -d',' -f2 )
             do
                ping -c 3 "${i}";
                echo "finish pinging host ${i}"
             done
          fi
     fi
fi

另一种方式,每次不满足条件时退出:

#!/bin/sh
[ "${#}" -ne 1 ] && { echo "There should be 1 (and only 1) argument" ; exit 1 ; }
[ ! -f "${1}" ] && { echo "Argv must be a file." ; exit 1 ; }
[ -f "${1}" ] && {
   for i in $(cat "${1}" | cut -d',' -f2 )
   do
      ping -c 3 "${i}";
      echo "finish pinging host ${i}"
   done
}

答案 1 :(得分:0)

对于每个展开if,您必须有相应的结束fielse if也是如此。更好地使用elif代替

if test ! -f "$1"; then
    echo "Argv must be text file";
elif test $# != 1; then
    echo "Max argument is 1";
elif test -f "$1"; then
    for i in `cut -d ',' -f2 "$1"` 
    do
        ping -c 3 $i;
        echo "finish pinging host $i"
    done
fi
  • 也没有argv变量。如果要访问命令行参数,则必须使用$1$2,...
  • 下一个点是$#argv,评估为$#(命令行参数的数量)和argv。这看起来很像perl。
  • 此外,使用test ...[ ... ]进行测试,而非( ... )
  • 最后,您应该至少将您的命令行参数括在双引号"$1"中。如果没有,并且没有命令行参数,则可以使用例如

    test ! -f
    

    而不是

    test ! -f ""
    

    这使得测试失败并继续进行第二次测试,而不是回应正确的消息。

答案 2 :(得分:0)

#!/usr/local/bin/bash -x

if [ ! -f "${1}" ]
    then 
    echo "Argument must be a text file."
else
    while-loop-script "${1}"
fi

我已经打破了这个,因为我个人认为将一个功能嵌入另一个功能中是非常糟糕的形式;或者如实地甚至在同一个文件中有多个功能。我也不关心文件大小;我有几个长度为300-500字节的脚本。我正在学习FORTH;在这种意义上的分形主义是一种美德。

# while-loop-script

while read line
    do
    IFS="@"
    ping -c 3 "${line}"
    IFS=" "        
done < "${1}"

不要使用cat来将单个文件行提供给脚本;它总是会失败,bash会尝试将输出作为文字命令执行。我认为sed打印会起作用,而且经常会这样,但由于某种原因,它经常用空格代替换行符,这也非常烦人。

将线路提供给我所知道的脚本(这将保留所有空间和格式)的唯一绝对防弹方法是使用while-read循环,而不是替换cat或sed循环,如上所述。< / p>

为了确保保留空格,您需要做的其他事情是将内部字段分隔符(IFS)设置为您知道文件不包含的内容,然后将其重置为空白区域循环的结束。