将stderr和stdout传递给不同的命令(而不仅仅是文件)


11

我正在为ldap制作备份脚本。我希望将错误转到/ var / log中的文件,并将输出转到备份文件夹中的另一个文件。当前,我将重定向到一个临时文件,然后将该临时文件发送到日志。我宁愿作为1班轮来做这件事...

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v 2>>/tmp/ldaptmp.err |
  gzip -c > /mnt/backups/ldap/`date +\%Y\%m\%d`.ldif.gz || 
  logger -t ldapbackup -p local6.err error exit $?

cat /tmp/ldaptmp.err | grep -v "ldap_initialize( ldap://ldap.server )" | 
  grep -v "filter: (objectclass=\*)" |
  grep -v "requesting: All userApplication attributes" >$ERR_LOG
rm -f /tmp/ldaptmp.err

关于如何将stderr和stdout重定向到不同管道以将此命令压缩为1行的任何想法?或者,还有更好的方法?


1
看一下这个演示:stackoverflow.com/a/16283739/1765658或其他有意义的示例:unix.stackexchange.com/a/84012/27653
F. Hauri

Answers:


10

如在Unix SE上的答案所示:

MyWeirdCommand.sh

#!/bin/bash
echo "1 2   3"
echo "4 5   6" >&2

testRedirection.sh:

#!/bin/bash
(./MyWeirdCommand.sh | cut -f1 >stdout.log) 3>&1 1>&2 2>&3 | cut -f3 >stderr.log

运行收益:

  • stderr.log 6

  • stdout.log 1


24

在Bash中,您可以使用进程替换为您管理额外的文件描述符。您可能会发现它比文件描述符交换方法看起来更整洁。

command > >(process_stdout) 2> >(process_stderr)

您的命令可能如下所示:

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v \
  > >( \
    gzip -c > /mnt/backups/ldap/$(date '+%Y%m%d').ldif.gz || 
    logger -t ldapbackup -p local6.err error exit $?
  ) \
  2> >( \
    grep -Ev "ldap_initialize( ldap://ldap.server )|filter: (objectclass=\*)|requesting: All userApplication attributes" > "$err_log" \
  )

1
这是正确的答案。
Michael Martinez

如果要保留链而不是重定向到文件,则可能需要将输出重定向回stderr,如下所示:sh f>>(sed -e“ s / ^ / stdout:/”)2>>( sed -e“ s / ^ / stderr:/”>&2)
James Moore

>(process)符号的技术名称是什么?
jchook

1
@jchook我在第一句话中使用了术语:“进程替换”。
暂停,直到另行通知。

1

这是我打印stdout和stderr来分离带有时间戳的文件的方法(从Debian moreutils包中将其管道传输到ts):

(./my_little_script.pl | ts %F\ %T > out.log) 2>&1 | ts > err.log

PS,如果您没有ts,请输入自己的别名:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.