在unix shell中循环时,exit语句不会中断

时间:2013-07-23 12:46:03

标签: shell unix while-loop

每个状态中的exit语句检查if语句是否不会破坏while循环并真正退出脚本。我可以做些什么来打破循环并退出$ STATUS代码?

编辑:我已经更新了我的代码但它仍然无法运行。状态检查if语句是否成功打破了循环,但是当我尝试评估$ EXIT_STATUS时,它总是为null,可能与范围有关。我在这里错过了什么?

  if [ $RESTART -le $STEP ]; then
  . tell_step

  while read XML_INPUT; do

    XML_GDG=`get_full_name $GDG_NAME P`

    cp $XML_INPUT $XML_GDG


    STATUS=$?
    EXIT_STATUS=$STATUS
    if [ $STATUS -ne 0 ]; then
      break
    fi

    add_one_gen $XML_GDG

    STATUS=$?
    EXIT_STATUS=$STATUS
    if [ $STATUS -ne 0 ]; then
      break
    fi

  done < $XML_STAGE_LIST

  echo $EXIT_STATUS
  if [ $EXIT_STATUS -ne 0 ]; then
    exit $EXIT_STATUS
  fi

fi

4 个答案:

答案 0 :(得分:2)

不太明白为什么你的脚本在退出时不会退出,因为下一个脚本没有问题:

while read name; do
    echo "checking: $name"
    grep $name /etc/passwd >/dev/null 2>&1
    STATUS=$?
    if [ $STATUS -ne 0 ]; then
        echo "grep failed for $name rc-$STATUS"
        exit $STATUS
    fi
done <<EOF
root
bullshit
daemon
EOF

运行它,产生:

$ bash testscript.sh ; echo "exited with: $?"
grep failed for bullshit rc-1
exited with: 1

如您所见,脚本立即退出并且不检查“守护程序”。

无论如何,当您使用bash functions时,它可能更具可读性:

dostep1() {
    grep "$1:" /etc/passwd >/dev/null 2>&1
    return $?
}

dostep2() {
    grep "$1:" /some/nonexistent/file >/dev/null 2>&1
    return $?
}

err() {
    retval=$1; shift;
    echo "$@" >&2 ; return $retval
}

while read name
do
    echo =checking $name=
    dostep1 $name || err $? "Step 1 failed" || exit $?
    dostep2 $name || err $? "Step 2 failed" || exit $?
done

运行时:

echo 'root
> bullshit' | bash testexit.sh; echo "status: $?"
=checking root=
Step 2 failed
status: 2

所以,step1没问题并退出step2(不存在文件) - grep退出状态2,以及何时

echo 'bullshit
bin' | bash testexit.sh; echo "status: $?"
=checking bullshit=
Step 1 failed
status: 1

立即退出step1(废话不在/ etc / passwd中) - grep退出状态1

答案 1 :(得分:2)

我遇到了同样的问题:当进入while循环时,脚本在退出时没有退出。相反,它应该像“休息”那样工作。

我找到了2个解决方案:

a)在while循环之后检查while循环的返回码然后退出:

somecommand | while something; do
    ...
done
# pass the exit code from the while loop
if [ $? != 0 ]
then
    # this really exits
    exit $?
fi

b)将bash脚本设置为在出现任何错误时退出。将其粘贴到脚本的开头:

set -e

答案 2 :(得分:0)

您需要从循环中break,然后从脚本中exit。您可以使用在出错时设置的变量来测试是否需要exit并出现错误情况。

答案 3 :(得分:0)

流水线时遇到了类似的问题。我的猜测是在piplining时启动一个单独的shell。希望它能帮助遇到问题的其他人。

从jm666上面的帖子中,这不会打印'我在这里!':

while read name; do
   echo "checking: $name"
   grep $name /etc/passwd >/dev/null 2>&1
   STATUS=$?
   if [ $STATUS -ne 0 ]; then
      echo "grep failed for $name rc-$STATUS"
      exit $STATUS
   fi
done <<EOF
root
yayablah
daemon
EOF

echo "Here I am!"

但是,将名称传递给while循环的以下内容确实如此。它也将以代码0退出。设置变量和break ing似乎也不起作用(如果它是另一个shell则有意义)。需要使用另一种方法来传达错误或首先避免这种情况。

cat <<EOF |
root
yayablah
daemon
EOF
while read name; do
   echo "checking: $name"
   grep $name /etc/passwd >/dev/null 2>&1
   STATUS=$?
   if [ $STATUS -ne 0 ]; then
      echo "grep failed for $name rc-$STATUS"
      exit $STATUS
   fi
done

echo "Here I am!"