diff --git a/tools/install.sh b/tools/install.sh index d3be1ace4..b7498fa64 100755 --- a/tools/install.sh +++ b/tools/install.sh @@ -56,6 +56,28 @@ command_exists() { command -v "$@" >/dev/null 2>&1 } +user_can_sudo() { + # The following command has 3 parts: + # + # 1. Run `sudo` with `-v`. Does the following: + # • with privilege: asks for a password immediately. + # • without privilege: exits with error code 1 and prints the message: + # Sorry, user may not run sudo on + # + # 2. Pass `-S` to `sudo` to tell it to get the password from stdin + # instead of from a tty, and pipe `true` to `sudo`, since it doesn't + # output anything. This will make sudo exit with error code 1 and print + # the message: + # sudo: no password was provided + # + # 3. Check for the words "may not run sudo" in the output to really tell + # whether the user has privileges or not. For that we have to make sure + # to run `sudo` in the default locale (with `LANG=`) so that the message + # stays consistent regardless of the user's locale. + # + true | LANG= sudo -v -S 2>&1 | grep -q "may not run sudo" +} + # The [ -t 1 ] check only works when the function is not called from # a subshell (like in `$(...)` or `(...)`, so this hack redefines the # function at the top level to always return false when stdout is not @@ -360,8 +382,16 @@ EOF echo "Changing your shell to $zsh..." - # Check if user has sudo privileges and run `chsh` or `sudo chsh` - if LANG= sudo -l -U "$USER" 2>/dev/null | grep -q "is not allowed to run"; then + # Check if user has sudo privileges to run `chsh` with or without `sudo` + # + # This allows the call to succeed without password on systems where the + # user does not have a password but does have sudo privileges, like in + # Google Cloud Shell. + # + # On systems that don't have a user with passwordless sudo, the user will + # be prompted for the password either way, so this shouldn't cause any issues. + # + if user_can_sudo; then chsh -s "$zsh" "$USER" # run chsh normally else sudo -k chsh -s "$zsh" "$USER" # -k forces the password prompt