shell - Two while loops behaving strangely, Bash script -
i'm new bash scripting. have written script me info using ssh bunch of servers. ip address of first set of devices 101 148, , other set 201 210.
#!/bin/bash base=192.168.11 sd_start=101 sd_end=148 hd_start=201 hd_end=210 sd_counter=$sd_start hd_counter=$hd_start while [[ $sd_counter -le $sd_end ]] ip=$base.$sd_counter ssh $ip command1 sd_counter=$(($sd_counter +1)) if [ "$sd_counter"==148 ] while [[ $hd_counter -le $hd_end ]] ip=$base.$hd_counter ssh $ip command2 hd_counter=$(($hd_counter +1)) done fi done > log_sd_hd echo "done!" but reason command1 executed on 192.168.11.101 first, command2 executed on ip range 192.168.11.201-192.168.11.210 second while loop. after first while loop continues till end. why happening? want first while loop done before second while loop. please point out i'm doing wrong?
@0x1cf's answer provides right pointer:
[ "$sd_counter"==148 ] doesn't work expected.
specifically: "$sd_counter"==148, based on bash's string synthesizing rules, expanded single string literal: value of $sd_counter concatenated literal ==148, , resulting string literal treated boolean. since non-empty string in boolean context evaluates true, [ "$sd_counter"==148 ] evaluates true due lack of spaces around ==.
aside that: in bash should use [[ ... ]] rather [ ... ] - more robust , provides more features.
also note (as @0x1cf notes too) - if using [ ... ] or [[ ... ]] - using arithmetic operators right choice when dealing numbers: -eq, -ne, -lt, -le, -gt, or -ge.
generally, though, using (( ... )) expressions - arithmetic evaluation - provides more flexibility numbers - see below.
that said, your code can simplified using arithmetic evaluation - (( ... )) (see section arithmetic evaluation in man bash):
it allows use c-style arithmetic , boolean expressions. if combine bash's array variables, code can simplified to:
#!/usr/bin/env bash base=192.168.11 start_indices=( 101 201 ) end_indices=( 148 210 ) commands=( command1 command2 ) numranges=${#start_indices[@]} (( range = 0; range < numranges; ++range )); cmd=${commands[range]} (( i=${start_indices[range]}; i<=${end_indices[range]}; ++i )); ip=$base.$i ssh $ip $cmd done done > log_sd_hd note:
(( ... ))expressions differ normal bash assignments , conditionals in you:- need not reference variables
$ - need not double-quote variable references
- you may have spaces around assignment operator (
=) - you may omit spaces around relational operators:
(( sd_counter==148 ))work.
- need not reference variables
( string1 ... )creates array elementsstring1,...;${#arrayvar[@]}returns count of elements of array variablearrayvar;${arrayvar[ndx]}returns element (0-based) indexndx.- it's better avoid all-uppercase variable names such
base, may conflict environment variables, convention typically all-uppercase.
Comments
Post a Comment