cwd*_*cwd 245 command-line shell io-redirection
有一些命令可以过滤或作用于输入,然后将其作为输出传递,我认为通常是stdout- 但有些命令只会接受stdin并执行它们对它所做的任何事情,并且不输出任何内容。
我最熟悉 OS X,因此我立即想到了两个pbcopy和pbpaste- 它们是访问系统剪贴板的方法。
无论如何,我知道如果我想使用 stdout 并将输出输出到两个stdout文件和一个文件,那么我可以使用该tee命令。我对 有一点了解xargs,但我认为这不是我要找的。
我想知道如何拆分stdout以在两个(或多个)命令之间切换。例如:
cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
Run Code Online (Sandbox Code Playgroud)
可能有一个比那个更好的例子,但我真的很想知道如何将标准输出发送到一个不中继它的命令,同时避免stdout被“静音” - 我不是问如何cat归档和grep它的一部分并将其复制到剪贴板 - 具体命令并不那么重要。
另外 - 我不是在问如何将它发送到文件,而且stdout- 这可能是一个“重复”的问题(抱歉),但我做了一些查找,只能找到类似的询问如何在标准输出和文件之间拆分的问题- 这些问题的答案似乎是tee,我认为这对我不起作用。
最后,你可能会问“为什么不让 pbcopy 成为管道链中的最后一件事?” 我的回答是 1) 如果我想使用它并且仍然在控制台中看到输出怎么办?2)如果我想使用两个stdout在处理输入后不输出的命令怎么办?
哦,还有一件事 - 我意识到我可以使用tee一个命名管道(mkfifo),但我希望有一种方法可以简洁地内联完成,无需事先设置:)
Mat*_*Mat 298
您可以tee为此使用和处理替换:
cat file.txt | tee >(pbcopy) | grep errors
Run Code Online (Sandbox Code Playgroud)
这将发送cat file.txtto 的所有输出pbcopy,并且您只能grep在控制台上获得结果。
您可以在tee零件中放置多个过程:
cat file.txt | tee >(pbcopy) >(do_stuff) >(do_more_stuff) | grep errors
Run Code Online (Sandbox Code Playgroud)
Gil*_*il' 158
您可以为 指定多个文件名tee,此外,标准输出可以通过管道传输到一个命令中。要将输出分派到多个命令,您需要创建多个管道并将它们中的每一个指定为tee. 有几种方法可以做到这一点。
如果您的 shell 是 ksh93、bash 或 zsh,则可以使用进程替换。这是一种将管道传递给需要文件名的命令的方法。shell 创建管道并将文件名传递/dev/fd/3给命令。该数字是管道连接到的文件描述符。某些 Unix 变体不支持/dev/fd; 在这些上,使用命名管道代替(见下文)。
tee >(command1) >(command2) | command3
Run Code Online (Sandbox Code Playgroud)
在任何 POSIX shell 中,您都可以显式使用多个文件描述符。这需要一个支持 的unix 变体/dev/fd,因为除了一个输出之外的所有输出都tee必须按名称指定。
{ { { tee /dev/fd/3 /dev/fd/4 | command1 >&9;
} 3>&1 | command2 >&9;
} 4>&1 | command3 >&9;
} 9>&1
Run Code Online (Sandbox Code Playgroud)
最基本和可移植的方法是使用命名管道。缺点是你需要找到一个可写的目录,创建管道,然后清理。
tmp_dir=$(mktemp -d)
mkfifo "$tmp_dir/f1" "$tmp_dir/f2"
command1 <"$tmp_dir/f1" & pid1=$!
command2 <"$tmp_dir/f2" & pid2=$!
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
rm -rf "$tmp_dir"
wait $pid1 $pid2
Run Code Online (Sandbox Code Playgroud)
jim*_*mij 23
如果您正在使用,zsh那么您可以利用MULTIOS功能的强大功能,即tee完全摆脱命令:
uname >file1 >file2
Run Code Online (Sandbox Code Playgroud)
只会将 的输出写入uname两个不同的文件:file1和file2,相当于uname | tee file1 >file2
同样重定向标准输入
wc -l <file1 <file2
Run Code Online (Sandbox Code Playgroud)
相当于cat file1 file2 | wc -l(请注意,这与 不同wc -l file1 file2,后者分别计算每个文件中的行数)。
当然,您也可以MULTIOS使用进程替换将输出重定向到其他进程而不是文件,例如:
echo abc > >(grep -o a) > >(tr b x) > >(sed 's/c/y/')
Run Code Online (Sandbox Code Playgroud)
Nik*_*ley 19
只是玩过程替换。
mycommand_exec |tee >(grep ook > ook.txt) >(grep eek > eek.txt)
Run Code Online (Sandbox Code Playgroud)
grep是两个二进制文件,它们的输出mycommand_exec与其过程特定的输入相同。
对于命令产生的相当小的输出,我们可以将输出重定向到临时文件,并将这些临时文件发送到循环中的命令。当执行命令的顺序可能很重要时,这会很有用。
例如,以下脚本可以做到这一点:
#!/bin/sh
temp=$( mktemp )
cat /dev/stdin > "$temp"
for arg
do
eval "$arg" < "$temp"
done
rm "$temp"
Run Code Online (Sandbox Code Playgroud)
在 Ubuntu 16.04 上使用/bin/shas dashshell测试运行:
$ cat /etc/passwd | ./multiple_pipes.sh 'wc -l' 'grep "root"'
48
root:x:0:0:root:/root:/bin/bash
Run Code Online (Sandbox Code Playgroud)
将命令捕获STDOUT到变量中,并根据需要多次重复使用它:
commandoutput="$(command-to-run)"
echo "$commandoutput" | grep -i errors
echo "$commandoutput" | pbcopy
Run Code Online (Sandbox Code Playgroud)
如果您也需要捕获STDERR,请2>&1在命令末尾使用,如下所示:
commandoutput="$(command-to-run 2>&1)"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
172775 次 |
| 最近记录: |