Reputation: 1337
I am trying to read part of a file and stop and a particular line, using bash. I am not very familiar with bash, but I've been reading the manual and various references, and I don't understand why something like the following does not work (but instead produces a syntax error):
while { read -u 4 line } && (test "$line" != "$header_line")
do
echo in loop, line=$line
done
I think I could write a loop that tests a "done" variable, and then do my real tests inside the loop and set "done" appropriately, but I am curious as to 1) why the above does not work, and 2) is there some small correction that would make it work? I still fairly confused about when to use [, (, {, or ((, so perhaps some other combination would work, though I have tried several.
(Note: The "read -u 4 line" works fine when I call it above the loop. I have opened a file on file descriptor 4.)
Upvotes: 1
Views: 5204
Reputation: 13614
I think what you want is more like this:
while read -u 4 line && test "$line" != "$header_line"
do
...
done
Braces (the {} characters) are used to separate variables from other parts of a string when whitespace cannot be used. For example, echo "${var}x"
will print the value of the variable var
followed by an x
, but echo "$varx"
will print the value of the variable varx
.
Brackets (the [] characters) are used as a shortcut for the test
program. [
is another name for test
, but when test
detects that it was called with [
it required a ]
as its last argument. The point is clarity.
Parenthesis (the () characters) are used in a number of different situations. They generally start subshells, although not always (I'm not really certain in case #3 here):
(echo "Hi" ; echo "Bye") | sed -e "s/Hi/Hello/"
will print two lines, "Hello" and "Bye". It is the easiest way to get multiple echo statements to produce a single stream.$(expr 1 + 1)
will act like a variable, but will produce the value 2
.$((5 * 4 / 3 + 2 % 1))
will evaluate like a variable, but will compute the result of that mathematical expression.Upvotes: 5
Reputation: 15486
The && operator is a list operator - he seperates two commands and only executes when the first is true, but in this case the first is the while and he is expecting his do stuff. And then he reaches do and the while stuff is already history. Your intention is to put it into the expression. So you put it together with (). E.g. this a solution with just a small change
while ( read -u 4 line && test "$line" != "$header_line" )
Upvotes: 2