Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I'm making a backup script for ldap. I want the errors to go to a file in /var/log and the output to go to another file in the backup folder. Currently I'm redirecting to a temp file and then sending the temp file to the log. I'd rather do this as a 1 liner though...

/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

Any ideas on how to redirect stderr and stdout to different pipes to condense this command into 1 line? Or is there a better way?

share|improve this question
    
Take a look at this demonstration: stackoverflow.com/a/16283739/1765658 or this other meaning sample: unix.stackexchange.com/a/84012/27653 –  F. Hauri Aug 2 '13 at 7:43

3 Answers 3

up vote 7 down vote accepted

As indicated by this answer at 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

Running yields:

  • stderr.log 6

  • stdout.log 1

share|improve this answer
4  
Useless use of tee award? –  Dubu Jul 26 '13 at 20:13
    
@Dubu - cargo cult programming, am afraid. Plus lack of coffeeeeee. Thanks... –  Deer Hunter Jul 27 '13 at 2:27

In Bash, you can use process substitution to manage the extra file descriptors for you. You may find this a little neater looking than the file descriptor swap method.

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

Your command might look something like this:

/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" \
  )
share|improve this answer
1  
This is the correct answer. –  Michael Martinez Aug 29 '13 at 18:10

I am guessing this is not possible. Pipe only connects the stdout of one command to the stdin of the next command. stderr avoids the pipeline altogether and is typically printed directly to the screen. Thus it is not possible to use the output of stderr later in the pipeline.

You can merge stderr into stdout with 2>&1 so that stderr continues along the pipeline, although then the two streams will be merged together and you can't separate them later in the pipeline.

I looked at the various methods of using file descriptors (http://www.tldp.org/LDP/abs/html/io-redirection.html), but didn't see a way to solve this.

share|improve this answer
    
The site that you linked to is widely considered to be low quality in relation to Bash. Greg Wooledge's site is much better. Here is his Redirection landing page. –  Dennis Williamson Jul 27 '13 at 0:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.