包含 sudo 的 Bash 脚本 - 不可靠的后台恢复 (bg)

Art*_*ild 9 bash ubuntu sudo job-control

我有以下简单的 bash 脚本(称为test.sh),它显示根目录中的磁盘使用情况。sudo需要列出所有目录(并且不需要我输入sudo密码)。

#!/bin/bash
sudo du -h --max-depth=1 / 2> /dev/null
Run Code Online (Sandbox Code Playgroud)

该目录位于我的路径中,然后我像这样运行脚本(以将输出输出到文本文件):

$ ./test.sh >> ./test.txt
Run Code Online (Sandbox Code Playgroud)

Ctrl现在,如果我用+暂停工作Z,我会得到:

^Z
[1]+  Stopped                 ./test.sh >> ./test.txt
Run Code Online (Sandbox Code Playgroud)

如果我然后在后台恢复bg,我仍然得到:

$ bg
[1]+ ./test.sh >> ./test.txt &

[1]+  Stopped                 ./test.sh >> ./test.txt

$ jobs
[1]+  Stopped                 ./test.sh >> ./test.txt
Run Code Online (Sandbox Code Playgroud)

(额外的尝试bg可能会导致脚本在 2-3 次尝试后实际上在后台恢复,但似乎是零星的......)

但是,如果我使用 继续fg,则脚本将在前台运行:

$ fg
./test.sh >> ./test.txt
Run Code Online (Sandbox Code Playgroud)

结果写入test.txt

3.8M    /root
4.0K    /authentic-theme
4.0K    /srv
72K     /tmp
3.2G    /snap
4.0K    /media
8.4M    /etc
0       /proc
0       /sys
4.0K    /cdrom
16K     /opt
16K     /lost+found
24K     /dev
4.3M    /run
263G    /mnt
14M     /home
19G     /var
245M    /boot
3.8G    /usr
297G    /
Run Code Online (Sandbox Code Playgroud)

如果我修改脚本以使用sudo(而是使用 运行脚本sudo),那么我可以使用 正常恢复到后台bg,并且运行脚本:

$ sudo ./test.sh >> ./test.txt 
^Z
[1]+  Stopped                 sudo ./test.sh >> ./test.txt

$ bg
[1]+ sudo ./test.sh >> ./test.txt &

$ jobs
[1]+  Running                 sudo ./test.sh >> ./test.txt &
Run Code Online (Sandbox Code Playgroud)

如果我使用 运行整个命令sudo,但不是作为脚本运行,也会发生同样的情况:

$ sudo du -h --max-depth=1 / 2> /dev/null >> ./test.txt
^Z
[1]+  Stopped                 sudo du -h --max-depth=1 / 2> /dev/null >> ./test.txt

$ bg
[1]+ sudo du -h --max-depth=1 / 2> /dev/null >> ./test.txt &

$ jobs
[1]+  Running                 sudo du -h --max-depth=1 / 2> /dev/null >> ./test.txt &
Run Code Online (Sandbox Code Playgroud)

有人能解释一下这是怎么回事吗?sudo为什么您可以在后台恢复使用以及脚本的命令,但是当脚本包含使用完全相同的命令时sudo,后台恢复bg显然无法正常工作?

我使用的是 Ubuntu 22.04.1,默认 Bash 版本为 5.1.16。

编辑#1:我可以告知我已设置alias sudo='sudo '允许命令使用sudo其他别名。但是,我测试了使用和不使用此别名的情况,并且bg在任何情况下都得到了相同的不稳定恢复行为。*

编辑#2: jobs -l给出以下正常信息:

jobs -l
[1]+ 1074808 Stopped                 ./test.sh >> ./test.txt
Run Code Online (Sandbox Code Playgroud)

编辑#3:我通常在 中运行tmux,但我也在没有 的情况下进行了测试tmux,问题仍然存在。

编辑 #4:除了我的 SuperMicro 服务器之外,我还有一个 Raspberry Pi 和一个用于在我的笔记本电脑 (Aorus X5) 上进行测试的 Ubuntu VM。这真的很奇怪:

  • 在我的 Ubuntu VM 上(在 Windows 10 下的 VMWare 上),根本不会出现此问题。bg在所有情况下,它都会第一次正确恢复。
  • 在我的 Raspberry Pi 上,问题也存在 - 通常需要 2-3 次尝试bg才能正确恢复。

我开始认为我需要测试在我的主服务器和 Raspberry Pi 上运行的软件,但不在我的虚拟机上运行。

编辑#5:stty -tostop不幸的是,运行脚本之前的设置并不能真正解决问题。大多数时候,仍需要 2-3 次尝试才能正确恢复。有几次第一次尝试就成功了,但我认为这比其他任何事情都更有机会。

编辑 #6:这些是在我的 Raspberry Pi 上运行的服务:

$ systemctl --type=service --state=running
  UNIT                             LOAD   ACTIVE SUB     DESCRIPTION                                            
  atd.service                      loaded active running Deferred execution scheduler
  containerd.service               loaded active running containerd container runtime
  cron.service                     loaded active running Regular background program processing daemon
  dbus.service                     loaded active running D-Bus System Message Bus
  docker.service                   loaded active running Docker Application Container Engine
  getty@tty1.service               loaded active running Getty on tty1
  irqbalance.service               loaded active running irqbalance daemon
  ModemManager.service             loaded active running Modem Manager
  networkd-dispatcher.service      loaded active running Dispatcher daemon for systemd-networkd
  packagekit.service               loaded active running PackageKit Daemon
  polkit.service                   loaded active running Authorization Manager
  prometheus-node-exporter.service loaded active running Prometheus exporter for machine metrics
  rsyslog.service                  loaded active running System Logging Service
  serial-getty@ttyS0.service       loaded active running Serial Getty on ttyS0
  smartmontools.service            loaded active running Self Monitoring and Reporting Technology (SMART) Daemon
  snapd.service                    loaded active running Snap Daemon
  ssh.service                      loaded active running OpenBSD Secure Shell server
  systemd-journald.service         loaded active running Journal Service
  systemd-logind.service           loaded active running User Login Management
  systemd-networkd.service         loaded active running Network Configuration
  systemd-timesyncd.service        loaded active running Network Time Synchronization
  systemd-udevd.service            loaded active running Rule-based Manager for Device Events and Files
  udisks2.service                  loaded active running Disk Manager
  unattended-upgrades.service      loaded active running Unattended Upgrades Shutdown
  unbound.service                  loaded active running Unbound DNS server
  user@1000.service                loaded active running User Manager for UID 1000

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.
26 loaded units listed.
Run Code Online (Sandbox Code Playgroud)

我相信这些是我安装和激活的(并且在 SuperMicro 和 Raspberry Pi 上运行):

  containerd.service               loaded active running containerd container runtime
  docker.service                   loaded active running Docker Application Container Engine
  prometheus-node-exporter.service loaded active running Prometheus exporter for machine metrics
  smartmontools.service            loaded active running Self Monitoring and Reporting Technology (SMART) Daemon
  unbound.service                  loaded active running Unbound DNS server
Run Code Online (Sandbox Code Playgroud)

要测试的东西:

  • 检查sudo配置是否NOPASSWD有影响。
  • 禁用我的 SuperMicro 服务器和 Raspberry Pi 之间常见的已安装服务。