是否可以在不使用cat的情况下有条件地“消失”外壳程序,使其成为管道? [英] Can I make a shell function in as a pipeline conditionally "disappear", without using cat?
问题描述
我有一个bash脚本,可以从一系列命令中生成一些文本。基于命令行选项,我想对输出进行一些验证。举一个人为的例子...
CHECK_OUTPUT = $ 1
...
check_output()
{
,如果[[[ $ CHECK_OUTPUT != --check; ]];然后
#不检查输出。传递并返回。
cat
return 0
fi
#在读行时检查fs根
中是否存在每行;如果[[! -e / $ line; ]];然后
echo错误:/ $ line不存在
返回1
fi
echo $ line
完成
返回0
}
ls / usr | grep‘^ b’| check_output
更好的示例: https://stackoverflow.com/a/52539364/1888983
这真的很有用,尤其是当我有多个可以通过的功能时。是的,我可以有条件地移动CHECK_OUTPUT并创建带有或不带有check_output的管道,但是我需要为每种组合写行以获得更多功能。如果有更好的方法可以动态构建管道,我想知道。
问题是猫的无用使用。是否可以避免这种情况,并使 check_output
像根本不在管道中一样?
是的,您可以执行此操作-通过将函数设置为有条件地注入管道元素的包装器,而不是成为无条件的管道元素本身。例如:
maybe_checked(){
if [[$ CHECK_OUTPUT!= --check; ]];然后
" $ @" #只是将参数作为命令运行,就好像我们不在这里
否则
#在进程替换中运行参数,从相同的标准输出中读取。
#...对原始代码进行了一些更改:
#IFS =停止删除前导或尾随空格
#read -r防止反斜杠被处理
本地行#避免在IFS = read -r行时修改函数
之外的$ line;做
[[-e / $ line; ]] || {echo错误:/ $ line不存在 >& 2;返回1; }
printf’%s\n’ $ line #参见https://unix.stackexchange.com/questions/65803
完成< <( $ @)
fi
}
ls / usr | may_checked grep'^ b'
上面代码的注意事项:如果 也就是说,这也是一个用例,其中使用 采用约翰·库格曼(John Kugelman)关于链接问题的答案中的示例: I have a bash script that produces some text from a pipe of commands. Based on a command line option I want to do some validation on the output. For a contrived example... [EDIT] better example: https://stackoverflow.com/a/52539364/1888983 This is really useful, particularly if I have multiple functions that can becomes passthroughs. Yes, I could move the CHECK_OUTPUT conditional and create a pipe with or without check_output but I'd need to write lines for each combination for more functions. If there are better ways to dynamically build a pipe I'd like to know. The problem is the "useless use of cat". Can this be avoided and make Yes, you can do this -- by making your function a wrapper that conditionally injects a pipeline element, instead of being an unconditional pipeline element itself. For example: Caveat of the above code: if the That said, this is also a use case wherein using Adopting the examples from John Kugelman's answers on the linked question:
这篇关于是否可以在不使用cat的情况下有条件地“消失”外壳程序,使其成为管道?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! pipefail $ c设置了$ c>选项,您将需要检查流程替换的退出状态,以与行为完全相同。在bash 4.3版或更高版本(IIRC)中,
$?
通过进程替换进行修改,以具有相关的PID,可以
cat
是可以接受的,并且我是说这是UUOC人群的持卡会员。 :)
maybe_sort(){
if((sort));然后
" $ @" |对
排序,否则
$ @
fi
}
may_limit(){
if [[-n $ limit]];然后
" $ @" |头-n $ limit
否则
$ @
fi
}
printf’%s\n’ $ {haikus [@]} | may_limit mayn_sort sed -e s / ^ [\t] * //’
CHECK_OUTPUT=$1
...
check_output()
{
if [[ "$CHECK_OUTPUT" != "--check" ]]; then
# Don't check the output. Passthrough and return.
cat
return 0
fi
# Check each line exists in the fs root
while read line; do
if [[ ! -e "/$line" ]]; then
echo "Error: /$line does not exist"
return 1
fi
echo "$line"
done
return 0
}
ls /usr | grep '^b' | check_output
check_output
like it wasn't in the pipe at all?maybe_checked() {
if [[ $CHECK_OUTPUT != "--check" ]]; then
"$@" # just run our arguments as a command, as if we weren't here
else
# run our arguments in a process substitution, reading from stdout of same.
# ...some changes from the original code:
# IFS= stops leading or trailing whitespace from being stripped
# read -r prevents backslashes from being processed
local line # avoid modifying $line outside our function
while IFS= read -r line; do
[[ -e "/$line" ]] || { echo "Error: /$line does not exist" >&2; return 1; }
printf '%s\n' "$line" # see https://unix.stackexchange.com/questions/65803
done < <("$@")
fi
}
ls /usr | maybe_checked grep '^b'
pipefail
option is set, you'll want to check the exit status of the process substitution to have complete parity with the behavior that would otherwise be the case. In bash version 4.3 or later (IIRC), $?
is modified by process substitutions to have the relevant PID, which can be wait
ed for to retrieve exit status.cat
is acceptable, and I'm saying this as a card-carying member of the UUOC crowd. :)
maybe_sort() {
if (( sort )); then
"$@" | sort
else
"$@"
fi
}
maybe_limit() {
if [[ -n $limit ]]; then
"$@" | head -n "$limit"
else
"$@"
fi
}
printf '%s\n' "${haikus[@]}" | maybe_limit maybe_sort sed -e 's/^[ \t]*//'