Bash 如何在不循环的情况下显示连续转换管道中每个步骤的结果?

Bash 如何在不循环的情况下显示连续转换管道中每个步骤的结果?,bash,pipe,Bash,Pipe,考虑下面的示例Bash one liner,其中字母“h”、“e”和“o”从单词“hello”中依次删除。只剩下两个“l”字母 $ echo "hello" | tr -d h | tr -d e | tr -d o ll 我试图找到一种方法,在一个行中显示每个命令的输出到屏幕,这样其他运行它的人可以看到发生了什么。继续上面的例子,我希望输出如下 $ echo "hello" | tr -d h | tr -d e | tr -d o hello ello llo ll 这可能吗?根据上述一

考虑下面的示例Bash one liner,其中字母“h”、“e”和“o”从单词“hello”中依次删除。只剩下两个“l”字母

$ echo "hello" | tr -d h | tr -d e | tr -d o
ll
我试图找到一种方法,在一个行中显示每个命令的输出到屏幕,这样其他运行它的人可以看到发生了什么。继续上面的例子,我希望输出如下

$ echo "hello" | tr -d h | tr -d e | tr -d o
hello
ello
llo
ll
这可能吗?根据上述一个班轮的操作,我们正在使用垂直管道将输出从一个命令传送到另一个命令。因此,我假设我必须从管道中断以打印到标准输出,这将中断我编写的“命令链”。或者这里可以使用
tee
,但我似乎无法达到欲望效果更新
tee
无法工作,因为它的输出仍在管道的边界内,duh


非常感谢。

您可以使用
tee-
,因为
-
代表控制台:

echo "hello" | tee - | tr -d h | tee - | tr -d e | tee - | tr -d o
希望有帮助

编辑

此解决方案将不起作用,因为通过
stdout
生成输出的所有命令都会阻止并重用
stdout


我不会删除答案,因为它清楚地表明它不能解决问题,但也表明这种解决方案是无效的,以及原因。如果有人发现自己处于相同的情况,将发现此信息,这将非常有用。

您可以使用
tee-
,因为
-
表示控制台:

echo "hello" | tee - | tr -d h | tee - | tr -d e | tee - | tr -d o
希望有帮助

编辑

此解决方案将不起作用,因为通过
stdout
生成输出的所有命令都会阻止并重用
stdout


我不会删除答案,因为它清楚地表明它不能解决问题,但也表明这种解决方案是无效的,以及原因。如果有人发现自己处于同样的情况,他会发现这些信息,这将是有用的。

但这将起作用:

tmp=`echo "hello"`; echo $tmp; tmp=`echo $tmp | tr -d h`; echo $tmp; tmp=`echo $tmp | tr -d e`; echo $tmp; echo $C | tr -d o
虽然很难看,但它很管用。该解决方案创建变量来存储每个过程,然后显示所有过程:

tmp=`echo "hello"`
echo $tmp
tmp=`echo $tmp | tr -d h`
echo $tmp
tmp=`echo $tmp | tr -d e`
echo $tmp
echo $C | tr -d o

我找不到更好的解决方案。

但这将起作用:

tmp=`echo "hello"`; echo $tmp; tmp=`echo $tmp | tr -d h`; echo $tmp; tmp=`echo $tmp | tr -d e`; echo $tmp; echo $C | tr -d o
虽然很难看,但它很管用。该解决方案创建变量来存储每个过程,然后显示所有过程:

tmp=`echo "hello"`
echo $tmp
tmp=`echo $tmp | tr -d h`
echo $tmp
tmp=`echo $tmp | tr -d e`
echo $tmp
echo $C | tr -d o

我找不到更好的解决方案。

您可以使用fifo(或常规文件)进行监听:

mkfifo tmp.fifo
tail -f tmp.fifo
然后在单独的shell上运行命令:

echo hello | tee -a tmp.fifo | tr -d e | tee -a tmp.fifo | tr -d o

您可以使用fifo(或常规文件)进行监听:

mkfifo tmp.fifo
tail -f tmp.fifo
然后在单独的shell上运行命令:

echo hello | tee -a tmp.fifo | tr -d e | tee -a tmp.fifo | tr -d o

使用一个小循环:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done
这个。仅用于简短的解决方案。在更仔细地阅读了这个问题后,我测试并发现,它在管道链中也起作用:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done | less 
# pure bash buildins, see chepner's comment
w="hello" ; for c in h e o .; do echo $w; w=${w/$c}; done

使用一个小循环:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done
这个。仅用于简短的解决方案。在更仔细地阅读了这个问题后,我测试并发现,它在管道链中也起作用:

