Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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: or this other meaning sample: – F. Hauri Aug 2 '13 at 7:43
up vote 8 down vote accepted

As indicated by this answer at Unix SE:

echo "1 2   3"
echo "4 5   6" >&2

(./ | 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
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
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 (, 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

This is how I print stdout and stderr to separate files with timestamps (piping to ts from Debian moreutils package):

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

P.S. if you don't have ts, make your own alias:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
share|improve this answer

Your Answer


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.