Hi, thanks a lot for not considering this bug as out-of-scope. :)
Quoting Gilles Filippini (2020-11-01 14:09:59) > Gilles Filippini a écrit le 31/10/2020 à 15:11 : > > Johannes 'josch' Schauer a écrit le 27/10/2020 à 18:45 : > >> Package: libhdf5-openmpi-dev > >> Version: 1.10.6+repack-2 > >> Severity: wishlist > >> > >> Hi, > >> > >> when installing libhdf5-openmpi-dev in a chroot that doesn't have /proc > >> mounted, one will get the following error: > >> > >> Setting up libhdf5-openmpi-dev (1.10.6+repack-2) ... > >> /var/lib/dpkg/info/libhdf5-openmpi-dev.postinst: line 56: /dev/fd/63: No > >> such file or directory > >> dpkg: error processing package libhdf5-openmpi-dev (--configure): > >> installed libhdf5-openmpi-dev package post-installation script subprocess > >> returned error exit status 1 > >> > >> The problem is, that the postinst script uses the bash-feature to write: > >> > >> while read x; do ... done < <(cmd2 args ...) > >> > >> Fortunately, these instances can easily be rewritten as: > >> > >> cmd2 args | while read x; do ... done > >> > >> Please consider making this change. > > > > Unfortunately it doesn't work this way. Consider this test script: > > > > $ cat test.sh > > #!/bin/bash > > declare -A foo bar > > while read var; do > > foo["$var"]="$var" > > done < <(seq 1 3) > > seq 1 3 | while read var; do > > bar["$var"]="$var" > > done > > echo "foo=${foo[@]}" > > echo "bar=${bar[@]}" > > > > $ ./test.sh > > foo=3 2 1 > > bar= > > > > Using a pipe makes variable assignments into the while loop inefficient. > > That's why I had to use the process substitution syntax. > > > > Any other idea? The problem is, that the while loop is part of the pipeline and each part of a pipe is executed within its own subshell. This means that every variable that is assigned inside the while loop is only is only valid for that subshell and never gets propagated to the parent shell. Since bash 4.2, there is one workaround: $ cat test.sh #!/bin/bash declare -A arr1 arr2 arr3 arr4 # fill arr1 while read var; do arr1["$var"]="$var" done < <(seq 1 3) # fill arr2 seq 1 3 | while read var; do arr2["$var"]="$var" done # fill arr3 set -- $(seq 1 3) while [ -n "$1" ]; do arr3["$1"]="$1" shift done # fill arr4 shopt -s lastpipe seq 1 3 | while read var; do arr4["$var"]="$var" done echo "arr1=${arr1[@]}" echo "arr2=${arr2[@]}" echo "arr3=${arr3[@]}" echo "arr4=${arr4[@]}" $ ./test.sh arr1=3 2 1 arr2= arr3=3 2 1 arr4=3 2 1 Using "shopt -s lastpipe" the last part of the pipe is not run inside a new subshell but inside the same shell as the parent and thus the variables survive. I've also put your solution into the mix as a comparison. > I've come up to this solution: > > function read_alt_slaves () { > local -n slaves=$1 > set -- $(echo "$2" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b > while;: end;q}') while [ -n "$1" ]; do > slaves["$1"]="$2" > shift 2 > done > } > ... > declare -A slave_links slave_targets > read_alt_slaves slave_links "$mpi_alt_sig" > read_alt_slaves slave_targets "$mpi_alt_impl" > > Can you confirm it would work with no /proc? I think there are some problems with wrong line wrapping in your code. To avoid any other copypaste mistake, I put a debdiff that worked for me as an attachment to this mail. With that diff, I can successfully install and remove libhdf5-openmpi-dev without /proc being mounted. Thanks! cheers, josch
diff -Nru hdf5-1.12.0+repack/debian/changelog hdf5-1.12.0+repack/debian/changelog --- hdf5-1.12.0+repack/debian/changelog 2020-04-23 19:05:38.000000000 +0200 +++ hdf5-1.12.0+repack/debian/changelog 2020-11-27 11:24:05.000000000 +0100 @@ -1,3 +1,10 @@ +hdf5 (1.12.0+repack-1~exp2.1) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * + + -- Johannes 'josch' Schauer <jo...@debian.org> Fri, 27 Nov 2020 11:24:05 +0100 + hdf5 (1.12.0+repack-1~exp2) experimental; urgency=medium * Default plugindir per flavor diff -Nru hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.postinst.in hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.postinst.in --- hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.postinst.in 2020-03-28 17:10:48.000000000 +0100 +++ hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.postinst.in 2020-11-27 11:24:05.000000000 +0100 @@ -12,6 +12,20 @@ update-alternatives \ --install /usr/lib/@MULTIARCH@/pkgconfig/hdf5.pc hdf5.pc /usr/lib/@MULTIARCH@/pkgconfig/hdf5-@FLAVOR@.pc @UA_PRIORITY_FLAVOR@ \ +# we use "set -- $(cmd); while ..." instead of "while ... < <(cmd)" because the +# latter needs /proc being mounted so that the symlink from /dev/fd to +# /proc/self/fd works. We use the "set -- $(cmd)" construct instead, so that +# we do not require /proc being mounted to run the postinst and prerm scripts +# See https://bugs.debian.org/973261 +function read_alt_slaves () { + local -n slaves=$1 + set -- $(echo "$2" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') + while [ -n "$1" ]; do + slaves["$1"]="$2" + shift 2 + done +} + # Install hdf5-mpi.pc as a new slave of the 'mpi' alternatives # See #953021 # There is no way to simply add a new slave. We must parse the existing @@ -23,14 +37,9 @@ mpi_alt_sig=$(echo "$mpi_alt" | sed '/^$/q') mpi_alt_impl=$(echo "$mpi_alt" | sed -n -e '\!^Alternative: /usr/bin/mpicc.@FLAVOR@!p' -e '0,\!^Alternative: /usr/bin/mpicc.@FLAVOR@!d' -e '/^$/q' -e 'p') mpi_impl_priority=$(echo "$mpi_alt_impl" | sed -n '/^Priority: /{s/Priority: \(.*\)$/\1/;p}') - declare -A slave_links - while read slave; do - slave_links[${slave%% *}]="${slave#* }" - done < <(echo "$mpi_alt_sig" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') - declare -A slave_targets - while read slave; do - slave_targets[${slave%% *}]="${slave#* }" - done < <(echo "$mpi_alt_impl" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') + declare -A slave_links slave_targets + read_alt_slaves slave_links "$mpi_alt_sig" + read_alt_slaves slave_targets "$mpi_alt_impl" # At this point: # * slave_links holds all the slaves name,link pairs # * slave_targets holds all the slaves name,target pairs for our mpi flavor diff -Nru hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.prerm.in hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.prerm.in --- hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.prerm.in 2020-03-28 17:10:48.000000000 +0100 +++ hdf5-1.12.0+repack/debian/libhdf5-flavor-dev.prerm.in 2020-11-27 11:24:05.000000000 +0100 @@ -2,6 +2,20 @@ set -e +# we use "set -- $(cmd); while ..." instead of "while ... < <(cmd)" because the +# latter needs /proc being mounted so that the symlink from /dev/fd to +# /proc/self/fd works. We use the "set -- $(cmd)" construct instead, so that +# we do not require /proc being mounted to run the postinst and prerm scripts +# See https://bugs.debian.org/973261 +function read_alt_slaves () { + local -n slaves=$1 + set -- $(echo "$2" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') + while [ -n "$1" ]; do + slaves["$1"]="$2" + shift 2 + done +} + if [ "$1" != "upgrade" ]; then if [ "@FLAVOR@" != "serial" ]; then update-alternatives \ @@ -21,14 +35,9 @@ mpi_alt_sig=$(echo "$mpi_alt" | sed '/^$/q') mpi_alt_impl=$(echo "$mpi_alt" | sed -n -e '\!^Alternative: /usr/bin/mpicc.@FLAVOR@!p' -e '0,\!^Alternative: /usr/bin/mpicc.@FLAVOR@!d' -e '/^$/q' -e 'p') mpi_impl_priority=$(echo "$mpi_alt_impl" | sed -n '/^Priority: /{s/Priority: \(.*\)$/\1/;p}') - declare -A slave_links - while read slave; do - slave_links[${slave%% *}]="${slave#* }" - done < <(echo "$mpi_alt_sig" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') - declare -A slave_targets - while read slave; do - slave_targets[${slave%% *}]="${slave#* }" - done < <(echo "$mpi_alt_impl" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') + declare -A slave_links slave_targets + read_alt_slaves slave_links "$mpi_alt_sig" + read_alt_slaves slave_targets "$mpi_alt_impl" # At this point: # * slave_links holds all the slaves name,link pairs # * slave_targets holds all the slaves name,target pairs for our mpi flavor @@ -50,9 +59,7 @@ mpi_alt=$(update-alternatives --query mpi) mpi_alt_sig=$(echo "$mpi_alt" | sed '/^$/q') declare -A slave_links_left - while read slave; do - slave_links_left[${slave%% *}]="${slave#* }" - done < <(echo "$mpi_alt_sig" | sed -n '/Slaves:/{: while;n;s/^ //;T end;p;b while;: end;q}') + read_alt_slaves slave_links_left "$mpi_alt_sig" if [ -z "${slave_links_left[hdf5-mpi.pc]}" ]; then update-alternatives --remove hdf5.pc /usr/lib/@MULTIARCH@/pkgconfig/hdf5-mpi.pc fi
signature.asc
Description: signature