27

Yesterday before going to sleep I started a long process of which I thought it would be finished before I stand up, therefore I used

./command && sudo poweroff

my system is configured to not ask for a password for sudo poweroff, so it should shutdown when that command is finished.

However it is still running and I want to use that system for other tasks now. Having that command running in the background is not an issue, but having my system possibly shutting down any second is.

Is there a way to prevent zsh from executing the poweroff command while making sure that the first one runs until it is done?

Would editing the /etc/sudoers file so that the system asks for my password still help in this case?

Max Matti
  • 493
  • 6
  • 13
  • Did you start that in an interactive zsh shell as `{ ./command && sudo poweroff; } &` or as part of a zsh script (in a terminal session or not?)? – Stéphane Chazelas Mar 22 '21 at 10:31
  • @StéphaneChazelas in an interactive shell. – Max Matti Mar 22 '21 at 10:32
  • Was it really put in background or is it still running in foreground in that interactive shell? How did you put it in background? – Stéphane Chazelas Mar 22 '21 at 10:36
  • @StéphaneChazelas it's not in background. It runs in a terminal in the terminal emulator "Konsole". I can start other programs by opening another tab or another window. I have used `htop` to increase the niceness of the command, so it doesn't interfere with what I'm doing. – Max Matti Mar 22 '21 at 10:40
  • I myself would write a simple C program that runs two command lines. Before running the second command line, the program would wait as long as a file is present. I can prevent the second command from being executed by creating the file. – Martin Rosenau Mar 26 '21 at 20:08
  • This question is a near-duplicate of mine ("[How can I cancel the rest of a list of commands in Bash?](https://unix.stackexchange.com/q/434991/37849)"), except that I ask about bash and this question is about zsh. Still, some of the answers there may be relevant. – Psychonaut Apr 06 '21 at 14:07

3 Answers3

35

As you clarified in comments it's still running in foreground on an interactive shell, you should just be able to press Ctrl+Z.

That will suspend the ./command job. Unless ./command actually intercepts the SIGTSTP signal and chooses to exit(0) in that case (unlikely), the exit status will be non-0 (128+SIGTSTP, generally 148), so sudo poweroff will not be run.

Then, you can resume ./command in foreground or background with fg or bg.

You can test with:

sleep 10 && echo poweroff

And see that poweroff is not output when you press Ctrl+Z and resume later with fg/bg.

Or with

sleep 10 || echo "failed: $?"

And see failed: 148 as soon as you press Ctrl+Z.

Note that this is valid for zsh and assuming you started it with ./command && sudo poweroff. It may not be valid for other shells, and would not be if you started it some other way such as (./command && sudo poweroff) in a subshell or { ./command && sudo poweroff; } as part of a compound command (which zsh, contrary to most other shells transforms to a subshell so it can be resumed as a whole when suspended).

Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
  • 1
    Once the ./command resumes (I assume op wants to finish that task) it will be still attached to the && sudo poweroff, so the problem remains? is there a way to cancel that && command? maybe rename the poweroff command temporarily? – Olivier Dulac Mar 23 '21 at 04:47
  • 2
    @OlivierDulac, no it will not, not in `zsh`, that `&& sudo poweroff` will be evaluated at the time `./command` is suspended and the job *returns* the first time with an exit status of 148. It's only if you entered `fg && sudo poweroff` instead of `fg` alone that `sudo poweroff` would be run once `./command` exits successfully (without being suspended again). – Stéphane Chazelas Mar 23 '21 at 06:35
  • 3
    wow, that's highly unexpected... && or || is usually there to ensure the right hand part is done only if the left hand part was complete (and resp exited with 0 or >0). suspending shouldn't change that, it makes little sense (and is counter intuitive). Thanks for the heads up (I usually am happy to use ctrl-z to pause something when needed, but now I will be very worried if the command is complex) – Olivier Dulac Mar 23 '21 at 07:52
  • 2
    @OlivierDulac,but if it had to be done like you say, how would the shell handle it? Note that `zsh`'s behaviour is already an improvement on most other shells where when you press Ctrl-Z while a function or compound command is running for instance, it interrupts the whole command and you can resume it later, though that's then done in a subshell, so in a subshell environment which means changes are lost once the interrupted and resumed function returns. Here if you want to be able to stop/resume a chain, you should start it in a subshell. – Stéphane Chazelas Mar 23 '21 at 08:08
  • 1
    And this is why I usually use `&&` when chaining long-running commands (like `cp` or `rsync`) instead of `;`, in case I want to change my mind about what I'm queueing up after this one finishes. – Peter Cordes Mar 24 '21 at 15:08
9

You could just rename /sbin/poweroff temporarily.

Bib
  • 2,056
  • 1
  • 4
  • 10
1

Is there a way to prevent zsh from executing the poweroff command while making sure that the first one runs until it is done?

I don't think it's possible unless you use something like gdb to edit the memory of a running process.

Would editing the /etc/sudoers file so that the system asks for my password still help in this case?

It should help.

Artem S. Tashkinov
  • 26,392
  • 4
  • 33
  • 64
  • 2
    They could always kill the shell process that waits for the `./command` termination. Whether that would affect the running of `./command` would depend on the context. – Stéphane Chazelas Mar 22 '21 at 10:32
  • That might kill the `./command` as well. – Artem S. Tashkinov Mar 22 '21 at 10:38
  • 2
    Possibly, which is what I meant by *Whether that would affect the running of ./command would depend on the context* and why I'm requesting clarifications from the OP. But depending on that context, it's likely it's possible to remove that risk one way or another. – Stéphane Chazelas Mar 22 '21 at 10:40