所以我之前问了一个问题,为ping添加了一个前缀。 (我的最后一个问题)给我留下了以下一行:
ping 8.8.8.8 | while read line; do echo "$(date): $line"; done | grep time=
这很有效。我只有一个问题,我无法将其保存在文件中。我尝试了一下这样简单的重定向:
ping 8.8.8.8 | while read line; do echo "$(date): $line"; done | grep time= >> googleping
但没有任何内容保存在文件中......
然后我尝试了这个:
ping 8.8.8.8 | while read line; do echo "$(date): $line"; done | grep time= | tee -a googleping
用tee将其打印在屏幕上并将其保存在文件中......再次没有运气。
(但尝试过echo hello | tee -a googleping
并且效果很好......)
然后我尝试了另一个while循环:
ping 8.8.8.8 | while read line; do echo "$(date): $line"; done | grep time= | while read line; do echo $line; echo $line >> googleping; done
再没有运气......
那么一条线可以有多少管道和重定向?如果是这样的话,当我无法访问谷歌时,我仍然可以实现我的记录目标(我只是使用grep time=
测试它以获得附加输出并使用grep -v time=
来获取所有行无论错误如何,都没有时间在其中。)
所以要补充的是,最后我想在mac终端中进行,但我在ubuntu服务器和mac上尝试过,并且都不能使用上述任何方法。
我希望有人可以帮助我!
答案 0 :(得分:9)
answer by hek2mgl解释了您的特定问题与管道数无关。
但要回答你标题中的问题(“我可以使用多少管道有限制吗?”),是 opened file descriptors < / strong>,但在目前的系统中,它在实践中非常大(数千)。 AFAIU,POSIX保证小限制(可能只有20)。您的系统可能每个进程都有一个文件描述符限制,另一个文件描述符限制系统范围......
要设置或查询每个进程的文件描述符限制,您可以将setrlimit(2)和a@a:~$ rails -v
Rails 4.2.5
a@a:~$ ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]
a@a:~$ sudo mysql -v
[sudo] password for a:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 39
Server version: 5.5.46-0ubuntu0.14.04.2 (Ubuntu)
与getrlimit
(RLIMIT_NOFILE
内置ulimit
一起使用,或者在您的交互式shell中bash
内置limit
。您还可以在Linux上阅读zsh
(有关/proc/self/limits
伪文件的更多信息,请参阅proc(5))。在我的Linux Debian系统上,每个进程有65536个最大文件描述符。
IIRC,/proc/
给出了打开的文件描述符的最大数量。在我的系统上,现在是1632058。
当您达到文件描述符限制时,pipe(2)系统调用(例如,您的pipelines open(2)与/proc/sys/fs/file-max
的shell完成)将失败:
|
该过程正在使用太多文件描述符。
EMFILE
已打开文件总数的系统限制 达到。
disk quota也可能因pipe(7)多余而失败...
ENFILE
如果指定了EDQUOT
,则该文件不存在,并且 用户对文件系统的磁盘块或inode的配额有 已经筋疲力尽。
另见Advanced Linux Programming并阅读fflush(3);当用C编程时,你应该适当而明智地使用org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator。
答案 1 :(得分:2)
这与您使用的管道数量无关。由于输出缓冲,您不会立即看到tee的输出。当grep的输出转到管道而不是终端时,它会被块缓冲。如果你有足够的耐心,输出会在一段时间后出现(一旦缓冲区被刷新)。
此行为在libc中实现,除非程序显式处理它自己的缓冲。您可以使用stdbuf
命令来影响此行为:
ping 8.8.8.8 \
| while read line; do echo "$(date): $line"; done \
| stdbuf -o0 grep time= \
| tee -a googleping
我正在使用grep
调用stdbuf -o0
,它将grep的输出缓冲区大小缩小为零长度。或者,您可以使用-oL
生成行缓冲输出。
旁注:stdbuf
适用于您的示例。但是,如果您仔细阅读stdbuf
的手册页,您会注意到:
注意:如果COMMAND调整其标准流的缓冲('tee'确实如此 例如,然后它将覆盖由'std-更改的相应设置 BUF”。还有一些过滤器(如'dd'和'cat'等)不使用流 I / O,因此不受'stdbuf'设置的影响。
这就是我上面所说的。 stdbuf
仅适用于不能自行处理缓冲的程序。 tee
就是这样一个程序。这意味着如果您从发球台进一步管道,则无法使用stdbuf
。