Search code examples
bashprocess-substitution

Idiomatic use of process substitution


I have learned Bash process substitution from Bash's man page. Unfortunately, my unskilled usage of the feature is ugly.

DEV=<(some commands that produce lines of data) && {
    while read -u ${DEV##*/} FIELD1 FIELD2 FIELD3; do
        some commands that consume the fields of a single line of data
    done
}

Do skilled programmers have other ways to do this?

If an executable sample is desired, try this:

DEV=<(echo -ne "Cincinnati Hamilton Ohio\nAtlanta Fulton Georgia\n") && {
    while read -u ${DEV##*/} FIELD1 FIELD2 FIELD3; do
        echo "$FIELD1 lies in $FIELD2 County, $FIELD3."
    done
}

Sample output:

Cincinnati lies in Hamilton County, Ohio.
Atlanta lies in Fulton County, Georgia.

In my actual application, the "some commands" are more complicated, but the above sample captures the essence of the question.

Process substitution <() is required. Alternatives to process substitution would not help.


Solution

  • Redirect into the loop's stdin with the operator <.

    while read city county state; do
        echo "$city lies in $county County, $state."
    done < <(echo -ne "Cincinnati Hamilton Ohio\nAtlanta Fulton Georgia\n")
    

    Output:

    Cincinnati lies in Hamilton County, Ohio.
    Atlanta lies in Fulton County, Georgia.
    

    Note that in this example, a pipe works just as well.

    echo -ne "Cincinnati Hamilton Ohio\nAtlanta Fulton Georgia\n" |
        while read city county state
    do
        echo "$city lies in $county County, $state."
    done
    

    Also, uppercase variable names should be reserved for environment variables (like PATH) and other special variables (like RANDOM). And descriptive variable names are always good.