I'm processing a package of pictures, from which "file" returns the following:
$ file pic.jpg
pic.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 96x96, segment length 16, baseline, precision 8, 231x288, frames 3
$ file pic.jpg | cut -d',' -f8 | tail -c+2
231x288
So I'm picking dimensions in two variables, using built-in "read", before proceeding with cropping.
But something eludes me. Why isn't this construct working...
$ ( file pic.jpg | cut -d',' -f8 | tail -c+2 | IFS=x read width height ; echo w:$width h:$height; )
w: h:
...while this construct is working?
$ ( IFS=x read width height <<< $(file pic.jpg | cut -d',' -f8 | tail -c+2) ; echo w:$width h:$height; )
w:231 h:288
To summarize, why can't I use a pipeline with built-in "read" in that situation?
In bash, the commands in a pipeline are run in subshells (see the last paragraph of Pipelines in the manual). Any variables you declare in a subshell will disappear when the subshell exits.
You can use the { }
grouping construct to keep the read
and the echo
in the same subshell:
file pic.jpg | cut -d',' -f8 | tail -c+2 | { IFS=x read width height ; echo w:$width h:$height; }
This is why the here-string is useful: it runs the read
command in the current shell, so the variables are available in the next command.