40

This is hackish.

I sometimes need to quickly run programs one after the other in the terminal with some commands needing sudo while others do not, such as:

$ command1; c2; sudo c3 | c4; c5 | sudo c6; c7; sudo c8

I would like to initiate sudo (aka type the password) before command1 so that there will be no bottleneck in c3 waiting for the password.

Most of the time, I initiate sudo using a random command I haphazardly typed in the keyboard, like:

$ sudo laksdfjlskjf; command1; c2; sudo c3 | c4; c5 | sudo c6; c7; sudo c8

It says command not found for laksdfjlskjf, but I've successfully done what I need to do: initiate sudo. No bottleneck in c3.

Question:

Is there a better way than typing (non-)random characters to initiate sudo? Is there a safe command that does nothing and so is safe to use sudo on?

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
Majal
  • 826
  • 2
  • 10
  • 19
  • 3
    Similar question: [Pre-authorise sudo? (So it can be run later)](https://superuser.com/q/640491/432690). I don't think it's a duplicate. You want to use `sudo` again in a minute, while the other question says "7 hours later"; therefore "angles of attack" are different. Still it's good to link the two questions together, this is the main purpose of this comment. – Kamil Maciorowski Jan 12 '23 at 17:07
  • 2
    `sudo ls` would be fairly benign. – MonkeyZeus Jan 13 '23 at 13:18
  • 3
    I use `sudo id` for this. Although, now that I actually think about it, the natural solution would seem to be `sudo true`. – Mark Dominus Jan 14 '23 at 15:04
  • 1
    Likewise I would always just `sudo -i` and then immediately ^D out. Guess everyone has their own silly solutions encoded in habit and muscle memory. – hobbs Jan 14 '23 at 20:02
  • i don't want to set up a test right now so I won't leave an answer, but (going off of my memory) using curly brackets around the commands and putting sudo in front should work. Alternatively you can use `sudo bash < <( echo 'commands' )` or something similar. – Reverent Lapwing Jan 15 '23 at 11:19

3 Answers3

61

sudo -v is exactly for this. From man 8 sudo:

-v, --validate
Update the user's cached credentials, authenticating the user if necessary. For the sudoers plugin, this extends the sudo timeout for another 5 minutes by default, but does not run a command. Not all security policies support cached credentials.

The complementary command is sudo -k, it invalidates the user's cached credentials.

While I think sudo -v is the Right Thing, I admit one has to remember the option to use it without consulting the manual. This is a downside. As an alternative almost any harmless command can be used with sudo to achieve your goal; so if you happen not to remember -v at the moment, use sudo true, sudo echo or sudo date (credits go to the linked answers).


sudo -v should work for you in cases where your original approach works. In your example, if command1 and c2 take more time than it takes for sudo to forget the cached credentials then sudo c3 will ask for your password. And so on. sudo -v can replace your sudo laksdfjlskjf, but in case of long-running command(s) preceding sudo neither will work.

If the line you want to run contains long-running command(s) (not excluding sudo commands) before some sudo then consider repeating sudo -v in the background frequently enough. Example:

sudo -v    # in the foreground, so you can input your password if needed
while sudo -v; do sleep 58; done &
command1; c2; sudo c3 | c4; c5 | sudo c6; c7; sudo c8; kill "$!"
Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • 2
    Note that neither this nor OP's original solution will work for long-running commands. Password caching depends on timeouts and it can expire before the non-sudo command succeeds. – gronostaj Jan 12 '23 at 19:16
  • @gronostaj I silently assumed the OP wants a better replacement for `sudo laksdfjlskjf` that happens to work for them anyway. You are right. My answer now addresses the concern. – Kamil Maciorowski Jan 12 '23 at 20:24
  • Apart from being fewer keystrokes, I wonder how `sudo -v` improves upon `sudo true`. – reinierpost Jan 13 '23 at 14:01
  • 3
    @reinierpost It does not run `true`, which is a separate executable and runs as a separate child process. Creating a new process is costly. But even on the fastest computer that is otherwise idle, it's more elegant not to create a new process in vain. – Kamil Maciorowski Jan 13 '23 at 14:17
  • 2
    I like `sudo whoami`. It outputs `root` to show that it worked. – bdsl Jan 14 '23 at 13:44
  • Will that `sudo -v` loop will run indefinitely if you forget about it, so if you walk away, the next person to sit down at your terminal could use `sudo` without a password? Or if there's a limit to how long you can extend the same cached credentials, does it leave a `sudo` process in the background blocked on reading stdin (err, suspended with SIGTTIN)? Perhaps `timeout 60m sh -c 'while ...;do; ...;done'` or something? – Peter Cordes Jan 15 '23 at 08:02
  • 1
    @PeterCordes `kill "$!"` is there to end the loop. Still if you walk away even without forgetting about the loop, a rogue can Ctrl+C the foreground command before it gets to `kill "$!"`. Note this angle of attack is possible even if you manage to use `timeout` to run the loop, unless `timeout` has already expired and cached credentials expired. – Kamil Maciorowski Jan 15 '23 at 08:06
  • Ah, I missed the `kill "$!"`. Yeah, as long as things go according to plan when running the set of commands, that'll do it. But if you're going to put the `while` loop into an alias or shell-function, incorporating a timeout right into that seems like a good idea. Like `sudo-refresh 20m &` to plan ahead to keep your sudo credentials valid for at least 20 minutes, or set a 1 hour default with no arg. You could still kill the background job earlier at the end of your string of commands, but a timeout as a failsafe might be good for an alias for people to copy/paste. – Peter Cordes Jan 15 '23 at 08:14
  • @PeterCordes The answer is now community wiki. If you think you can improve it then please go ahead. – Kamil Maciorowski Jan 15 '23 at 08:16
  • You didn't need to make it CW, I could have just edited since I have more than 2k rep on this site. Also, I wasn't sure if it was good idea to introduce a dependency on `timeout` from GNU Coreutils, vs. maybe `sleep 60m && kill "$!" &` inside a shell function after putting a loop in the background. If I get back to this and have an idea I'm happy with, I'll make an edit. – Peter Cordes Jan 15 '23 at 08:26
  • @PeterCordes I know I didn't need. My attitude is summarized in [this comment of mine](https://meta.stackexchange.com/q/11740/355310#comment953392_11741). – Kamil Maciorowski Jan 15 '23 at 08:48
  • `sudo -v` will work even if one is not authorised to run all commands in sudoers. – user3840170 Jan 15 '23 at 11:53
22

How about true? Description: The true utility always returns with an exit code of zero.

If you want something shorter, try id. It returns user identity (and doesn't change the system in any way).

  • 6
    Although I think my answer (`sudo -v`) is the Right Thing, I vote this answer up because `sudo true` would be my second choice. – Kamil Maciorowski Jan 12 '23 at 16:06
  • 1
    The shortest mostly harmless command seems to be `w`. I don't know any command shorter than that. – jy3u4ocy Jan 13 '23 at 05:15
  • 2
    one issue with running any external command (versus the internal switch -v) is that you ARE running that command, with elevated privileges. Also, you must have set up the external command as allowed to be run with sudo. – CGCampbell Jan 13 '23 at 14:39
  • I forgot about "sudo -v". Definitely the Right Thing. Nicely done, @KamilMaciorowski – Aleksey Tsalolikhin Jan 13 '23 at 18:56
  • 2
    The advantage with this solution over `sudo -v` is that if you disabled password prompting completely (by adding `username ALL=(ALL) NOPASSWD: ALL` to `sudo visudo`), then `sudo -v` will ask for your password anyway whereas `sudo true` won't. – Donald Duck Jan 15 '23 at 20:00
7

What about a simple echo or echo -n to suppress the line break?