1

I'm currently working on a small script where I need to update a file on multiple servers, I have a long IP list of my servers and currently I'm using ncftpput to add the files to the servers one at a time.

I can't figure out how to start ncftpput with the next IP address in my list so that I can have multiple updates running at the same time.

My list is just IP addresses:

192.168.0.1
192.168.0.2
192.168.0.3
......
until 192.168.0.150

What I need is the first ncftpput to access the first IP, the second number two IP and so on for the amount of threads I need / system can handle.

Let's say 10 at a time and when the first thread finishes it just takes the next IP NOT taken by any of the other threads.

I hope I made myself clear on my problem and that someone can help me figure this out.

So far I'm doing it this way: (running one at a time)

while read ip; do
    ncftpput -c -A -u "$USER" -p "$PASSWD" "$ip" "/usr/local/program/program.conf" < "~/addthisinfo" 2>/dev/null
    if [ $? -eq 0 ]
        then
            echo -e "Here goes my succes test" >>/tmp/text_added
        else
            echo "$ip failed ! please take care of this"
    fi  
done <"$pathtoiplist""/iplist"

I have been trying with some of the answers I found around the net but I can't see my way out of this. I keep ending up with a new instance of ncftpput or multiple starting from top of my file and not from the next IP address in the list.

1

Simply put an & character at the end of your ncftpput command to make it run in background and return control back to the script immediately, like this:

ncftpput [...] < "~/addthisinfo" 2>/dev/null &

I omitted the long list of options you had, don't forget to add them back instead of [...]

0

Building on Byte Commander’s answer, I suggest

while read ip
do
    (
    ncftpput -c -A -u "$USER" -p "$PASSWD" "$ip" "/usr/local/program/program.conf" < "~/addthisinfo"
    if [ "$?" -eq 0 ]
        then
            echo "Here goes my success test" >>/tmp/text_added
        else
            echo "$ip failed ! please take care of this"
    fi
    ) &
done < "$pathtoiplist/iplist" 2>/dev/null

Notes:

  • This spawns an asynchronous (background) subshell for each IP address in your iplist.  This allows the shell to detect and log the failure of any ncftpput instance (process).
  • You’ve done a good job of quoting your shell variable references (e.g., "$ip" and "$pathtoiplist").  But you should also quote "$?".  Strictly speaking, you don’t need to quote simple constant strings like "/usr/local/program/program.conf".  But it doesn’t hurt.
  • I’m not sure whether you really want the echo for every successful invocation, and I especially don’t know why you want to do it with echo -e (when the message text doesn’t contain any backslashes).
  • You might want to send the error (failure) messages to a file.  Since the processes are running asynchronously, you might want to write separate error files to avoid collisions; e.g.,
     echo "$ip failed ! please take care of this" > "/tmp/$ip.error"
  • I moved the 2>/dev/null from the ncftpput command to the loop (the done line) for simplicity.  Note that you cannot do this with the < "~/addthisinfo", since you need each instance to read the file independently.
  • I changed "$pathtoiplist""/iplist" to "$pathtoiplist/iplist".  This is safe as long as the first character after the variable name (/, in this case) is one that is not allowed in variable names.  I did the same thing with "/tmp/$ip.error", above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.