w="hello" ; for c in h e o .; do echo $w; w=$(echo $w | tr -d $c); done | less 
# pure bash buildins, see chepner's comment
w="hello" ; for c in h e o .; do echo $w; w=${w/$c}; done

这仅适用于终端:

echo hello  | tee /dev/tty |
    tr -d h | tee /dev/tty |
    tr -d e | tee /dev/tty |
    tr -d o
echo hello  | tee /proc/$$/fd/1 |
    tr -d h | tee /proc/$$/fd/1 |
    tr -d e | tee /proc/$$/fd/1 |
    tr -d o

/dev/tty
设备将输出重定向到当前终端,无论正常输出到哪里。

这仅适用于终端:

echo hello  | tee /dev/tty |
    tr -d h | tee /dev/tty |
    tr -d e | tee /dev/tty |
    tr -d o
echo hello  | tee /proc/$$/fd/1 |
    tr -d h | tee /proc/$$/fd/1 |
    tr -d e | tee /proc/$$/fd/1 |
    tr -d o

/dev/tty
设备将输出重定向到当前终端,无论正常输出到哪里。

您可以
将输出直接发送到终端:

echo hello  | tee /dev/tty |
    tr -d h | tee /dev/tty |
    tr -d e | tee /dev/tty |
    tr -d o
echo hello  | tee /proc/$$/fd/1 |
    tr -d h | tee /proc/$$/fd/1 |
    tr -d e | tee /proc/$$/fd/1 |
    tr -d o

$
是外壳的PID。

您可以
将输出直接发送到终端:

echo hello  | tee /dev/tty |
    tr -d h | tee /dev/tty |
    tr -d e | tee /dev/tty |
    tr -d o
echo hello  | tee /proc/$$/fd/1 |
    tr -d h | tee /proc/$$/fd/1 |
    tr -d e | tee /proc/$$/fd/1 |
    tr -d o

$
是shell的PID。

在我看来,如果这是现实世界中的问题,而不是如何在bash中实现,那么您可以尝试一个简单的perl oneliner,而不是bash疯狂地启动X tr和Y tee进程:

echo hello | perl -nale 'foreach $i (qw(h e o)) {@F=map{s/$i//g;print $_;$_}@F}'
将打印:

ello
llo
ll
或者如果你真的想要bash(正如@chepner建议的那样)

读取w时
;o中c的do;dow=${w/$c};echo$w;完成;完成
IMO,如果这是现实世界中的问题,而不是在bash中如何实现,那么您可以尝试一个简单的perl oneliner,而不是bash疯狂地启动X tr和Y tee进程:

echo hello | perl -nale 'foreach $i (qw(h e o)) {@F=map{s/$i//g;print $_;$_}@F}'
将打印:

ello
llo
ll
或者如果你真的想要bash(正如@chepner建议的那样)

读取w时
;o中c的do;dow=${w/$c};echo$w;完成;完成
还有一个房间吗

echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) )

输出为:

hello
ubuntu@ubuntu:~$ ello
llo
ll
hello
ello
llo
ll
通过
ubuntu@ubuntu:~$

cat <(echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) ) )
还有一个房间吗

echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) )

输出为:

hello
ubuntu@ubuntu:~$ ello
llo
ll
hello
ello
llo
ll
通过
ubuntu@ubuntu:~$

cat <(echo "hello" | tee >(tr -d h | tee >(tr -d e | tee >(tr -d o) ) ) )

奇怪的是,这并不像预期的那样有效<代码>回显“hello”| tee-| tr-d h | tr-d e | tr-d o
正在输出“ll ll”,因此它是最终输出,但又回到了接近开始的位置?!在
tee
:)中使用
-
仍然+1奇怪!我马上看一看,试一下变化。让我惊讶的是。。。是的,它不会工作,直到整条线完成,标准输出才会被阻塞,所有的
tee
s都被链接!!!这行不通,这个答案解决不了你的问题。很抱歉,这无法工作,因为原件和副本都会转到标准输出(fd 1),因此会被后续命令转换。奇怪的是,这并没有按预期工作<代码>回显“hello”| tee-| tr-d h | tr-d e | tr-d o
正在输出“ll ll”,因此它是最终输出,但又回到了接近开始的位置?!在
tee
:)中使用
-
仍然+1奇怪!我马上看一看,试一下变化。让我惊讶的是。。。是的,它不会工作,直到整条线完成,标准输出才会被阻塞,所有的
tee
s都被链接!!!这行不通,这个答案解决不了你的问题。对不起,这不起作用,因为原件和复印件都转到标准输出(fd 1),因此是传输的