如何将管道输入传递给别名中的第二个命令?

如何将管道输入传递给别名中的第二个命令?

我定义了一个别名,例如:

alias xyz='command1; command2'

我想将另一个命令 pqr 的输出通过管道传输到 command2,例如:

pqr | xyz -f -

是否可以?我怎样才能做到这一点?

答案1

使用别名通常是不是非交互式 shell 脚本的良好实践(BashFAQ/080)。您在 OP 中定义别名的方式,只有第一个命令从标准输入读取,因为;会终止您的标准输入超出第一个命令。

一种可能的方法是使用 进行命令分组{..},以便任何重定向都适用于组内的整个命令集。您仍然可以保留您的alias定义并执行

alias xyz='{ command1; command2; }'

在这种情况下,您comamnd1不必要地获得标准输入的副本。您可以通过执行以下操作来关闭它

alias xyz='{ command1 < /dev/null ; command2 - ; }'

或者使用函数来定义您的命令。

xyz() {
    command1; command2
}

如果您的 shell支持进程bash替换zsh,您只需定义command2接收 stdin 内容作为位置参数。将您的函数重新定义为

xyz() {
    command1
    command2 "$@"
}

然后调用你的命令 ( pqr) 作为

xyz < <(pqr)

上面的一个简单的演示,

zoo() { date; sed 's/foo/boo/' "$@"; }
zoo < <(echo food)                     #(or) zoo <<<"food"
Mon Nov 25 02:44:49 EST 2019
bood

答案2

我建议您尝试 xargs 方法,即:

alias xyz='command1; command2 | xargs pqr'

这相当于以输入参数pqr运行command2

答案3

command2将某些内容传递到命令列表的标准输入中

command1; command2

您必须确保command1不从标准输入读取。这可以通过将标准输入重定向到来/dev/null完成command1

command1 </dev/null; command2

这给你留下了别名

alias xyz='command1 </dev/null; command2`

你会的不是能够打电话给

pqr | xyz -f -

因为那相当于

pqr | command1 </dev/null; command2 -f -

这与以下相同

pqr | command1 </dev/null
command2 -f -

相反,定义xyz为 shell 函数:

xyz () {
    command1 </dev/null
    command2 "$@"
}

在这里,command2将获取函数的标准输入以及提供给函数的任何命令行参数。

您现在可以像在管道中一样使用它pqr | xyz -f -

如果(且仅当)-f -您传递给的参数command2是“从标准输入读取”(表示-标准输入),那么您可以代替-将进程替换传递给xyz,如果您的 shell 支持它:

xyz -f <(pqr)

使用上面的函数,这与执行相同

command1 </dev/null
command2 -f <(pqr)

相关内容