Mailinglist Archive: opensuse (2576 mails)
| < Previous | Next > |
Re: [opensuse] BASH - Need help with ssh remote directory test?
- From: David Haller <opensuse@xxxxxxxxxx>
- Date: Sat, 21 Feb 2009 21:24:10 +0100
- Message-id: <20090221202410.GA3041@xxxxxxxxxxxxxxxxxx>
Hello,
On Sat, 21 Feb 2009, David Bolt wrote:
Correct, (I guess D.C.R. would have seen that himself, eventually),
but that was not the real problem ...
[..]
... 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@xxxxxxxxxxxx
For additional commands, e-mail: opensuse+help@xxxxxxxxxxxx
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@xxxxxxxxxxxx
For additional commands, e-mail: opensuse+help@xxxxxxxxxxxx
| < Previous | Next > |