sudo+use_pty+urxvt+pipe [WAS: apt-get aborts in subshell with redirections on Debian 12]
- To: debian-user@lists.debian.org
- Subject: sudo+use_pty+urxvt+pipe [WAS: apt-get aborts in subshell with redirections on Debian 12]
- From: John Crawley <john@bunsenlabs.org>
- Date: Sun, 24 Dec 2023 17:41:33 +0900
- Message-id: <[🔎] 03c5ca99-b449-4977-bfa8-5ea77d10cffd@bunsenlabs.org>
- In-reply-to: <bbafa481-ff11-bc43-88d4-e86c2026c20e@bunsenlabs.org>
- References: <a4cfab72-d12d-c269-0ce8-8b43a37a8056@bunsenlabs.org> <8734z3ew7p.fsf@free.fr> <ZRAtYYFzSAM1pJ4V@wooledge.org> <7738690d-8792-8d1b-2247-dfaace3a28a6@bunsenlabs.org> <ZRDWAgSvfkxmeD16@wooledge.org> <a704cb6d-0c3e-0407-418b-35e98df3d53a@bunsenlabs.org> <ZREBoTRuAek1rM3+@wooledge.org> <7b11b341-5d82-4ee9-8ddb-d32f062a23cf@hemathor.de> <ZRFtN7YkYU6j/yzp@wooledge.org> <bbafa481-ff11-bc43-88d4-e86c2026c20e@bunsenlabs.org>
On 26/09/2023 11:52, John Crawley wrote:
On 25/09/2023 20:21, Greg Wooledge wrote:
On Mon, Sep 25, 2023 at 11:14:24AM +0200, Michael wrote:
so i looked into /etc/sudoers and all /etc/sudoers.d/* and found two
suspicous flags:
/etc/sudoers:
Defaults use_pty
/etc/sudoers.d/0pwfeedback:
Defaults pwfeedback
then consulting the sudo manpage convinced me, it was the 'use_pty' flag (in
section SUDOERS OPTIONS). after removing that flag everything works as
'expected':
Well, that is quite the find.
Indeed! Many thanks Michael.
8< snip >8
Anyway, for my personal purposes, this new behaviour looks too unpredictable and I plan to fall back on capturing stderr in a tempfile. Kludgy but maybe more robust than multiple redirections?
:~$ temp=$(mktemp)
:~$ sudo apt-get install nopkg 2>"$temp"
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
:~$ errors=$(<"$temp")
:~$ echo "$errors"
E: Unable to locate package nopkg
:~$ rm "$temp"
It would be nice to unpick the rest of the mystery though...
Revision:
apt commands where STDERR was captured in a variable were (still are) causing the apt prompt to be pre-empted to "No", eg:
(replace mirage with any package which is not installed, and needs to pull in some dependencies, so will call a prompt to confirm)
john@bookworm-tmp:~$ errors=$(sudo apt-get install mirage 2>&1 1>/dev/tty)
[sudo] password for john:
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
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 12 not upgraded.
Need to get 0 B/1,735 kB of archives.
After this operation, 8,373 kB of additional disk space will be used.
Do you want to continue? [Y/n] Abort.
That was because of the new sudo default use_pty, and there seemed to be no workaround, so I switched to sending apt's STDERR to a temporary file instead. Life could go on.
Background:
The function which ran apt was part of a long script which logged all its output to a file for later possible bugfixing, using this line near the beginning:
exec > >( tee -ia "$logfile" ) 2>&1
Once the apt functions no longer used the previous subshell capturing then everything worked fine, until recently, when the aborts reappeared, but only under very specific circumstances, all these:
*) use_pty is set in /etc/sudoers (now default and desirable for security)
*) the apt command is run in a new terminal launched with <terminal> -e bash -c '<command+args>'
*) the terminal is urxvt (I tested xterm, gnome-terminal, lxterminal and terminator - none aborted)
*) the apt command output is either piped (apt install mirage | cat) or redirected to a process substitution (as in the above exec).
Redirecting STDERR to a file (sudo apt-get install mirage 2>"$tempfile") is fine,
and even redirecting STDOUT to a file works (typing blind!).
Redirecting to a command triggers the Abort.
Examples of commands which will cause apt to abort:
urxvt -e bash -c "sudo apt-get install mirage > >( tee -ia \"$logfile\" )"
urxvt -e bash -c 'sudo apt-get install mirage | cat'
urxvt -e bash -c 'sudo apt-get install mirage | tee /dev/null'
urxvt -e bash -c 'sudo apt-get install mirage > >( cat )'
urxvt -e bash -c 'sudo apt-get install mirage 2> >( cat )'
Examples where the Abort is NOT triggered:
urxvt -e bash -c "sudo apt-get install mirage >$filename"
urxvt -e bash -c "sudo apt-get install mirage 2>$filename"
urxvt -e bash -c 'sudo apt-get install mirage 3> >( cat )'
urxvt -e bash -c "sudo apt-get install mirage 3> >( tee -ia \"$logfile\" )"
any command where the terminal is not urxvt
any command run directly in the terminal, not in a new one with -e
In fact, to see what's happening in the terminal before it closes, you should append a 'read' command:
urxvt -e bash -c "sudo apt-get install mirage > >( tee -ia \"$logfile\" ); echo 'Press any key to continue'; read -srn1"
So, is this a urxvt bug, or is it doing the Right Thing here when in a pseudo-terminal and all the others are not?
More practically, is there now any way to record a script's STDOUT to a logfile, while also showing it to the user, while urxvt is set as x-terminal-emulator, if that script is going to run apt commands with sudo?
--
John
Reply to: