help-bash
[Top][All Lists]
Advanced

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

strange redirection error


From: Christoph Anton Mitterer
Subject: strange redirection error
Date: Mon, 13 Sep 2021 02:02:47 +0200
User-agent: Evolution 3.38.3-1

Hey.

Perhaps someone can help me with the following, cause I cannot seem to
understand it.

The goal is to get the following in an portable (well as far as
possible) way:

output="$(cmd1 | cmd2)"
exitstatus1=...
exitstatus2=...

So I want stdout of cmd2 (which cmd1 pipes into), plus the exit statues
of each command, and stderr should also pass through unmodified.



I got that to work with the following redirection black magic:
-------------------------------------------------------------------
rk()
{
        ~/rk
}


find /proc/$$/fd -type l | sort |  sed 's/^/\tb /' >&2
value="$(
#        exec 4>&1
        exitstatus1="$(
                        {
                                { rk 3>&- 4>&- ; printf $? >&3; } |
                                ~/b64 -w 0 >&4 3>&- 4>&- ;
                        } 3>&1
                   )" 4>&1
        exitstatus2=$?
printf "INNER exitstatus1=%s\n" "$exitstatus1" >&2
printf "INNER exitstatus2=%s\n" "$exitstatus2" >&2
        if [ "$exitstatus1" -ne 0 ]; then
                exit 11
        fi
        if [ $exitstatus2 -ne 0 ]; then
                exit 22
        fi
#        exec 4>&-
      )"

printf "OUT EXIT: %s\n" "$?"
printf "OUT VALUE: %s\n" "$value"
find /proc/$$/fd -type l | sort |  sed 's/^/\te /' >&2
-------------------------------------------------------------------

With ~/rk being:
-------------------------------------------------------------------
#!/bin/sh
find /proc/$$/fd -type l | sort |  sed 's/^/\t\tread_key_b /' >&2
head -c 32 /dev/urandom
find /proc/$$/fd -type l | sort |  sed 's/^/\t\tread_key_e /' >&2
exit 3
-------------------------------------------------------------------

And ~/b64 being:
-------------------------------------------------------------------
#!/bin/sh
find /proc/$$/fd -type l | sort |  sed 's/^/\t\tbase64_b /' >&2
/usr/bin/base64 -w 0
find /proc/$$/fd -type l | sort |  sed 's/^/\t\tbase64_e /' >&2
exit 9
-------------------------------------------------------------------


The reason that I call ~/rk via rk() (and not directly as I do with
~/b64) is simply that this follows my actual program, in which rk reads
a binary key, depending on config via some other program from an
unmounted device, or directly via cat.

Since it's binary, I have to feed it through e.g. base64 (and later
again, when I us it).

That I call base64 via ~/b64 was simply that I can print the
/proc/$$/fd for testing purposes.




Now in principle, all works fine:
- I get the exit statuses (yah, the two ones are actually just
  available within the outer $(), but that's enough for me)
- I get the base64 enced data in $value
- before and after all this, there seem to be no extra FDs left
- even the executed "programs" (~/rk and ~/b64) don't seem to see any
  of the temporary FDs (3 and 4)


The above works in e.g. dash and busybox' sh/ash, but it fails in bash.

It works in bash if I uncomment the:
#        exec 4>&1


1) I didn't find in POSIX, whether one would need to explicitly open
   the FD with exec before, or not.
   Any ideas?
2) What puzzles me even more:
   Why is it needed for FD 4, but not for FD 3 ... isn't that doing
   just the very same?
3) Even with the final:
   #        exec 4>&-
   there is no leftover FD 4, after the whole thing (I mean in the same
   shell context).
   Why? Shouldn't that be left over?
4) Oh and does anyone know, whether I need to look out for already
   opened FD 3 and 4?


Thanks,
Chris.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]