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

apt-get aborts in subshell with redirections on Debian 12



Hi folks,

I've just about run out of ideas here, so appealing for suggestions.
I don't know if this is a change in the behaviour of apt or bash, or both, between Debian 11 and 12.

I have a script which is supposed to smooth out some apt actions, while still keeping user interactions, but with the upgrade to Debian Bookworm some apt prompts are aborting immediately. Any apt errors are stored in a variable for checking over. I'll paste the full function below for those who are curious - but this simple command will illustrate:

errors=$( sudo apt-get install mirage 2>&1 1>/dev/tty )
echo "$errors"

(Replace 'mirage' with 'mirag' to see some content in $errors, and anyway choose a package you don't already have installed and which will bring in some dependencies, so apt will prompt to continue.)

On Debian 12, I get:

Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  gir1.2-gexiv2-0.10 libexiv2-27 libgexiv2-2
Suggested packages:
  exiv2 gimp imagemagick
The following NEW packages will be installed:
  gir1.2-gexiv2-0.10 libexiv2-27 libgexiv2-2 mirage
0 upgraded, 4 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,761 kB of archives.
After this operation, 8,250 kB of additional disk space will be used.
Do you want to continue? [Y/n] Abort.

Going straight to "Abort" which is what happens if apt has no stdin. But surely it does?

Running the same command on Debian 11 works as expected, waiting for USER response at the prompt.

Also, even on Debian 12, the command does not abort if run on dash instead of bash.

This works OK too:

( sudo apt-get install mirage 2>&1 1>/dev/tty )

It's only when stderr is captured that the abort is triggered.

If there's no nice workaround I'll switch to making a temp file and put stderr there instead. Not elegant, but this works:

tmp=$(mktemp)
sudo apt-get install mirage 2> $tmp
errors=$(<$tmp)

FWIW this is the original bash function (maybe no longer needed anyway) which used to work on Bullseye but not on Bookworm:

# Usage safeInstall [--apt-get-option] package [package...]
safeInstall() {
    local ignore_string_pw='Sorry, try again.' # message if password mistyped
    local ignore_string1='Extracting templates from packages: 100%' # apt sends this to stderr!
    local ignore_string2='Retrieving bug reports... Done' # apt-listbugs sends this to stderr!
    local ignore_string3='Parsing Found/Fixed information... Done' # apt-listbugs sends this to stderr!
    local apt_error
    if exec 3>&1; apt_error=$(LC_MESSAGES=C sudo apt-get install "${@}" 2>&1 1>&3) && {
            [[ -z "$apt_error" ]] || ! grep -iqEv "(${ignore_string_pw:-$^}|${ignore_string1:-$^}|${ignore_string2:-$^}|${ignore_string3:-$^}|^$)" <<<"$apt_error"
            }
    then
        exec 3>&-
        say 'Installation finished sucessfully.' 1
        return 0
    else
        exec 3>&-
        errorExit "There were problems installing ${*}" "${apt_error:-Install Aborted}"
        return 1
    fi
}

--
John


Reply to: