如何在Bash中的条件上进行管道传输

时间:2019-07-03 12:45:38

标签: bash scripting pipe

问题太复杂了,但是考虑到Bash中的一行条件,是否有一种将命令传递到另一个命令的方法?

基本上我目前有这个

if [ "$check" -eq 1 ]; then
    echo -n "foo" | xclip -selection clipboard
else
    echo -n "foo"
fi

我想知道Bash中是否有将其转换为以下形式的东西:

echo -n "foo" && [ "$check" -eq 1 ] | xclip -selection clipboard

如果$ check == 1,则“ foo”将通过管道传递到剪贴板,否则内容将输出到stdout,并且管道永远不会激活,并且什么也不会写入剪贴板。我希望这是一种单线方式,在此只调用一次echo。

4 个答案:

答案 0 :(得分:3)

$ check=0
$ echo "foo" | { if (( check == 1 )); then cat -n; else cat -; fi; }
foo

$ check=1
$ echo "foo" | { if (( check == 1 )); then cat -n; else cat -; fi; }
     1  foo

答案 1 :(得分:0)

距离您不远。

您可以将echo的输出通过管道传递到子shell

echo -n "foo" | ([[ "$check" -eq 1 ]] && xclip -selection clipboard || cat - )

在此代码中,您的echo将根据条件由xclipcat用作输入。

编辑:

如果您还希望命令在xclip失败时失败,则可以执行以下操作:

echo -n "foo" | ( ( [[ "$check" -ne 1 ]] && cat - ) || ( [[ "$check" -eq 1 ]] && xclip -selection clipboard ) )

但是这种方式可能比多行代码的可读性差。

只有一个echo的多行解决方案可以是:

# Create temporary pipe file
PIPE=$(mktemp -u)
mkfifo $PIPE
# Open pipe handles
# 6 can be replaced by any other non-opened fd identifier
exec 6<>$PIPE
# Remove file from disk
rm $PIPE
echo -n "foo" >&6
if [[ "$check" -eq 1 ]]; then
    xclip -selection clipboard <&6
else
    cat - <&6
fi
# Close file handles
exec 6<&- 6>&-

答案 2 :(得分:0)

对于您的可选命令(使用大写字母的示例)使用特殊的var(也许是check,我将使用cmd):

# default
cmd='cat -'
echo "foo" | $cmd
# output: foo
cmd='tr [:lower:] [:upper:]'
echo "foo" | $cmd
# output FOO

当您希望此结构的值更改为check时,可以使用以下函数:

xcmd() {
   sed '/0/ s/.*/cat -/; /1/ s/.*/tr [:lower:] [:upper:]/' <<< "${check-0}"
}

或使用xclip

xcmd() {
   sed '/0/ s/.*/cat -/; /1/ s/.*/xclip -selection clipboard/' <<< "${check-0}"
}

现在:

check=0
echo "foo" | $(xcmd)
# output: foo
check=1
echo "foo" | $(xcmd)
# output: FOO or the xclip pipe

答案 3 :(得分:0)

在某些情况下,例如,如果library(dplyr) dt %>% mutate(Iteration = group_indices(,, Group, Credit_ID)) 被多次检查,则条件定义的函数可能更合适。这也假设check的值在使用check之间不会改变。

receiver