Hello, On Sat, 21 Feb 2009, David Bolt wrote:
On Fri, 20 Feb 2009, David C. Rankin wrote:- [..]
while read DESTHOST; do if ssh $DESTHOST '[[ -d "$DIRNAME" || $(mkdir -p "DIRNAME") -eq 0 ]]'; then [..] Also, one thing that's very likely to be breaking it is that you've wrapped the string in single quotes, $DIRNAME is passed to the shell on $DESTHOST as is, which means that the test and mkdir will fail because $DIRNAME will be an empty variable. That is unless it is defined on $DESTHOST as a part of the environment.
Correct, (I guess D.C.R. would have seen that himself, eventually), but that was not the real problem ... [..]
for DESTHOST in $(<${HOME}/testhosts) do
... which you coincidentally avoid here. BTW, you should _always_ quote _all_ variables as "good" as you can! If D.C.R. had quoted the command correctly himself, others might have seen that the problem is something else entirely, and you could have suggested the for-loop as an alternative. The real reason why only the first host is tested is, that ssh "sucks" away all stdin so that the read in the while-loop sees only the first host -- the rest disappears in ssh. Example: $ echo -e "localhost\nlocalhost\nlocalhost" | while read host ; do ssh "$host" 'wc -l'; done dh@localhost's password: 2 (which happens also, if the remote program does _not_ read stdin itself, e.g. using '/bin/true' instead of 'wc -l') The solution is to simply tell ssh not to read stdin: $ echo -e "localhost\nlocalhost\nlocalhost" | while read host ; do ssh "$host" 'wc -l' </dev/null; done dh@localhost's password: 0 dh@localhost's password: 0 dh@localhost's password: 0 And openssh ssh has an '-n' switch. $ DIRNAME="/tmp/test10/foo"; $ test -d /tmp/test10/foo && rmdir /tmp/test10/foo $ echo -e "localhost\nlocalhost\nlocalhost" | while read host ; do ssh -n "$host" "test -d '$DIRNAME' || { echo 'creating \"$DIRNAME\"'; mkdir -p '$DIRNAME'; }"; echo "$?" done; dh@localhost's password: creating "/tmp/test10/foo" 0 dh@localhost's password: 0 dh@localhost's password: 0 And you can simplify quoting and add comments by feeding the commands to ssh via stdin (which is not the while-loop stdin): $ echo -e "localhost\nlocalhost\nlocalhost" | while read host ; do ssh "$host" /bin/bash <<EOCMD; ## this is our stdin for ssh->/bin/bash. If you don't use /bin/bash ## or another shell as remote command, the default login-shell is used ## (includes getting /etc/issue). test -d "$DIRNAME" || { echo "creating \"$DIRNAME\""; mkdir -p '$DIRNAME'; } EOCMD echo $?; done dh@localhost's password: creating "/tmp/test10/foo" 0 dh@localhost's password: 0 dh@localhost's password: 0 You could also use this formatting: $ [..] while read host ; do ssh "$host" /bin/bash <<EOCMD; echo $?; done test -d "$DIRNAME" || { ... } EOCMD i.e. put the rest of the loop behind the '<<EOCMD;'. Oh, and you can feed the while-loop with the 'done < filename'. HTH, -dnh -- Most people would say I write code like I've already lost my mind. -- Randal L. Schwartz -- To unsubscribe, e-mail: opensuse+unsubscribe@opensuse.org For additional commands, e-mail: opensuse+help@opensuse.org