0

I am trying to write a script where I enumerate users by checking the HTTP reponse length. I want to get output "good" when response is not equal 23, however I get these errors now:

for ((i=113;i<=115;i++)); do
  if [[curl -i -s -k  -X 'GET' "http://myurl/some.asp?q=$i" |
       grep Content-Length | cut -d' ' -f2 != 23]]
  then
       echo "good"
  fi
done

Output:

bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found
cut: !=: No such file or directory
cut: 23]]: No such file or directory
bash: [[curl: command not found

If I simply make a script without if condition, then it works well:

for ((i=113;i<=115;i++)); do
    curl -i -s -k  -X 'GET' "http://myurl/some.asp?q=$i" |
    grep Content-Length
done

I checked many examples but can't seem to figure out where I am doing wrong.

tripleee
  • 175,061
  • 34
  • 275
  • 318
ChildinTime
  • 151
  • 1
  • 1
  • 10
  • 3
    Check your script in http://www.shellcheck.net/, it contains some syntax errors. – fedorqui Jul 01 '16 at 08:35
  • As the error message says, `[[curl` is not a valid command. Try `curl` instead. – melpomene Jul 01 '16 at 08:42
  • @fedorqui indeed there were not spaces after brackets. Now I have `bash: conditional binary operator expected bash: syntax error near `-i'`. Btw, that site is great! Thanks. – ChildinTime Jul 01 '16 at 08:44

2 Answers2

1

After updating your initial error, you may have a syntax like (suggestion: put some effort on format, so that it is more clear what you have and what may be wrong):

for ((i=113;i<=115;i++))
do
    if [[ curl -i -s -k  -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2 != 23 ]]
    then
        echo "good"
    fi
done

This is returning you the error:

bash: conditional binary operator expected bash: syntax error near -i'`

Which is normal, because you are basically saying:

if [[ command ]]; then ...

Where command is a set of multiple piped commands. However, in [[ you just can add expressions on the form "$var" -eq 23 or "$(command)" -ne 23.

So use $( ) to execute the command: if [[ "$(command)" -ne 23 ]]:

if [[ "$(curl -i -s -k  -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2)" -ne 23 ]]

Note I am using -ne to perform an integer comparison that means "not equal to".

Finally, notice that awk alone can do what grep and cut do in two steps:

... | grep "Content-Length" | cut -d' ' -f2

This means: check the line containing "Content-Length" and print its second field. awk makes it simple by saying:

... | awk '/Content-Length/ {print $2}'

And last, but not least, your expression for ((i=113;i<=115;i++)) can be also written as for i in {113..115} using brace expansion.

fedorqui
  • 275,237
  • 103
  • 548
  • 598
  • Thanks for this response. So final versions is `for i in {113..115}; do if [[ "$(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | awk '/Content-Length/ {print $2}')" -ne 23 ]]; then echo "good" ; fi; done` but now I get error `")syntax error: invalid arithmetic operator (error token is "` for each iteration. The only similar error I found is http://stackoverflow.com/questions/22481278/syntax-error-invalid-arithmetic-operator-error-token-is but not sure how that related to my case case. If I switch back to `!=` instead of `-ne` error disappears, but it's not correct. – ChildinTime Jul 01 '16 at 09:32
  • @Thomas well this is probably due to having double quotes within double quotes. Try escaping them --> `if [[ "$(curl -i -s -k -X 'GET' \"http://myurl/some.asp?q=$i\" | grep ...` – fedorqui Jul 01 '16 at 09:35
  • @fedorqui No, the quotes outside `"$(...)"` are independent from the quotes inside. This is one of the few cases where you can nest quotes. – tripleee Jul 01 '16 at 09:38
  • Awk can do comparison, too; `if curl ... | awk '/Content-Length/ && $2==23 { exit 0 } END { exit 1 }'; then ...` – tripleee Jul 01 '16 at 09:39
  • @fedorqui well escaping got rid of the error, but not I am pretty sure curl is not executed correctly. I get instantly response that all are 'good', while it's not the case, and usually response takes longer. – ChildinTime Jul 01 '16 at 09:40
  • @tripleee but things like `[[ "$(curl -i -s -k -X 'GET' "http://www.google.com" | grep Content-Length | cut -d' ' -f2)" -ne 23 ]] && echo "yes"` give me an error `")syntax error: invalid arithmetic operator (error token is "`. – fedorqui Jul 01 '16 at 09:42
  • 1
    The problem there is that the HTTP header contains a trailing carriage return. Awk can obiviosly fix that, too; `sub(/\015/, "");` – tripleee Jul 01 '16 at 09:44
  • @Thomas this is a bit weird. What if we split this in two steps, to debug: firstly get the content: `var=$(curl -i -s -k -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2)`. Print that var with `echo "$var"` to see what exactly is there. – fedorqui Jul 01 '16 at 09:48
  • 1
    My Awk on OSX doesn't like `$2` even after the `sub` but I can get the result I want with `awk '/Content-Length/ { if (0+$2 == 23) exit 0; last } END { exit 1 }'` – tripleee Jul 01 '16 at 09:52
0

If you want to test a result of the command execution you should put it into $() . So the resulting script should look as follows:

for i in {113..115}; do if [[ $(curl -i -s -k  -X 'GET' "http://myurl/some.asp?q=$i" | grep Content-Length | cut -d' ' -f2) != 23 ]]; then echo "good" ; fi; done

Also I've changed a way you iterate the values. {a..b} in bash provides a sequence from 'a' to 'b'.

alexK
  • 963
  • 1
  • 7
  • 17
  • Well it does not work. I get the same output every single time while I am supposed to get different. – ChildinTime Jul 01 '16 at 09:35
  • Can you please give some example output you're getting while executing curl? That should help debugging the issue. – alexK Jul 01 '16 at 13:24