【问题标题】:Why is ksh script exit code 1 after while loop?为什么在while循环之后ksh脚本退出代码1?
【发布时间】:2016-09-01 21:38:10
【问题描述】:

我通常编写 Perl 脚本,但我正在修改一个遗留的 KSH 脚本(所以我不必重写整个东西),它设置一个等于数组中项目数的计数器,然后执行一个 while 循环这会减少计数器,因此我可以按特定顺序为变量赋值。但是,当我这样做时,退出代码是 1,而不是 0。

这是代码():

set -A MY_ARRAY item1 item2
i=${#MY_ARRAY[@]}
while [[ ${i} -gt 0 ]]; do
    (( j = ${#MY_ARRAY[@]} ))
    if [[ ${i} -ge ${j} ]]; then
        x="first value"
    else
        x="second value"
    fi

    (( i = i - 1 ))
done

当上面的代码运行时,退出代码是1。我想这是因为最后一次尝试迭代期间的条件是[[ 0 -gt 0 ]],并且因为这个测试是假的,所以返回值在$?是 1。但是,如果我写以下代码,则退出代码为 0:

i=0
if [[ ${i} -gt 0 ]]; then
    x="first value"
else
    x="second value"
fi

如果问题是因为最后一次迭代的条件为假,那么最好的处理方法是什么?是否会在“完成”行之后立即设置返回值,如下所示:

done || return 0

done || exit 0

或者是在“完成”行之后的后续行中设置返回/退出值,如下所示:

done
return 0

done
exit 0

否则,我错过了什么/做错了什么?

谢谢。

【问题讨论】:

  • 一组很好的假设/问题。您可以通过将export PS3='$LINENO >' ; set -vx 添加为脚本的第二行来自己测试这些假设。您将在执行之前看到每组命令(例如整个 while 循环),然后以 +(和 3 > (LINENO))开头的行显示每行执行时变量的实际值。有时很难说出什么是什么,您可能必须增强调试输出,例如print -- -u2 "#DBG: i=$i \tj=$j ..."。祝你好运。

标签: ksh aix


【解决方案1】:

while 循环将返回循环中最后一条命令的退出代码(当循环至少一次时):

j=1
while [ $j -gt 0 ]; do
   ((j--))
   true
done
echo "$? after true"
j=1
while [ $j -gt 0 ]; do
   ((j--))
   false
done
echo "$? after false"

在您的情况下,请尝试以下命令查看返回值:

j=5; ((j = j - 1 )); echo "$j returns $?"
j=1; ((j = j - 1 )); echo "$j returns $?"

我认为您想要的退出/返回代码不是循环的值。 考虑:

function count_highvalues {
   retval=0
   while [[ ${i} -gt 0 ]]; do
      (( j = ${#MY_ARRAY[@]} ))
      if [[ ${i} -ge ${j} ]]; then
         ((retval++))
      fi
      ((i--))
   done
   return ${retval}
}

让 while-do-done 做你要求的事情,然后返回/退出你想要的。
尝试将返回/退出值设为 0,使 van 被认为是 OK/true。

有时您想要退出,有时您想要返回。退出将完成当前脚本,并仅返回当前函数。
试试下面的代码:你不会看到“After f2”,因为脚本已经退出了。

function f1 {
   return 1
}

function f2 {
   exit 2
}

echo "Before f1"
f1
echo "After f1: $?"
echo "Before f2"
f2
echo "After f2: $?"

【讨论】:

  • 你知道为什么我在运行脚本后echo $? 得到 1 吗?根据您的评论,我认为您建议我将代码放入具有指定返回值的函数中。我认为这对我有用,虽然根据你所说的,我真的只需要在我的 while 循环之后放置一个 exit 0 (因为这是我脚本中代码的结尾)。我只是不清楚为什么会发生 while 循环或测试条件,或者任何可能导致 1 退出代码的原因。
  • 你不需要函数,可以使用exit。 return 在函数中是有效的,所以为了说明exit和return的区别,我举了一个函数作为例子。
  • 编辑了while的退出值问题。
  • 我试过j=5; ((j = j - 1)); echo "$j returns $?"j=1; ((j = j - 1)); echo "$j returns $?"。第一个语句的输出是“4 返回 0”,第二个语句的输出是“0 返回 1”。所以,我的问题是,为什么$? 退出代码在$j = 0 时在第二个语句中返回1?当变量的计算结果等于0 时,$? 是否总是等于1?但是,我在这里找到了答案:unix.stackexchange.com/a/63306.
猜你喜欢
  • 1970-01-01
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 2022-01-22
  • 1970-01-01
  • 2013-08-04
相关资源
最近更新 更多