9

I have the following simple bash script (called test.sh), that shows disk usage in the root dir. sudo is needed to list all directories (and I'm not asked for sudo password).

#!/bin/bash
sudo du -h --max-depth=1 / 2> /dev/null

The directory is in my path, and then I run the script like this (to get output to a text file):

$ ./test.sh >> ./test.txt

Now, if I suspend the job with Ctrl+Z, I get this:

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

If I then resume in background with bg, I still get:

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

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

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

(Additional tries with bg may result in the script actually resuming in background after 2-3 tries, but it seems sporadic...)

However, if I resume with fg, then the script runs in foreground:

$ fg
./test.sh >> ./test.txt

And the result is written to 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    /

If I modify the script to not use sudo (and instead run the script with sudo), then I can resume to background normally with bg, and the script is run:

$ 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 &

The same happens if I run the entire command with sudo, but not as a script:

$ 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 &

Can anybody explain what's going on here? Why can you resume a command that uses sudo as well as a script in background, but when the script contains the exact same command using sudo, then background resume with bg is apparently not working correctly?

I'm using Ubuntu 22.04.1 with default Bash version 5.1.16.

Edit #1: I can inform that I have setup alias sudo='sudo ' to allow commands using sudo to use other aliases. However, I tested both with and without this alias, and I got the same erratic bg resume behavior in any case.*

Edit #2: jobs -l give the following normal information:

jobs -l
[1]+ 1074808 Stopped                 ./test.sh >> ./test.txt

Edit #3: I'm normally running in tmux, but I also tested without tmux, and the issue still persists.

Edit #4: Besides my SuperMicro server, I also has a Raspberry Pi, and an Ubuntu VM for testing on my Laptop (Aorus X5). This where it gets really strange:

  • On my Ubuntu VM (on VMWare under Windows 10), this problem does NOT occur at all. It correctly resumes bg the first time in all cases.
  • On my Raspberry Pi, the problem is present as well - it usually takes 2-3 tries with bg until it correctly resumes.

I'm beginning to think I need to test with regards to software that is running on both my main server and my Raspberry Pi, but not on my VM.

Edit #5: Setting stty -tostop before running the script unfortunately does not really help the problem. Most of the time, it still takes 2-3 tries to resume correctly. A few times it succeeds on the first try, but I think this is more chance than anything else.

Edit #6: These are the services running on my 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
  [email protected]               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
  [email protected]       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
  [email protected]                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.

I believe these are the ones that I installed and activated (and are running on both the SuperMicro and the 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

Things to test:

  • Check if sudo configuration without NOPASSWD makes a difference.
  • Disable installed services that are common between my SuperMicro server and Raspberry Pi.
12
  • I can confirm that this happens no matter what command is used with sudo in the script (I tested with sudo sleep 30), and it isn't limited to Ubuntu (I tested on Arch). I think this is related to a recent change, I know I've seen questions about the behavior in the past few days.
    – terdon
    Commented Nov 24, 2022 at 13:53
  • I noticed that if I run bg a few times (it seems to vary between 1 in some cases, 2 in others and 3 in yet others, with the same command in the script) it eventually gets passed to the right process and the sudo command continues. Do you see the same behavior?
    – terdon
    Commented Nov 24, 2022 at 13:59
  • Thanks for confirming. Yes that is correct - if you try more times, it eventually succeeds - but the written output seems "interrupted" in a way.. Commented Nov 24, 2022 at 14:01
  • 1
    It feels like there is some other process consuming the bg commands. Very strange.
    – terdon
    Commented Nov 24, 2022 at 14:13
  • I find it even more strange that the two other ways of doing the same thing with sudo succeeds every time. I actually tried a very thorough troubleshooting approach. So it is isolated when sudo is inside the script. 🤔 Commented Nov 24, 2022 at 14:16

1 Answer 1

-1

Usually, when a program refuses to background, it is because it wants input.
While df doesn't actually read from stdin, it is still open. Try:

#!/bin/bash
sudo du -h --max-depth=1 / 2> /dev/null 0< /dev/null

Note that this may leave you unable to enter a password.

Alternatively, there could be issues with attempting to send the relevant signals to the process because it isn't . I doubt this is the case, but if it is, I would suggested just running it in the background to begin with. (This isn't an issue for me.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .