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,

Itai Ganot
  • 10,424
  • 27
  • 88
  • 143
  • 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 '15 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 06 '15 at 13:02

1 Answers1

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
MadHatter
  • 78,442
  • 20
  • 178
  • 229