说我有一个目录hi.txt 和blah.txt 我执行以下命令在linux上下的命令行

ls *.* | xargs -t -i{} echo {}

输出你将看到的是

echo blah.txt
blah.txt
echo hi.txt
hi.txt

我想向stderr输出(说'echo blah.txt'失败...), 只留下的产出从xargs-t命令 写到标准,但它看起来如果它stderr。

ls *.* | xargs -t -i{} echo {} 2> /dev/null

有没有办法控制它,以使它输出到stdout?

有帮助吗?

解决方案

因此,我相信你想要的是有如stdout是

  • 该stdout从实用工具,执行xargs
  • 该清单的命令产生的xargs-t

你想忽略stderr流而产生的 执行工具。

请纠正我,如果我错误的。

第一,让我们创造一个更好的检测实用工具:

% cat myecho
#!/bin/sh
echo STDOUT $@
echo STDERR $@ 1>&2
% chmod +x myecho
% ./myecho hello world
STDOUT hello world
STDERR hello world
% ./myecho hello world >/dev/null
STDERR hello world
% ./myecho hello world 2>/dev/null
STDOUT hello world
%

所以现在我们有一些实际产出的两stdout and stderr,所以我们 可以肯定,我们只得到我们想要什么。

一切方式来做到这一点是不使用xargs,而是使。呼应的命令 然后做这是种什么样的作。那是它的袋子。

% cat Makefile
all: $(shell ls *.*)

$(shell ls): .FORCE
  ./myecho $@ 2>/dev/null

.FORCE:
% make
./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./myecho hi.txt 2>/dev/null
STDOUT hi.txt
% make >/dev/null
% 

如果你绑到使用xargs,然后你需要修改的实用工具, xargs使用,因此它surpresses stderr。然后你可以使用 2>&1 欺骗其他人 已经提到移动的命令清单所产生的xargs-t从stderr 到stdout。

% cat myecho2
#!/bin/sh
./myecho $@ 2>/dev/null
% chmod +x myecho2
% ./myecho2 hello world
STDOUT hello world
% ls *.* | xargs -t -i{} ./myecho2 {} 2>&1
./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./myecho hi.txt 2>/dev/null
STDOUT hi.txt
% ls *.* | xargs -t -i{} ./myecho2 {} 2>&1 | tee >/dev/null
%

所以这种方式工作,并崩溃你想要的一切stdout(留下了什么你不想要)。

如果你发现自己这样做很多,你可以写一般的实用工具谅stderr:

% cat surpress_stderr
#!/bin/sh
$@ 2>/dev/null
% ./surpress_stderr ./myecho hello world
STDOUT hello world
% ls *.* | xargs -t -i{} ./surpress_stderr ./myecho {} 2>&1
./surpress_stderr ./myecho blah.txt 2>/dev/null
STDOUT blah.txt
./surpress_stderr ./myecho hi.txt 2>/dev/null
STDOUT hi.txt
%

其他提示

使用:

ls | xargs -t -i{} echo {} 2>&1 >/dev/null

2>&1发送的标准误差从xargs到标准输出是目前打算;所述>/dev/null发送原始标准输出到/dev/null。所以,最终的结果是,标准输出包含回声命令,/dev/null包含文件名。我们可以辩论有关的文件名空间和是否会更容易使用sed脚本把“回声”在每一行的前面(无-t选项),或者是否可以使用:

ls | xargs -i{} echo echo {}

(测试:Solaris 10上,Korn外壳;应在其他壳和Unix平台上工作)


如果你不介意看到的命令的内部工作,我还是设法隔离开来xargs输出的错误,并且命令的错误输出执行。

al * zzz | xargs -t 2>/tmp/xargs.stderr -i{} ksh -c "ls -dl {} 2>&1"

在(非标准)命令al列出每行它的一个参数:

for arg in "$@"; do echo "$arg"; done

在第一重定向(2>/tmp/xargs.stderr)发送从xargs输出的误差到文件/tmp/xargs.stderr。执行的命令是“ksh -c "ls -dl {} 2>&1"”,它使用Korn外壳在包含任何错误输出去到标准输出的文件名运行ls -ld

/tmp/xargs.stderr的输出如下所示:

ksh -c ls -dl x1 2>&1
ksh -c ls -dl x2 2>&1
ksh -c ls -dl xxx 2>&1
ksh -c ls -dl zzz 2>&1

我用“ls -ld”到位echo,以确保我在测试错误 - 文件x1x2xxx存在,但zzz

在标准输出的输出看起来像:

-rw-r--r--   1 jleffler rd          1020 May  9 13:05 x1
-rw-r--r--   1 jleffler rd          1069 May  9 13:07 x2
-rw-r--r--   1 jleffler rd            87 May  9 20:42 xxx
zzz: No such file or directory

当没有包裹在“ksh -c "..."”的命令运行,则I / O重定向被作为参数传递给该命令(“ls -ld”)通过,并且因此报告说,它不能找到文件“2>&1”。也就是说,xargs本身没有使用shell做I / O重定向。

这将有可能为各种其他重定向安排,但基本的问题是,xargs未作任何规定从它所执行的命令分离了自己的错误输出,所以这是很难做的。

在其它相当明显的选择是使用xargs写一个外壳脚本,然后有壳执行它。这是我以前显示的选项:

ls | xargs -i{} echo echo {} >/tmp/new.script

可以看到然后命令以:

cat /tmp/new.script

可以运行命令以丢弃错误:

sh /tmp/new.script 2>/dev/null

和,如果你不希望看到的命令标准输出的任一,追加1>&2到命令的末尾。

要执行的

xargs -t回声的命令执行它们之前到stderr。如果你想他们,而不是回显到标准错误,你可以管标准错误与2>&1构建标准输出:

ls *.* | xargs -t -i{} echo {} 2>&1

它看起来像xargs的-t到stderr,而且也没有什么可以做的。

您可以这样做:

ls | xargs -t -i{} echo "Foo: {}" >stderr.txt | tee stderr.txt

到终端作为命令运行在仅显示标准错误的数据,然后通过的stderr.txt的grep后以查看是否发生任何意外,沿着grep -v Foo: stderr.txt的线

另外请注意,在Unix上,ls *.*是不是你显示的一切。如果你想看到所有的文件,只是在自己的运行ls

据我了解使用GNU并行 http://www.gnu.org/software/并行/ 会做正确的事:

ls *.* | parallel -v echo {} 2> /dev/null
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top