0

I am trying to get the uptime of servers using SNMP. First I check if the server is online, then I try to retrieve the uptime. The issue is that I want to run the command multiple times to decrease latency in script, but I am not getting the expected output into the array.

for ip in "${Iparray[@]}"
do
    uparray=($(snmpwalk -Os -c public -v 1 $ip DISMAN-EVENT-MIB::sysUpTimeInstance | grep "^sysUpTimeInstance" | awk '{print $5}')) &
done
tail /proc/uptime | grep -o '^\S*'
wait $(jobs -p)
for ti in "${uparray[@]}"
do
    echo $ti
done

The output that I get when running the command outside of the script is:

5:58:27.35

But inside the script I get:

Timeout: No Response from 192.168.0.2
Timeout: No Response from 192.168.0.3    
Timeout: No Response from 192.168.0.5
Timeout: No Response from 192.168.0.4
Timeout: No Response from 192.168.0.1
Timeout: No Response from 192.168.0.6
Timeout: No Response from 192.168.0.12
Timeout: No Response from 192.168.0.14
Timeout: No Response from 192.168.0.13
Timeout: No Response from 192.168.0.10
Timeout: No Response from 192.168.0.21
Timeout: No Response from 192.168.0.24
Timeout: No Response from 192.168.0.22
Timeout: No Response from 192.168.0.101
Timeout: No Response from 192.168.0.23
Timeout: No Response from 192.168.0.254
Timeout: No Response from 192.168.0.107

Any help would be great. Probably a small issue in the script I have over looked.

  • There's nothing parallel about this code at all. Did you leave something out? – Charles Duffy Nov 13 '16 at 16:10
  • ...and the quoting is rather badly broken. Run it through http://shellcheck.net/ and fix what it finds. – Charles Duffy Nov 13 '16 at 16:10
  • ...if your intent is to have separate script instances contribute to a single variables's contents, then it's just "nope, doesn't work that way": each instance is its own program with its own memory, and can only change its own variables. I'd suggest using the filesystem as a combined store -- write all your results into individual files in a temporary directory, collect them all when done. – Charles Duffy Nov 13 '16 at 16:11
  • Sorry yes I forgot to add the & to the end of the code, just updated it then – AyeitzaMoleRat Nov 13 '16 at 16:13
  • (You could also use GNU parallel to generate a single, consistent output stream). – Charles Duffy Nov 13 '16 at 16:13
  • Where exactly you add a `&` is critical, but still: Once you put a `&` in place, the code so modified is running in a subprocess, so it can't change the parent process's variables. Thus, you either make the parent process wait for the output to be written (in which case it's no longer parallel), or you have the parent process going on ahead to run additional commands and no longer able to collect the output. – Charles Duffy Nov 13 '16 at 16:14
  • so, bottom line, you can't do it that way. Either have each subprocess write to a file and collect the contents of those files when they're all done, or use `parallel` or an equivalent. – Charles Duffy Nov 13 '16 at 16:15
  • To reword and emphasize: `var=$(foo) &` assigns to `var` *in a subprocess*, and that subprocess's value for `var` is not reflected in the parent process, so the rest of your script can't see it. The idiom you're using is thus one that can't possibly work, because it depends on variable state being shared with subshells, and it's not: subshells inherit their parents' variables, but parents don't inherit changes to variable state made by their children. – Charles Duffy Nov 13 '16 at 16:17

0 Answers0