管道分配变量


19

为了简单起见,我想这样做:

echo cart | assign spo;
echo $spo  

输出:购物车

是否assign存在这样的应用程序?

我知道使用替代的所有方法。


您为什么要这样做而不做替代?
Thanatos

仅使用管道书写时,我喜欢波兰语的相反符号流程。我的编码速度更快,并且编码质量/速度并不是那么重要。此外,我当链接它是不是海拉容易注释掉链的部分和回声的电流输出而不是擦除蜱等
MageProspero

如果您担心调试的简便性,请考虑将backticks命令放在一系列单独的行上。A=$( some | command | here )与每个some |command |以及here在自己的行。
roaima

Answers:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

只要只输出echo一行,就可以工作(将不带换行符的输出存储到spo变量中)echo

您可以随时这样做:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

以下解决方案将在bash脚本中起作用,但在bash提示符下不起作用:

shopt -s lastpipe
echo cat | assign spo

要么:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

要在中存储whatever最多前NUL个字符的输出(bash变量无论如何都不能存储NUL字符)$spo

要么:

shopt -s lastpipe
whatever | readarray -t spo

将的输出存储whatever$spo 数组中(每个数组元素一行)。


1
IFS=与之间不应该有空格read
caesarsol 2015年

所有的人都欢呼不已。另外,由于最后一个管道在作业控制处于活动状态时不起作用,因此在命令行中还需要使用+ m(ermmm或-m)旁注集。
MageProspero 2015年

17

如果使用,则可以执行以下操作bash

echo cart | while read spo; do echo $spo; done

不幸的是,变量“ spo”不会在while-do-done循环之外存在。如果您可以在while循环中完成所需的工作,那将起作用。

实际上,您几乎可以完全按照您在ATT ksh(而不是pdksh或mksh)或神话般的zsh中所做的操作:

% echo cart | read spo
% echo $spo
cart

因此,另一种解决方案是使用ksh或zsh。


1
您可以在Korn Shell中使用协同处理(例如mksh):(echo cart |& while read -p spo; do echo $spo; done实际上更好用while IFS= read -p -r spo; do…
mirabilos 2014年

2

如果我正确理解了该问题,则希望将stdout传递给变量。至少那是我一直在寻找的东西,并最终到了这里。所以对于那些分享我命运的人:

spa=$(echo cart)

分配cart给变量$spa


2
这就是他们所谓的替代,OP希望避免。
德米特里·格里戈里耶夫

这对我很有用,我只需要将其分配给变量,我不在乎它如何到达那里!
克里斯·马里西奇

1

如果只想输出当前管道流,请使用cat

echo cart | cat 

如果要继续执行命令链,请尝试使用tee命令回显输出。

echo cart | tee /dev/tty | xargs ls

您可以使用别名来缩短命令。

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

您为什么要通过管道将输出传递到纯文本cat
roaima 2015年

1
@roaima某些命令认为它们在终端上运行,其行为与输出到管道的行为不同。特别是它们可能会将行截断为当前屏幕宽度。对于大多数命令,cat命令是多余的。
BillThor

好的,我现在明白了您要说明的内容。该echo | cat构造扔我。
roaima

1

这是我解决问题的方法。

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.