`xargs -t` 输出是 stderr 还是 stdout,你能控制它吗?
假设我有一个包含 hi.txt 和 blah.txt 的目录,并且我在 linux-ish 命令行上执行以下命令
ls *.* | xargs -t -i{} echo {}
您将看到的输出是
echo blah.txt
blah.txt
echo hi.txt
hi.txt
我想重定向 stderr 输出(例如“echo blah.txt”失败...),仅留下输出从 xargs -t 命令写入 std 输出,但看起来好像也是 stderr 。
ls *.* | ls *.* | xargs -t -i{} echo {} 2> /dev/null
有没有办法控制它,使其输出到stdout?
say i have a directory with hi.txt and blah.txt and i execute the following command on a linux-ish command line
ls *.* | xargs -t -i{} echo {}
the output you will see is
echo blah.txt
blah.txt
echo hi.txt
hi.txt
i'd like to redirect the stderr output (say 'echo blah.txt' fails...), leaving only the output from the xargs -t command written to std out, but it looks as if it's stderr as well.
ls *.* | xargs -t -i{} echo {} 2> /dev/null
Is there a way to control it, to make it output to stdout?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
所以我相信您想要的是,因为 stdout 是
您想忽略由 xargs -t 生成的 stderr 流
执行的实用程序。
如果我错了,请纠正我。
首先,让我们创建一个更好的测试实用程序:
现在我们有了实际上输出到 stdout 和 stderr 的东西,所以我们
可以确定我们只得到我们想要的。
执行此操作的一种切线方法是不使用 xargs,而是使用 make。 回显命令
然后这样做就像 make 所做的那样。 那是它的包。
如果您依赖于使用 xargs,那么您需要修改您的实用程序
xargs 使用它来抑制 stderr。 然后你就可以使用
2>&1
欺骗别人提到将 xargs -t 生成的命令列表从 stderr 移出
到标准输出。
因此,这种方法有效,并且可以折叠您想要标准输出的所有内容(留下您不想要的内容)。
如果您发现自己经常这样做,您可以编写一个通用实用程序来抑制 stderr:
So I believe what you want is to have as stdout is
You want to ignore the stderr stream generated by the
executed utility.
Please correct me if I'm wrong.
First, let's create a better testing utility:
So now we have something that actually outputs to both stdout and stderr, so we
can be sure we're only getting what we want.
A tangential way to do this is not to use xargs, but rather, make. Echoing a command
and then doing it is kind of what make does. That's its bag.
If you're tied to using xargs, then you need to modify your utility that
xargs uses so it surpresses stderr. Then you can use the
2>&1
trick othershave mentioned to move the command listing generated by xargs -t from stderr
to stdout.
So this approach works, and collapses everything you want to stdout (leaving out what you don't want).
If you find yourself doing this a lot, you can write a general utility to surpress stderr:
xargs -t 在执行之前将要执行的命令回显到 stderr。 如果您希望它们回显到 stderr,您可以使用
2>&1
结构将 stderr 通过管道传输到 stdout:xargs -t
echos the commands to be executed to stderr before executing them. If you want them to instead echo to stderr, you can pipe stderr to stdout with the2>&1
construct:看起来 xargs -t 会转到 stderr,您对此无能为力。
你可以这样做:
ls | xargs -t -i{} echo "Foo: {}" >stderr.txt | tee stderr.txt
以在命令运行时仅在终端上显示 stderr 数据,然后按照 grep -v Foo: stderr 的方式 grep 遍历 stderr.txt 以查看是否发生任何意外情况.txt
另请注意,在 Unix 上,
ls *.*
并不是显示所有内容的方式。 如果您想查看所有文件,只需单独运行ls
即可。It looks like xargs -t goes to stderr, and there's not much you can do about it.
You could do:
ls | xargs -t -i{} echo "Foo: {}" >stderr.txt | tee stderr.txt
to display only the stderr data on your terminal as your command runs, and then grep through stderr.txt after to see if anything unexpected occurred, along the lines of
grep -v Foo: stderr.txt
Also note that on Unix,
ls *.*
isn't how you display everything. If you want to see all the files, just runls
on its own.据我了解,使用 GNU Parallel http://www.gnu.org/software/parallel/< /a> 会做正确的事情:
As I understand your problem using GNU Parallel http://www.gnu.org/software/parallel/ would do the right thing:
使用:
2>&1
将标准错误从xargs
发送到标准输出当前所在的位置;>/dev/null
将原始标准输出发送到/dev/null
。 因此,最终结果是标准输出包含 echo 命令,而/dev/null
包含文件名。 我们可以讨论文件名中的空格以及使用sed
脚本将“echo”放在每行前面(没有-t
选项)是否会更容易),或者您是否可以使用:(已测试:Solaris 10、Korn Shell;应该可以在其他 shell 和 Unix 平台上工作。)
如果您不介意查看命令的内部工作原理,我确实设法将错误输出与
xargs
以及所执行命令的错误输出。(非标准)命令
al
每行列出一个参数:第一个重定向 (
2>/tmp/xargs.stderr
) 发送来自的错误输出xargs
到文件/tmp/xargs.stderr
。 执行的命令是“ksh -c "ls -dl {} 2>&1"
”,它使用 Korn shell 对文件名运行ls -ld
任何错误输出都会转到标准输出。/tmp/xargs.stderr
中的输出如下所示:我使用“
ls -ld
”代替echo
以确保我正在测试错误- 文件x1
、x2
和xxx
存在,但zzz
不存在。标准输出上的输出如下所示:
当在没有包含在 '
ksh -c "..."
' 中的命令的情况下运行时,I/O 重定向作为参数传递给命令 ('ls -ld
'),因此报告找不到文件“2>&1
”。 也就是说,xargs 本身并不使用 shell 来执行 I/O 重定向。可以安排各种其他重定向,但基本问题是 xargs 没有提供将其自身的错误输出与其执行的命令的错误输出分开的规定,因此很难做到。
另一个相当明显的选项是使用 xargs 编写 shell 脚本,然后让 shell 执行它。 这是我之前展示的选项:
然后您可以使用以下命令查看命令:
您可以运行命令来丢弃错误:
并且,如果您也不想看到命令的标准输出,请附加
1> ;&2
到命令末尾。Use:
The
2>&1
sends the standard error fromxargs
to where standard output is currently going; the>/dev/null
sends the original standard output to/dev/null
. So, the net result is that standard output contains the echo commands, and/dev/null
contains the file names. We can debate about spaces in file names and whether it would be easier to use ased
script to put 'echo' at the front of each line (with no-t
option), or whether you could use:(Tested: Solaris 10, Korn Shell ; should work on other shells and Unix platforms.)
If you don't mind seeing the inner workings of the commands, I did manage to segregate the error output from
xargs
and the error output of the command executed.The (non-standard) command
al
lists its arguments one per line:The first redirection (
2>/tmp/xargs.stderr
) sends the error output fromxargs
to the file/tmp/xargs.stderr
. The command executed is 'ksh -c "ls -dl {} 2>&1"
', which uses the Korn shell to runls -ld
on the file name with any error output going to standard output.The output in
/tmp/xargs.stderr
looks like:I used '
ls -ld
' in place ofecho
to ensure I was testing errors - the filesx1
,x2
, andxxx
existed, butzzz
does not.The output on standard output looked like:
When run without the command wrapped in '
ksh -c "..."
', the I/O redirection was passed as an argument to the command ('ls -ld
'), and it therefore reported that it could not find the file '2>&1
'. That is,xargs
did not itself use the shell to do the I/O redirection.It would be possible to arrange for various other redirections, but the basic problem is that
xargs
makes no provision for separating its own error output from that of the commands it executes, so it is hard to do.The other rather obvious option is to use
xargs
to write a shell script, and then have the shell execute it. This is the option I showed before:You can then see the commands with:
You can run the commands to discard the errors with:
And, if you don't want to see the standard output from the commands either, append
1>&2
to the end of the command.