为什么grep“-c”有0个计数退出程序,状态代码为-1

时间:2016-12-10 18:39:04

标签: bash count grep

为什么当grep -c返回0时,脚本会以'-1'退出代码失败。只有在设置set -o errexit时才会发生这种情况。

复制/粘贴bash shell

cat <<'EOT' > /tmp/foo.sh
#!/usr/bin/env bash

function bash_traceback() {
  local lasterr="$?"
  set +o xtrace
  local code="-1"
  local bash_command=${BASH_COMMAND}
  echo "Error in ${BASH_SOURCE[1]}:${BASH_LINENO[0]} ('$bash_command' exited with status $lasterr)"
  if [ ${#FUNCNAME[@]} -gt 2 ]; then
    # Print out the stack trace described by $function_stack
    echo "Traceback of ${BASH_SOURCE[1]} (most recent call last):"
    for ((i=0; i < ${#FUNCNAME[@]} - 1; i++)); do
    local funcname="${FUNCNAME[$i]}"
    [ "$i" -eq "0" ] && funcname=$bash_command
    echo -e "  $i: ${BASH_SOURCE[$i+1]}:${BASH_LINENO[$i]}\t$funcname"
    done
  fi
  echo "Exiting with status ${code}"
  exit "${code}"
}

test_redirecting_of_stdout_stderr() {

    # Exit program when error found
    set -o errexit

    # Exit program when undefined variable is being used
    set -o nounset

    local up_count
    up_count=$(ls | grep -c NOTHING_MATCHED)
    echo "up_count: $up_count"
}

# provide an error handler whenever a command exits nonzero
trap 'bash_traceback' ERR

set -o errtrace

test_redirecting_of_stdout_stderr

EOT

bash /tmp/foo.sh

输出

debian:~/my-mediawiki-docker$ bash /tmp/foo.sh
Error in /tmp/foo.sh:31 ('up_count=$(ls | grep -c NOTHING_MATCHED)' exited with status 255)
Traceback of /tmp/foo.sh (most recent call last):
  0: /tmp/foo.sh:31     up_count=$(ls | grep -c NOTHING_MATCHED)
  1: /tmp/foo.sh:40     test_redirecting_of_stdout_stderr
Exiting with status -1
debian:~/my-mediawiki-docker$

2 个答案:

答案 0 :(得分:4)

grep报告“失败”,如果找不到任何匹配的行。这是man grep

EXIT STATUS
       The exit status is 0 if selected lines are found, and 1 if not found. 

如果要在errexit期间允许命令以非零退出而不终止脚本,请使用|| true

up_count=$(ls | grep -c NOTHING_MATCHED) || true

答案 1 :(得分:2)

设置此选项假定命令的任何非零退出状态都是致命错误。 grep不是这种情况,它仅使用非零退出状态来指示匹配失败。这允许您编写像

这样的代码
if grep "$pattern" file.txt; then
    echo "Found a match"
else
    echo "Found no match"
fi

errexit特别忽略了if条件中使用的命令的退出状态,如上所述,但无法知道是否有像

这样的行
up_count=$(ls | grep -c NOTHING_MATCHED)

是&#34;允许&#34;具有非零退出状态。解决方法是使用

保护此类命令
# As an aside, see http://mywiki.wooledge.org/ParsingLs
up_count=$(ls | grep -c NOTHING_MATCHED) || :

一般来说,做自己的错误检查比依赖errexit更好;有关详细信息,请参阅http://mywiki.wooledge.org/BashFAQ/105