在 Linux 中,如果你/proc/<pid>/fd经常深入挖掘,你会看到如下输出:
lrwx------ 1 root root 64 Jul 30 15:14 0 -> /dev/null
lrwx------ 1 root root 64 Jul 30 15:14 1 -> /dev/null
l-wx------ 1 root root 64 Jul 30 15:14 10 -> pipe:[90222668]
lr-x------ 1 root root 64 Jul 30 15:14 11 -> pipe:[90222669]
l-wx------ 1 root root 64 Jul 30 15:14 13 -> pipe:[90225058]
lr-x------ 1 root root 64 Jul 30 15:14 14 -> pipe:[90225059]
Run Code Online (Sandbox Code Playgroud)
如何获取有关开放管道的更多信息,例如另一端是哪个进程?
我可以让 unzip 或任何类似的程序在标准输出上工作吗?情况是我正在下载一个 zip 文件,该文件应该可以即时解压缩。
怎么可能通过管道输出wget下载的文件?如果不是,我应该使用哪些替代方案?
我的一个常见做法是对某种类型的所有文件执行 grep,例如,找到所有包含“rumpus”一词的 HTML 文件。为此,我使用
find /path/to -name "*.html" | xargs grep -l "rumpus"
Run Code Online (Sandbox Code Playgroud)
有时,find会返回名称中带有空格的文件,例如my new file.html. 但是,当xargs将此传递给grep时,我收到以下错误:
grep: /path/to/bad/file/my: No such file or directory
grep: new: No such file or directory
grep: file.html: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我可以看到这里发生了什么:管道或xargs正在将空格视为文件之间的分隔符。但是,对于我的一生,我无法弄清楚如何防止这种行为。可以用find+完成xargs吗?还是我必须使用完全不同的命令?
我不清楚的最佳顺序是同时捕获什么STDERR,并STDOUT使用相同的文件tee。我知道如果我想通过管道传输到文件,我必须在重定向后映射文件句柄,即
find . >/tmp/output.txt 2>&1
Run Code Online (Sandbox Code Playgroud)
这指示外壳发送STDOUT到/tmp/output.txt然后发送STDERR到STDOUT(现在正在发送到/tmp/output.txt)。
尝试2>&1在重定向文件之前执行不会有预期的效果。
但是,当我想管道使用时,tee应该是:
find . |tee /tmp/output.txt 2>&1 # or
find . 2>&1 |tee /tmp/output.txt # ?
Run Code Online (Sandbox Code Playgroud) 如何在不通过管道传输标准输出流的情况下传输标准错误流?
我知道这个命令有效,但它也会写出标准。
Command 2>&1 | tee -a $LOG
Run Code Online (Sandbox Code Playgroud)
我如何得到标准错误?
注意:我想要的是将 stderr 流写入日志并将 stderr 和 stdout 写入控制台。
假设我有一个foo带有文件名参数的命令:foo myfile.txt. 令人讨厌的是,foo不从标准输入读取。我想将另一个命令的结果传递给它,而不是实际的文件(实际上,pv,它将捕获文件并输出进度表作为副作用)。
有没有办法做到这一点?我的技巧包中似乎没有任何东西可以做到。
(foo在这种情况下是一个 PHP 脚本,我相信它会按顺序处理文件)。
我正在使用 Ubuntu 和 Bash
编辑抱歉,问题描述有点不清楚,但这是我想要的答案:
pv longfile.txt | foo /dev/stdin
Run Code Online (Sandbox Code Playgroud)
现在我看到它非常明显。
有没有人理解处理时间、使用中间文件或使用管道时的巨大差异?我在新的 debian 挤压服务器上使用标准工具将 tiff 转换为 pdf。执行此操作的标准方法是先转换为 ps。
无管:
root@web5:~# time tiff2ps test.tif > test.ps
real 0m0.860s
user 0m0.744s
sys 0m0.112s
root@web5:~# time ps2pdf13 -sPAPERSIZE=a4 test.ps > test.pdf
real 0m0.667s
user 0m0.612s
sys 0m0.060s
Run Code Online (Sandbox Code Playgroud)
配管:
root@web5:~# time tiff2ps test.tif | ps2pdf13 -sPAPERSIZE=a4 - > test.pdf
real 1m6.098s
user 0m15.861s
sys 0m50.9
Run Code Online (Sandbox Code Playgroud)
在最后一条命令期间,gs 进程始终处于 100%。
更新:
这是 ps 生成的 strace 输出:
root@web5:~# strace tiff2ps test.tif > test.ps
execve("/usr/bin/tiff2ps", ["tiff2ps", "test.tif"], [/* 28 vars */]) = 0
brk(0) = 0x1395000
access("/etc/ld.so.nohwcap", F_OK) …Run Code Online (Sandbox Code Playgroud) 我正在运行一个 shell 脚本,它将数据从一个进程传输到另一个进程
process_a | process_b
Run Code Online (Sandbox Code Playgroud)
有谁知道一种方法来找出两个程序之间传递了多少字节?目前我能想到的唯一解决方案是编写一个小的 c 程序,从标准输入读取,写入标准输出并计算所有传输的数据,将计数存储在环境变量中,例如:
process_a | count_bytes | process_b
Run Code Online (Sandbox Code Playgroud)
有没有人有更简洁的解决方案?
如果我有一个管道命令,例如
cat myfile | processor_application
Run Code Online (Sandbox Code Playgroud)
其中processor_application 是从标准中读取的东西,以块为单位,进行处理,是否有可能看到文件 cat 已经走了多远?
可能使用lsof?
谢谢!