1

I have a bash script which install bunch of opensource libraries (example :- opencv,octave,ff-mpeg and SDL etc.,) and I need sudo privilege to access most of the file paths. As far as I know, by default sudo session will last for 5 mins after that i need to re-enter my password to extend sudo access.

In my script some installation may take more than 30 mins, so I need to re-enter my password again and again. If I run the script with sudo privilege, it install everything without promoting for password, but the problem is, it runs the script as root user and expand all the relative paths inside my script according to root instead of normal user who run the script.

for example, retaliative path ~/.bashrc expands to /root/.bashrc instead of /home/actual_user/.bashrc

2 Answers 2

2

If HOME variable is set, ~ in your example expands according to the variable. Normally the variable is exported to the environment.

From man 8 sudo:

-E

The -E (preserve environment) option indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the -E option is specified and the user does not have permission to preserve the environment.

So sudo -E your_script is a way to have ~/.bashrc in the script expanded to /home/actual_user/.bashrc. Note environment variables other than HOME will also be preserved.

Alternatively you can preserve just this one variable with

sudo HOME="$HOME" your_script

This works out of the box in my Debian but please see man 8 sudo and man 5 sudoers to learn how variables may be restricted.

Another alternative is to set the variable at the beginning of your script. Its value may be hardcoded or passed as a command line argument.

Be aware that running your entire script with sudo has disadvantages:

  1. Any bug will bite you with elevated permissions.
  2. If your script needs to know the actual user's $HOME in order to create files or directories therein, then the objects created will be owned by root. This may be a problem later on, when you want to use them without sudo. The general premise is everything in your home directory is yours (possible exceptions are, well, exceptions).

Maybe you can isolate the elevated part of the script, so it runs in its entirety after you provide the password once, then returns to the non-elevated parent script to mangle with /home/actual_user. Like this:

#!/bin/bash

foo1  # runs normally

sudo bash <<EOF
bar1  # runs as if with sudo
bar2  # runs as if with sudo
EOF

foo2  # runs normally
2
  • Thanks for mentioning the disadvantage of running script with sudo. I have edited my ~/.bashrc path in my script to /home/$USER/.bashrc and it works fine. If your script needs to know the actual user's $HOME in order to create files or directories therein, then the objects created will be owned by root. As you mentioned above, all my libraries are installed with root ownership.
    – Vencat
    Commented Dec 17, 2018 at 9:26
  • Maybe you can isolate the elevated part of the script, so it runs in its entirety after you provide the password once, then returns to the non-elevated parent script to mangle with /home/actual_user. As you suggested above, I tried to segregate the part of my script that require root privilege, but the problem is, installation of opensource libraries takes 2 to 3 hours and I need configure linker directories /etc/ld.so.conf.d/mytool.conf, ~/.bashrc and pkg_config etc., so it's not possible for someone to wait for 3 hours to enter the password.
    – Vencat
    Commented Dec 17, 2018 at 9:29
2

in bash, tilde expand to the variable HOME, just put this command in the top of script:

default_user=$(logname 2>/dev/null || echo ${SUDO_USER:-${USER}})
HOME="/home/${default_user}"

using this all tildes in the script will expand to the home user directory that running the script by calling sudo, so you can just run sudo ./your-script.sh

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .