V

2012-11-25
ssh draining stdin

We had a script which does some remote commands based on preconditions. It stopped processing the loop after the first time the condition was true:

#!/bin/sh
DATA="host1 1
host2 2
host3 3
host4 4
host5 5"

echo "$DATA" | while read host num; do
    if [ $(( num % 2 )) -eq 1 ]; then
        ssh $host "echo $num"
    fi
done
$ sh test1.txt 
1
$

I found that ssh was reading all the remaining data and the next read failed and the loop ended. When redirecting ssh's stdin from /dev/null everything worked as expected. As alternative to redirecting stdin you can also use the -n switch for ssh (i.e. run ssh -n $host "echo $num" ):

#!/bin/sh
DATA="host1 1
host2 2
host3 3
host4 4
host5 5"

echo "$DATA" | while read host num; do
    if [ $(( num % 2 )) -eq 1 ]; then
        ssh -n $host "echo $num"
    fi
done
$ sh test1.sh
1
3
5
$
Permalink | shell, ssh.
2012-11-26
how NOT to use xargs

What happens in the following snippet if $TEMPFILE is empty?


#!/bin/sh

TEMPFILE=$( tempfile )
find /some/dir -type f -mtime +60 -print0 > $TEMPFILE

num=0
xargs -n 1 -0 ls -Q < ${TEMPFILE} | while read file; do
    num=$(( num + 1 ))
    if [ $num -gt 1000 ]; then
        break
    fi
    file=$( echo "$file" | sed -e 's/^"//; s/"$//; s/\\"/"/g' )
    mv "$file" /some/other/dir/
done

... it will move all files from the current directory to /some/other/dir/.

One workaround is to use the --no-run-if-empty switch for xargs:

  --no-run-if-empty
  -r     If the standard input does not contain any nonblanks, do not run
         the command.  Normally, the command is run once even if there is
         no input.  This option is a GNU extension.
  (GNU xargs(1))

... we decided to rewrite in perl :)

Permalink | shell.
$HOME
Archives

Tags