'Avoid subshell from pipe on dash

I have this example code:

find "$1" ! -regex "$regex" 2>/dev/null | while read line ; do
    a="$line"
done

echo ("$a") # prints nothing because of subshell

I need:

  • Workaround for subshell to make $a visible outside (in global scope)
  • To NOT use bash's process substitution
  • To have compatible with dash, bash and korn shell

How can I achieve this? Is there any simple solution?



Solution 1:[1]

If I understand you correctly, it is not so much the subshell that is bothering you, but the fact that the variable does not retain its value outside the subshell. You could use code grouping like this:

find "$1" ! -regex "$regex" 2>/dev/null | 
{ 
  while read line
  do
    a=$line
  done
  echo "$a"
}

You can use the value of variable a as long as it is inside the curly braces.

Solution 2:[2]

Without a named pipe and without running the whole thing in a subshell, you can use a here-doc with a command substitution inside the here-doc:

while read line; do
    a=$line
done <<EOF
    $(find "$1" ! -regex "$regex" 2>/dev/null)
EOF

echo "$a"

This should be portable.

See also. BashFAQ/024.

Note. Parsing the output of find like this is an antipattern.

Solution 3:[3]

I also just ran into this bug so here are a few things I've found:

Here's a link to a relevant github issue

According to this comment, this problem only affects images with specific tags. Also this only applies to version 7, while version 6 had a different but similar issue that stopped exif_transpose from working. The comment says this wasn't fixed until version 8.1.0. I'm trying on version 9 and it appears to be fixed.

I'd recommend upgrading your version of pillow. If you're not able to do that, you could try this. I haven't tested it on pillow 7 but it looks like it may work.

    import Image, ExifTags

try :
    image=Image.open(os.path.join(path, fileName))
    for orientation in ExifTags.TAGS.keys() : 
        if ExifTags.TAGS[orientation]=='Orientation' : break 
    exif=dict(image._getexif().items())

    if   exif[orientation] == 3 : 
        image=image.rotate(180, expand=True)
    elif exif[orientation] == 6 : 
        image=image.rotate(270, expand=True)
    elif exif[orientation] == 8 : 
        image=image.rotate(90, expand=True)

    image.thumbnail((THUMB_WIDTH , THUMB_HIGHT), Image.ANTIALIAS)
    image.save(os.path.join(path,fileName))

except:
    traceback.print_exc()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 gniourf_gniourf
Solution 3