0

I have ips file with content:

192.168.10.10 3306
192.168.10.20 3306

and my script is:

1 #!/bin/bash
  2
  3 p=0
  4 cat /root/ips | while read host port
  5  do
  6    check_up=$(bash -c 'exec 3<> /dev/tcp/'$host'/'$port';echo $?' 2>/dev/null)
  7     if [ $check_up != 0 ]
  8         then
  9           p=$[$p+1]
 10           echo "(1):p in loop = $p"
 11     fi
 12         echo "(2):p in loop = $p"
 13  done
 14      echo "(3):p out loop = $p"
 15
 16     if [ $p % 2 != 0 ]
 17        then
 18             exit 1
 19      fi
~

and out put is:

[root@db1 ~]# ./new-script.sh
(1):p in loop = 1
(2):p in loop = 1
(1):p in loop = 2
(2):p in loop = 2
(3):p out loop = 0
./new-script.sh: line 16: [: too many arguments

why echo "(3):p out loop = $p" return 0 (first value $p)!? when last value $p is 2 ? also, how to fix the error in line 16?

  • Why do you believe that you're using correct test syntax? – Ignacio Vazquez-Abrams Mar 6 '18 at 15:47
  • @Ignacio Vazquez-Abrams I did not understand you.what do you mean? – pyramid13 Mar 6 '18 at 15:52
  • You're asking two questions - you should only ask one at a time, for the benefit of other people who search for answers before asking themselves. It becomes difficult for searches to find the correct url results when you combine questions. – user1404316 Mar 6 '18 at 15:58
2

The standard way to do arithmetic in the shell is $((..)). Standard test/[ supports only comparisons and other tests. So, the standard-conforming version would be:

if [ "$(( p % 2 ))" -ne 0 ]; then...

(That only needs the quotes if your IFS contains digits, so usually they're not needed.)


In Bash/ksh/zsh, you could use the (( .. )) construct, which works like a command and allows the test too:

if (( p % 2 != 0 )); then ...

The [[ test seems to allow some arithmetic, but it's a bit picky about the syntax/whitespace, so you probably shouldn't do that.


As for why the assignment to p doesn't persist outside the loop, see

  • Note that [ p%2 -ne 0 ] works in ksh. – Stéphane Chazelas Mar 6 '18 at 16:08
  • And in bash. test (and [) absolutely does do integer math if you actually use correct syntax, e. g. if [ $((2+2)) -eq 4 ]; then echo yep; fi. – DopeGhoti Mar 6 '18 at 16:14
  • @DopeGhoti, that's not test doing the addition, it's the arithmetic expansion that does it. – ilkkachu Mar 6 '18 at 16:18
  • I should have said, rahter, that [ and test can to integer arithmetic comparison (with the -eq, -ne, -ge, le, -lt, and -gt operators). – DopeGhoti Mar 6 '18 at 16:47

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.