假设我有一个bash命令mycommand
。有时它会输出一些内容,但总是返回退出码0。我需要使用管道来将退出码修复为对于空输出为0,对于非空输出为其他值。
mycommand | ???
我不关心if语句或自定义命令。我只想有一个像grep一样简单的命令,带一些参数来检查其输入是否为空,并返回退出代码。最好能够在输入不为空时打印输出,但这不是必需的。
假设我有一个bash命令mycommand
。有时它会输出一些内容,但总是返回退出码0。我需要使用管道来将退出码修复为对于空输出为0,对于非空输出为其他值。
mycommand | ???
yourcommand | grep -qv .
! ( yourcommand | grep -q ^ )
yourcommand | grep -q ^ || echo no output.
echo
),则应该测试 ^
而不是 .
。例如:echo | grep -q ^ || echo no
与 echo | grep -q . || echo no
。 - clt60grep -v ^
,尽管这样不会显示任何内容。你对避免使用 !
的执念似乎有些过度了。 - tripleeebash -c '! yourcommand | grep ^'
命令行吧? - tripleeewc
支持换行符和 \0
:
$ printf '\n' | wc -c
1
$ printf '\0' | wc -c
1
因此,以下是一个简单的符合POSIX标准的方法:
mycommand | [ $(wc -c) -eq 0 ]
示例:
$ printf '' | [ $(wc -c) -eq 0 ]; echo $?
0
$ printf 'yay' | [ $(wc -c) -eq 0 ]; echo $?
1
$ printf '\n' | [ $(wc -c) -eq 0 ]; echo $?
1
$ printf '\0' | [ $(wc -c) -eq 0 ]; echo $?
1
不起作用的替代方案:
grep .
doesn't match a solitary newline or \0
as a character:
$ printf '\n' | grep .; echo $?
1
$ printf '\0' | grep .; echo $?
1
You can't save \0
in a variable:
$ a=$'foo\0bar\0baz'
$ printf '%s' "$a" | wc -c
3
Command substitutions remove trailing newlines:
$ test -z "$(printf '\n')"; echo $?
0
echo
命令会返回一个空行!请尝试使用 echo -n
或 true
命令! - F. Hauri - Give Up GitHub\0
。 - l0b0^
,grep
将会工作... @l0b0 - clt60看起来最清晰的方法是
mycommand | ( ! grep ^ )
! mycommand | grep ^
。 - Sergii Shymko由于答案众多,因此使用^
来使用grep
。
pp() { printf "================\nfor: %s\n" "$@"; }
pp "no input"
printf '' | grep -q ^ ; echo $?
printf '' | grep -q ^ && echo got input || echo no input
pp 'null character'
printf '\0' | grep -q ^ ; echo $?
printf '\0' | grep -q ^ && echo got input || echo no input
pp '\n'
printf '\n' | grep -q ^ ; echo $?
printf '\n' | grep -q ^ && echo got input || echo no input
pp 'some'
printf 'some' | grep -q ^ ; echo $?
printf 'some' | grep -q ^ && echo got input || echo no input
pp 'some\n'
printf 'some\n' | grep -q ^ ; echo $?
printf 'some' | grep -q ^ && echo got input || echo no input
输出
================
for: no input
1
no input
================
for: null character
0
got input
================
for: \n
0
got input
================
for: some
0
got input
================
for: some\n
0
got input
pp() { local sline;eval "printf -v sline '%.0s-' {1..$COLUMNS}";printf "%s\nFor: <%s>:\n" $sline "$1";printf "$1" | grep ^ ; echo "Returned code: $?"; }
- F. Hauri - Give Up GitHubpp
而不带任何参数,例如。然后printf... ${1:-no output}
...但您已经知道这些了。 - F. Hauri - Give Up GitHubread -v COLUMNS < <(tput cols)
,然后对于固定的输入,eval
不是“邪恶”的!使用这种方式使用 eval
没有问题。 - F. Hauri - Give Up GitHubt=$(mktemp -t myscript.XXXXXXXX) || exit
# Use a trap to clean up even if interrupted
trap 'rm -f "$t"' EXIT
trap 'exit' HUP TERM
cat >"$t"
if [ -s "$t" ]; then
: do stuff with "$t"
fi
这显然太复杂了,无法在命令行上随意使用,但有时你只需要编写一个脚本。
这个方法可以很好地推广到任何需要对所有输入执行多个命令的情况。
我还要顺便提一下xargs -r
,当然,这只有在你已经将输出管道传递给xargs
时才有意义。
!(mycommand | grep ^)
。 - enumag