[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Probably very stupid script/bash question

Brian wrote:
Mark Clarkson wrote:
On Tue, 04 Mar 2008 18:46:05 +0100
Brian <Brian_dorling@t-online.de> wrote:

I could not get this to work, the shell complains:

./dirvish-mail.sh: 98: Syntax error: redirection unexpected

Interesting to note that this does not work under busybox. I think
this is rather an esoteric but often useful bash feature. (It also
needs /proc so is not available in some special cases.)

The other solution from Alex:

 >> echo "$teststring" | ( read A B C D E F; )

Of course, both solutions work perfectly under bash.

This should not have worked under bash either since it is still running
in a sub-shell, so the variables are lost when read finishes.

of course you are correct. I had written the following test script:


teststring="one two three four five six"

{ read A B C D E F; } < <( echo "$teststring" )
echo "Data received = $E Bytes"

echo "$teststring" | ( read A B C D E F; )
echo "Data received = $E Bytes"

$E was still set from the first read call. Duuh.

So can you explain exactly what the first < <( echo "$teststring" )
does exactly please?

Cheers Brian

It looks like the construct '< <(...)' is an undocumented (at least it's not in the man page for bash) feature that redirects the output of a command in such a way as to look like it's from a file. I base this on the following observations:

1. Reading the man page for bash, it states that if a builtin command (such as 'read') is used in a pipe, the command is run in a sub shell. This is why "echo 1 2 3 | read A B C" followed by echo $A $B $C prints only a blank line. The assignment is in a sub shell and lost when execution comes back to the parent.

2. If I have a file with more than one line in it and the first line has no white space, and I do this:

        read A B C < file

The variable A will have the first line of the file in it, with all subsequent variables empty. If the first line has white space, then as many variables as there are "fields" in the line will contain values.

3. if I do this, using the '< <(...)' construct with an echo that produces two lines:

        { read A B C D E F; } < <( echo -e "one two three\nfour five" )

The first three variables will have the first three values, but the last three variables will be empty.

4.  See 5, below.

Since this operator appears to follow the same rules as file redirection, it would seem logical to assume it "mimics" file type I/O redirection. But this is a WAG ('wild ass guess' for those that don't know) and may be way off base.

In any case, I'd be interested in knowing where you found this construct.

Further, for those interested in actually using it, these are the rules I've figured out, so far:

1. The format is exact, you must have one or more white spaces between the two 'less than' symbols and NO space between the 'less than' and the 'left parenthesis'. White space before or after the four characters appears to be immaterial, it works with or without it.

2. Changing the operator to '< <{' doesn't work, only works with parenthesis (not unexpected, just checking:).

3. Space after the left parenthesis or before the right parenthesis is not needed. Works with or without it.

4. The command to the left of the operator does not need to be isolated. Both:

        { read A B C D E F; } < <( echo ....)
        read A B C D E F < <( echo ....)

work the same.

5. Just like '<' from a file, the position of '< <(...)' can be anywhere on the line. This line works just like the examples above, though the ones used above are certainly more understandable to human eyes:

        < <(echo one two three four five six) read A B C D E F

Bob McGowan

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

Reply to: