1

In Bash this will set a time limit of 10 seconds for the slowcommand

timeout 10 slowcommand

I'm wondering how I could get the same behavior, if I had to call sudo in order to run slowcommand, i.e.:

timeout 10 sudo slowcommand

This will timelimit on sudo, not on the slowcommand... Is there an elegant way to do this while using sudo?

Edit: Let's assume timeout is not permitted to be run with sudo.

8
  • What's wrong with sudo timeout 10 slowcommand? – Panki Nov 16 '20 at 15:10
  • @Panki Reasons aside, let's just assume timeout is not allowed to be run as sudo. – su_li Nov 16 '20 at 15:16
  • 1
    You know what happens when you assume right? Why can't timeout be run with sudo? – jesse_b Nov 16 '20 at 15:22
  • 2
    Essential read: What is the XY problem? – pLumo Nov 16 '20 at 15:34
  • 1
    @jesse_b I would say having timeout in sudoers would be a pretty bad idea - just a guess – Panki Nov 16 '20 at 15:54
6

timeout is not a builtin/function of the bash shell or of any shell for that matters (except if you want to consider busybox sh, where busybox commands can be seen as builtin of the shell).

timeout is a non-standard standalone utility of which there exists several often incompatible implementations (there also exist timelimit utilities with the same function).

In:

timeout 10 sudo slowcommand

Current versions of the GNU implementation of the timeout utility (from GNU coreutils, again distinct from the GNU shell, bash), run sudo slowcommand and sends the SIGTERM command to its own process group if sudo has not finished within 10 seconds.

However the process running sudo has changed user id, and the process that sudo has spawned to run slowcommand will also run with a different uid, so even though both processes will be in the same process group as that running timeout, timeout will not have the right to send signals to them.

There are possible ways around that. You can arrange for the kernel to send some signals instead of some unprivileged process like that running timeout. For instance, you could have it send:

  • SIGPIPE if slowcommand writes to a closed pipe:

    sudo slowcommand | timeout 10 cat
    

    would cause SIGPIPE to be sent to slowcommand if it writes something to stdout after 10 seconds.

    (incidentally, here, cat, sudo and slowcommand will all run in the same process group, so that's the same as timeout 10 sudo slowcommand | cat).

  • SIGXCPU if slowcommand uses more than its assigned limit of CPU time:

    (ulimit -t 10; exec sudo slowcommand)
    

    Would cause slowcommand to be killed if it uses 10 seconds of CPU time.

  • SIGHUP if the terminal hangs up, and sudo is not session leader:

    timeout 10 script -qfc 'sudo slowcommand; exit' /dev/null
    

    (here assuming util-linux script)

  • SIGINT/SIGQUIT. You could also use things like expect/zpty/script/screen to simulate a terminal and send a ^C character after 10 seconds for SIGINT to be sent to the foreground process group of that terminal.

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.