11

I want to read my files line by line every 5 seconds. This time I just tried one-line bash command to do this. And bash command is:

let X=1;while [ $X -lt 20 ];do cat XXX.file |head -$X|tail -1;X=$X+1;sleep 5;done

However I got the error like:

-bash: [: 1+1: integer expression expected

What's the problem? btw, why can't we do $X < 20? (Instead we have to do -lt, less than?)

thx

1
  • And this doesn't address your question at all, but have you considered using the read operator, rather than that cat-head-tail thing? It would be simpler and much less IO-intensive. – Malvolio Aug 18 '11 at 16:30
21

Your assignment X=$X+1 doesn't perform arithmetic. If $X is 1, it sets it to the string "1+1". Change X=$X+1 to let X=X+1 or let X++.

As for the use of -lt rather than <, that's just part of the syntax of [ (i.e., the test command). It uses = and != for string equality and inequality -eq, -ne, -lt, -le, -gt, and -ge for numbers. As @Malvolio points out, the use of < would be inconvenient, since it's the input redirection operator.

(The test / [ command that's built into the bash shell does accept < and >, but not <= or >=, for strings. But the < or > character has to be quoted to avoid interpretation as an I/O redirection operator.)

Or consider using the equivalent (( expr )) construct rather than the let command. For example, let X++ can be written as ((X++)). At least bash, ksh, and zsh support this, though sh likely doesn't. I haven't checked the respective documentation, but I presume the shells' developers would want to make them compatible.

0
1

I would use

X=`expr $X + 1`

but that's just me. And you cannot say $X < 20 because < is the input-redirect operator.

2
  • Is "because" sufficient answer? The shell's parser is not very sophisticated. It was written sometime around 1970. Do you remember 1970? I don't and I'm older than you. There have been a lot of updates to shell, of course, but nobody wants to break backward-compatibility. – Malvolio Aug 18 '11 at 17:02
  • -> expr is a program and it expects operands and operators to be separate command-line arguments. – svckr Mar 15 '13 at 11:37
1

The sum X=$X+1 should be X=$(expr $X + 1 ).

You can also use < for the comparison, but you have to write (("$X" < "20")) with the double parenthesis instead of [ $X -lt 20 ].

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.