29

I want to write an automated post-installation script in Bash (called post-install.sh, for instance). The script will automatically add and update repositories, install and update packages, edit config files, etc.

Now, if I execute this script, for instance with sudo post-install.sh, will I only be prompted for a sudo password once, or will I need to enter the sudo password on each invocation of a command inside the script, that needs sudo permission? In other words, do the commands inside the bash script 'inherit' the execution permissions, so to speak?

And, if they indeed do, is there still a possibility that the sudo permissions will time out (if, for instance, a particular command takes long enough to exceed the sudo timeout)? Or will the initial sudo password entrance last for the complete duration of whole script?

  • 4
    You may be interested to check out some tools specifically designed for this task. 3 common ones are: Puppet, chef, and ancible. – spuder Feb 16 '14 at 17:24
  • @spuder, and for larger-scale, enterprise-level architecture and security of your configuration management, you can use CFEngine 3. (Not for the faint of heart, nor for one-off commands.) – Wildcard Feb 10 '16 at 1:28
38

Q#1: Will I only be prompted for a sudo password once, or will I need to enter the sudo password on each invocation of a command inside the script, that needs sudo permission?

Yes, once, for the duration of the running of your script.

NOTE: When you provide credentials to sudo, the authentication is typically good for 5 minutes within the shell where you typed the password. Additionally any child processes that get executed from this shell, or any script that runs in the shell (your case) will also run at the elevated level.

Q#2: is there still a possibility that the sudo permissions will time out (if, for instance, a particular command takes long enough to exceed the sudo timeout)? Or will the initial sudo password entrance last for the complete duration of whole script?

No they will not timeout within the script. Only if you interactively were typing them within the shell where the credentials were provided. Every time sudo is executed within this shell, the timeout is reset. But in your case they credentials will remain so long as the script is executing and running commands from within it.

excerpt from sudo man page

This limit is policy-specific; the default password prompt timeout for the sudoers security policy is 5 minutes.

  • 1
    The answer to Q1 is "No, you will not be prompted again." – dannysauer Feb 16 '14 at 17:42
  • @dannysauer - read his Q again. I'm saying Yes to being prompted for password only once! – slm Feb 16 '14 at 22:35
  • The question says "is it a or b", and just saying "yes" didn't make it clear if it was "yes, a" or "yes, b". Just trying to clarify things for future readers. :D – dannysauer Feb 17 '14 at 3:02
  • @dannysauer - see update. – slm Feb 17 '14 at 3:05
  • 1
    This new question would be this: stackoverflow.com/questions/3522341/… . sudo -u $(logname) <command> should work. – Gauthier Feb 13 '15 at 10:17
17

bash and all of its child processes will run with superuser permissions. So you will not need to re-enter a password for commands in your bash script.

The sudo timeout only applies to (later) separate invocation of sudo. It would not affect your already running bash process, or any of its descendants.

3

These answers are all probably correct. However, this is not the generally-used way (as far as I am aware) to create bash scripts that require sudo permissions. Generally, at the top of the script you assume it hasn't been run with sudo permissions and instead call sudo -v yourself (which will prompt the user for their password) to 'set up' a sudo 'session'. You can either echo some explanatory text before the prompt, or override sudo's own prompt with the -p switch, to let the user know you need sudo access for some commands.

Then, in your script you should be fine to call sudo on the commands that require it (and only those commands that require it) without further password requests. If you think a certain group of commands that run together in your script (regardless of their own use of sudo) will extend beyond the sudo timeout, you can call sudo -v in the middle in order to issue a kind of 'keep-alive' the sudo 'session'.

If the sudo 'session' does happen to expire during the script, the user will simply be asked for their password the next time you issue a sudo command in the script.

  • 1
    Say that one of the steps of the script is building a whole new linux kernel, which can take say two hours. Keeping the session alive could be a challenge, how'd you deal with that? – Gauthier Feb 13 '15 at 10:20
  • You can't. But next time you call sudo -v it'll ask the user for their password again. Not the worst issue in my opinion. Maybe to be helpful, making the user aware of the mechanism might be handy. – alexrussell Feb 18 '15 at 9:39
  • The inverse of this is to require the user to call the script with sudo per the other answers, and then sudo -u $SUDO_USER to make all non-root requiring commands run un-elevated. Sadly it adds more code, but is the only reliable way to perform root things in a long running process. – dragon788 Nov 17 '17 at 15:31
  • I guess I should clarify, another other way to do this would be to call sudo once at the beginning of the script to put a temporary file into /etc/sudoers.d using visudo -c -f /tmp/tempsudoers to ensure the file is valid before copying it into place, and then remove that file once done (using a trap on exit/error to ensure the escalation can't be abused). The most safe and secure implementation would only allow your user to run the specific commands in your script with specific arguments without a password using NOPASSWD by storing each command/arguments into an array to build the file. – dragon788 Nov 22 '17 at 16:51
  • Somewhat late coming back to @Gauthier here but it would appear that I was wrong when I said you can't keep a sudo session alive if a given single task takes longer than the timeout. I came across this technique the other day in Mathias Bynens's dotfiles repo: while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & - github.com/mathiasbynens/dotfiles/blob/master/.macos#L13 – alexrussell Nov 27 '17 at 16: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.