1

In order to troubleshoot some ftp connection error, I've been instructed to write a bash script which will infinitely connect to a remote frp server and get one file from there.

ftpuser="ftpuser" 
ftppasswd="ftppasswd" 
ftpsrv="download.akamai.com" 
log="/var/log/test_ftp_akamai.log" 
function print_log { 
        echo $(date +'%d-%m-%y %H:%M:%S') $* >> $log 
} 

while true 
do print_log "-----===== Start =====------" | tee -a $log 
/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv | tee -a $log 
sleep 2 | tee -a $log 
print_log "-----===== Done =====------" | tee -a $log 
done

The script works properly but the output of the wget line which is printed to screen is supposed to also be tee'ed to the log, but for some reason only it isn't being written to the log.

Example:

[root@sjorigin1 ~]# tailf /var/log/test_ftp_akamai.log 
25-02-15 02:10:31 -----===== Start =====------
25-02-15 02:10:33 -----===== Done =====------
25-02-15 02:10:33 -----===== Start =====------
25-02-15 02:10:35 -----===== Done =====------

Can you find the reason for the fact that it is not written to the log?

Thanks in advance,

2
  • Is the wget output really on STDERR? That would explain why it doesn't get sent through the pipe. If that's the case you could try ... |& tee -a $log (given a grown-up shell).
    – MadHatter
    Feb 25, 2015 at 10:22
  • 1
    You are also using double redirection. print_log appends to $log and then you pipe to tee -a $log as well. The pipe will never receive any input so you could simply remove it; or for consistency, you could change the function so it just logs to stdout. The whole thing would be more elegant if you just added done | tee -a "$log" at the end of the loop, rather than redirect every command inside the loop. Then you can fix wget by just adding 2>&1 there.
    – tripleee
    Mar 6, 2015 at 13:02

1 Answer 1

3

The reason is that although the echo statements go to STDOUT, and thus get sent through the pipe to tee, the "output" you're seeing from the wget command is on STDERR, which doesn't.

This doesn't go through a pipe by default, going - as you saw - to tty instead. If you want to send both STDOUT and STDERR to a pipe's STDIN, you should use |&, eg

/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv |& tee -a $log

That works in bash and tcsh, if memory serves. For bog standard sh it's a bit more work, but can still be done (though I can't off the top of my head remember how).

Edit (by Anthony, whose comment follows; thanks! - MadHatter):

The syntax for POSIX compatible shells (should also work for sh) would be:

/usr/bin/wget ftp://$ftpuser:$ftppasswd@$ftpsrv 2>&1 | tee -a $log
1
  • I can never remember off the top of my head either; it's quicker and easier to find relevant information in the dash manual. Feb 25, 2015 at 14:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .