while loop to read file ends prematurely

后端 未结 4 1869
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-06 08:29

The eventual goal is to have my bash script execute a command on multiple servers. I almost have it set up. My SSH authentication is working, but this simple while loop is

相关标签:
4条回答
  • 2021-01-06 08:48

    Assign to an array before the loop, so that you are not using stdin for your loop variables. The ssh inside the loop can then use stdin without interfering with your loop.

    readarray a <  hosts.list
    for HOST in "${a[@]}"; do 
           ssh $HOST "uname -a"
           #...other stuff in loop
    done
    
    0 讨论(0)
  • 2021-01-06 08:51

    maybe with python XD

    #!/usr/bin/python
    
    import sys
    import Queue
    from subprocess import call
    
    logfile = sys.argv[1]
    q = Queue.Queue()
    
    with open(logfile) as data:
        datalines = (line.rstrip('\r\n') for line in data)
        for line in datalines:
            q.put(line)
    
    
    while not q.empty() :
        host = q.get()
        print "++++++ " + host + " ++++++"
        call(["ssh", host, "uname -a"])
        call(["ssh", host, "oslevel -s"])
        print "++++++++++++++++++++++++++"
    
    0 讨论(0)
  • 2021-01-06 08:59

    If you run commands which read from stdin (such as ssh) inside a loop, you need to ensure that either:

    • Your loop isn't iterating over stdin
    • Your command has had its stdin redirected:

    ...otherwise, the command can consume input intended for the loop, causing it to end.

    The former:

    while read -u 5 -r hostname; do
      ssh "$hostname" ...
    done 5<file
    

    ...which, using bash 4.1 or newer, can be rewritten with automatic file descriptor assignment as so:

    while read -u "$file_fd" -r hostname; do
      ssh "$hostname" ...
    done {file_fd}<file
    

    The latter:

    while read -r hostname; do
      ssh "$hostname" ... </dev/null
    done <file
    

    ...can also, for ssh alone, can also be approximated with the -n parameter (which also redirects stdin from /dev/null):

    while read -r hostname; do
      ssh -n "$hostname"
    done <file
    
    0 讨论(0)
  • 2021-01-06 09:04

    As the solution specified here use -n option for ssh or open file with a different handle:

    while read -u 4 HOST
      do
        echo $HOST
        ssh $HOST "uname -a"
        ssh $HOST "oslevel -s"
        echo ""
      done 4< hosts.list`
    
    0 讨论(0)
提交回复
热议问题