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?

6
  • 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 at 10:31
  • @StéphaneChazelas in an interactive shell. – Max Matti Mar 22 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 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 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 at 20:08
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).

5
  • 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 at 4: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 at 6:35
  • 2
    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 at 7: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 at 8: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 at 15:08
8

You could just rename /sbin/poweroff temporarily.

2
  • 8
    If you were feeling really cheeky, you could rename /bin/sudo temporarily. :) – Brian Drake Mar 23 at 10:01
  • oh god, thats so dirty - but I like it. – Robert Riedl Mar 24 at 10:36
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.

3
  • 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 at 10:32
  • That might kill the ./command as well. – Artem S. Tashkinov Mar 22 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 at 10:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.