【发布时间】:2021-05-27 18:36:47
【问题描述】:
如果标准输入为空,我想打破整个管道。我尝试将 xargs -r 和 tee 结合起来,这意味着如果 stdin 为空则不打印和写入,但它失败了
...| upstream commands | xargs -r tee output.txt | downstream commands | ...
感谢任何反馈。
【问题讨论】:
如果标准输入为空,我想打破整个管道。我尝试将 xargs -r 和 tee 结合起来,这意味着如果 stdin 为空则不打印和写入,但它失败了
...| upstream commands | xargs -r tee output.txt | downstream commands | ...
感谢任何反馈。
【问题讨论】:
您实际上无法有条件地终止 bash 管道。管道中的所有命令同时启动。但是,有一个工具可以帮助您创建 条件 管道。在moreutils 中,您可以找到工具ifne,当且仅当输入/dev/stdin 不为空时,该工具才会执行命令。所以你可以这样写:
$ command1 | ifne command2 | ifne command3 | ifne command4
这里所有命令ifne 和command1 都是同时启动的。只有当ifne通过/dev/stdin接收输入时,它才会启动其各自的commandx
【讨论】:
如果命令失败,管道会破裂。您可以在两者之间添加 grep 来实现这一点。一个例子:
$ echo ok | awk '{print $0,"1"}' | awk '{print $0,"2"}' | awk '{print $0,"3"}'
ok 1 2 3
现在添加 grep:
$ echo ok | grep -Ei '^.+$' | awk '{print $0,"1"}' | awk '{print $0,"2"}' | awk '{print $0,"3"}'
ok 1 2 3
并测试空回声:
$ echo | awk '{print $0,"1"}' | awk '{print $0,"2"}' | awk '{print $0,"3"}'
1 2 3
$ echo | grep -Ei '^.+$' | awk '{print $0,"1"}' | awk '{print $0,"2"}' | awk '{print $0,"3"}'
看起来这行得通,但行不通,确实很有趣,那么 obvy 管道不适合这里,试试这个方法:
#!/bin/bash
set -x
fun(){
data=$(echo "$1"); [[ $data ]] && data=$(awk '{print $0,1}' <<< "$data") || return 1; [[ $data ]] && data=$(awk '{print $0,2}' <<< "$data") || return 1; [[ $data ]] && data=$(awk '{print $0,3}' <<< "$data") || return 1; echo "$data"
}
fun ok
fun
测试:
$ ./test
+ fun ok
++ echo ok
+ data=ok
+ [[ -n ok ]]
++ awk '{print $0,1}'
+ data='ok 1'
+ [[ -n ok 1 ]]
++ awk '{print $0,2}'
+ data='ok 1 2'
+ [[ -n ok 1 2 ]]
++ awk '{print $0,3}'
+ data='ok 1 2 3'
+ echo 'ok 1 2 3'
ok 1 2 3
+ fun
++ echo ''
+ data=
+ [[ -n '' ]]
+ return 1
更易读的变体:
#!/bin/bash
set -x
fun(){
data=$(echo "$1")
[[ $data ]] && data=$(awk '{print $0,1}' <<< "$data") || return 1
[[ $data ]] && data=$(awk '{print $0,2}' <<< "$data") || return 1
[[ $data ]] && data=$(awk '{print $0,3}' <<< "$data") || return 1
echo "$data"
}
fun ok
fun
【讨论】: