管道查找命令“stderr”命令

时间:2012-03-01 11:30:16

标签: unix find pipe io-redirection

嗨,我有一个奇怪的问题,我正在努力找到(双关语)解决方案。

$> find ./subdirectory -type f 2>>error.log

我收到一个错误,例如,“查找:./subdirectory/noidea:Permission denied”来自此命令,这将被重定向到 error.log

在重定向到 error.log 之前,有没有办法将 stderr 传递给另一个命令?

我希望能够做一些像

这样的事情
$> find ./subdirectory -type f 2 | sed "s#\(.*\)#${PWD}\1#" >> error.log

我想只将 stderr 连接到 sed 命令并获取 find命令错误的完整路径。

我知道管道在这里不起作用,可能不是正确的方法。

我的问题是我需要 stdout stderr ,两者都必须同时处理不同的事情。

编辑: 好。对我的问题略作修改。

现在,我有一个shell脚本 solve_problem.sh

在这个shell脚本中,我有以下代码

ErrorFile="error.log"
for directories in `find ./subdirectory -type f 2>> $ErrorFile`
do
    field1=`echo $directories | cut -d / -f2`
    field2=`echo $directories | cut -d / -f3`
done

同样的问题,但在shell脚本中。 “find:./ sububirectory / noidea:Permission denied”错误应该进入 $ ErrorFile 并且 stdout 应该分配给变量 $ directories

3 个答案:

答案 0 :(得分:2)

同时管道stderr和stdout - 来自this post的想法:

(find /boot | sed s'/^/STDOUT:/' ) 3>&1 1>&2 2>&3 | sed 's/^/STDERR:/'

示例输出:

STDOUT:/boot/grub/usb_keyboard.mod
STDERR:find: `/boot/lost+found': Brak dostępu

3>&1 1>&2 2>&3这样的Bash重定向交换了stderr和stdout。

我会将您的示例脚本修改为如下所示:

#!/bin/bash
ErrorFile="error.log"
(find ./subdirectory -type f 3>&1 1>&2 2>&3 | sed "s#^#${PWD}: #" >> $ErrorFile) 3>&1 1>&2 2>&3 | while read line; do
    field1=$(echo "$line" | cut -d / -f2)
    ...
done

请注意我换了stdout& stderr两次。

小额外评论 - 请查看查找手册页中的-printf选项。它可能对你有用。

答案 1 :(得分:1)

如果您需要将stderr重定向到stdout,以便管道中的以下命令将其作为输入,那么您可以使用2>&1

有关详细信息,请查看all about redirection操作方法。

编辑:即使您需要在管道中进一步编辑传递stdout,您也可以使用sed过滤错误消息并将其写入文件:

$ find . -type f 2>&1 | sed '/^find:/{
> w error.log
> d
> }'

在这个例子中:

    {li} in find命令stderr被重定向到stdout 来自sed的{​​{1}}命令中的
  • 与正则表达式匹配的错误将写入文件(find)并从输出中删除(w error.log)。
  • 管道后面的管道中的任何命令都将收到d的输出。

注意:这将作为lon工作,因为来自find的所有错误消息都以find开头。否则,应修改find:中的正则表达式以正确匹配所有情况。

答案 2 :(得分:0)

你可以尝试这个(在bash上),这似乎有效:

find ./subdirectory -type f 2> >(sed "s#\(.*\)#${PWD}\1#" >> error.log)

执行以下操作:

  1. 2>将stderr重定向到
  2. >(...)进程替换(运行sed,附加到error.log)