Failed to run scripts in multiple remote host by ssh

前端 未结 3 1195
轻奢々
轻奢々 2021-01-24 21:27

I write a deployAll.sh, which read ip_host.list line by line, then add group for all the remote hosts,

when I run: sh deployAll.sh

results:

Gro         


        
相关标签:
3条回答
  • 2021-01-24 21:33

    That's a frequent problem which is caused by the special behavior of ssh, which sucks up stdin, starving the loop ( i.e. while read line;do ...;done )

    Please see Bash FAQ 89 which discusses this subject in detail.

    I also just answered ( and solved ) a similar question regarding ffmpeg with the same behavior as ssh in this case. Here: When reading a file line by line, I only get to execute ffmpeg on the first line.

    TL;DR :

    There are three main options:

    • Using ssh's -n option. Quoted from man ssh:
      -n     Redirects  stdin  from  /dev/null  (actually,  prevents reading from stdin).  This must be used when ssh is run in the background.  A common trick is to use this to run X11 programs on a remote
              machine.  For example, ssh -n shadows.cs.hut.fi emacs & will start an emacs on shadows.cs.hut.fi, and the X11 connection will be automatically forwarded over an encrypted channel.  The ssh pro‐
              gram will be put in the background.  (This does not work if ssh needs to ask for a password or passphrase; see also the -f option.)
    
    • Adding a </dev/null at the end of ssh's line ( i.e. ssh ... </dev/null ) will fix the issue and will make ssh behave as expected.

    • Let read read from a File Descriptor which is unlikely to be used by a random program:

         while IFS= read -r line <&3; do
             # Here read is reading from FD 3, to which 'ip_host.list' is redirected.
         done 3<ip_host.list
      
    0 讨论(0)
  • 2021-01-24 21:36

    Without the ssh command (which wouldn't make sense on my network), I get the expected output so I suspect that the ssh command is swallowing the remaining standard input. You should use the -n flag to prevent ssh from reading from stdin (equivalent to redirecting stdin from /dev/null):

    ssh -n "${ipandhost[0]}" "groupadd -g 1011 test"
    

    or

    ssh "${ipandhost[0]}" "groupadd -g 1011 test" < /dev/null
    

    See also How to keep script from swallowing all of stdin?

    0 讨论(0)
  • 2021-01-24 21:45

    My solution is to generate ssh keys through ssh-keygen command and replace existing public key file (if any). After which installation will resume.

    0 讨论(0)
提交回复
热议问题