Use sudo without password INSIDE a script
For some reason I need, as user, to run without sudo a script script.sh which needs root privileges to work.
I saw as the only solution to put sudo INSIDE script.sh. Let’s take an example :
script.sh : #!/bin/sh sudo apt-get update
Of course, if I execute this script, I get a prompt asking me for a password. Then I added to my sudoers file (at the end to override everything else) :
user ALL=(ALL:ALL) NOPASSWD:/path/to/script.sh
user ALL=(ALL) NOPASSWD:/path/to/script.sh
(I think I didn’t fully understand the difference) But this doesn’t solve my problem if I don’t use sudo to execute this script :
# ./script.sh [sudo] password for user: # sudo ./script.sh Starts updating.
Well, so I say to myself «Ok, that means that if I have a file refered in sudoers as I did, it will work without prompt only if I call him with sudo, what is not what I want».
So, ok, I create another script script2.sh as following :
script2.sh #!/bin/sh sudo /path/to/script.sh
In fact it works. But I am not truly satisfied of this solution, particularly by the fact that I have to use 2 scripts for every command. This post is then for helping people having this problem and searching for the same solution (I didn’t find a good post on it), and perhaps have better solutions coming from you guys. Feel free to share your ideas ! EDIT 1 : I want to insist on the fact that this «apt-get update» was just an example FAR from whhat my script actually is. My script has a lot of commands (with some cd to root-access-only config files), and the solution can’t be «Well, just do it directly with apt-get». The principle of an example is to help the understanding, not to be excuse to simplify the answer of the general problem.
How do I run a shell script as root (sudo)?
I have a SVN repository server that runs under the repository user. I want to run a script after every post-commit action. I wrote a shell script that runs from the hook after every commit. It needs to be run as root. This is why I used sudo in the script, but it didn’t work. Is there any way to run the script as root?
sudo su echo "password" svn export --force file:///home/repository/trunk/ /home/memarexweb/public_html/devel/ chmod -R 777 /home/memarexweb/public_html/devel/
one option could be to disable password but isnt really a good solution maestric.com/doc/unix/ubuntu_sudo_without_password
5 Answers 5
I was searching around and found this useful solution:
Edit your sudoers file to allow running certain commands without a password.
It’s best to split your post-commit script into two parts, one of which will be run through sudo .
loqman ALL=(root) NOPASSWD: /usr/local/bin/svn-postcommit-export
#!/bin/sh sudo /usr/local/bin/svn-postcommit-export
#!/bin/sh svn export --force file:///home/repository/trunk/ /home/memarexweb/public_html/devel/ chmod -R 777 /home/memarexweb/public_html/devel/
starts a new process, owned by the root user. After that process is terminated or stopped, the next line is executed, again as the user that executes the script.
A possible solution is to run the whole script using sudo, and to give that use sudo rights to exectute the scripts. In order to do that, you need to edit the /etc/sudoers file using the visudo command.
In the last line of your script, you’re changing the mode of /home/memarexweb/public_html/devel/ to 777, so user «repository» should be able to copy files to that directory without root privileges. In that case, you don’t need to use sudo or su.
However, changing the permissions of the directory to 777 is dangerous, as it allows anyone to write to that directory and create or delete files. It would be better to change the ownership of the directory to user «repository» and change the mode to 755. If that’s not feasible, you may be able to add a POSIX ACL allowing «repository» to write to the directory. You can Google «POSIX ACL» for more information, or read the man pages for getfacl and setfacl .
This will not work, the best thing is to put only the requires commands in the shell script. And then setuid the script itself, like this (using root):
Like this, executing this script will give you the permissions of the owner of the script (root).
EDIT: As mentioned in comments, stuid is not allowed for shell script. This solution works for executable files only.
Execute a shell script in current shell with sudo permission
To execute a shell script in current shell, we need to use a period . or a source command. But why does it not work with a sudo permission? I have a script with execute permission called setup.sh . When I use a period, I get this:
$ sudo . ./setup.sh sudo: .: command not found
The source command also produces a similar error. Am I missing out something? What should I do to run the script with sudo permission in the same/current shell?
Despite the excellent answers, I think the problem is almost just a typo. Delete the first period that is by itself.
@beroe you are in error. The problem is not a typo. If setup.sh does not have execute privileges, then you must explicitly interpret it with bash. This can be done as bash setup.sh or source setup.sh or . setup.sh . However, because the latter 2 are bash built-ins, only the 1st form can be used with sudo which requires an executable. You can use sudo which bash and sudo which source and sudo which . to see what sudo will find.
@BrunoBronosky it looked (looks) to me like they are trying to run the first lone dot as a command. Since this specifies the current working directory, which is not a command, it throws that error. If they put ./setup.sh it would be a different story.
@beroe A lone dot is a shell command — specifically, it’s a shell builtin that’s equivalent to the source command (also a builtin).
10 Answers 10
I’m not sure if this breaks any rules but
What you are trying to do is impossible; your current shell is running under your regular user ID (i.e. without root the access sudo would give you), and there is no way to grant it root access. What sudo does is create a new *sub*process that runs as root. The subprocess could be just a regular program (e.g. sudo cp . runs the cp program in a root process) or it could be a root subshell, but it cannot be the current shell.
(It’s actually even more impossible than that, because the sudo command itself is executed as a subprocess of the current shell — meaning that in a sense it’s already too late for it to do anything in the «current shell», because that’s not where it executes.)
I’m not sure why this is the accepted answer when @JaseC’s answer below seems to work for me. sudo bash myscript.sh does exactly what I was looking for, and what the OP seemed to be asking for.
@dalesikkema: sudo bash myscript.sh will run the script in a subshell, rather than the current shell. If that works in your situation, great — but this particular question is about running the script as root in the current shell.
The entire premise of ambiguous because of the inaccurate word choice. «For executing a shell script in current shell, we need to use a period» No, that period doesn’t execute, it sources, inserts, reads, or interprets. Execution implies a disparate PID. So, we are unclear if/why they might care about the PID of their current shell.
I think you are confused about the difference between sourcing and executing a script.
Executing a script means creating a new process, and running the program. The program can be a shell script, or any other type of program. As it is a sub process, any environmental variables changed in the program will not affect the shell.
Sourcing a script can only be used with a bash script (if you are running bash). It effectively types the commands in as if you did them. This is useful as it lets a script change environmental variables in the shell.
Running a script is simple, you just type in the path to the script. . is the current directory. So ./script.sh will execute the file script.sh in the current directory. If the command is a single file (eg script.sh ), it will check all the folders in the PATH variable to find the script. Note that the current directory isn’t in PATH, so you can’t execute a file script.sh in the current directory by running script.sh , you need to run ./script.sh (unless the current directory is in the PATH, eg you can run ls while in the /bin dir).
Sourcing a script doesn’t use the PATH, and just searches for the path. Note that source isn’t a program — otherwise it wouldn’t be able to change environmental variables in the current shell. It is actually a bash built in command. Search /bin and /usr/bin — you won’t find a source program there. So to source a file script.sh in the current directory, you just use source script.sh .
How does sudo interact with this? Well sudo takes a program, and executes it as root. Eg sudo ./script.sh executes script.sh in a sub process but running as root.
What does sudo source ./script.sh do however? Remember source isn’t a program (rather a shell builtin)? Sudo expects a program name though, so it searches for a program named source . It doesn’t find one, and so fails. It isn’t possible to source a file running as root, without creating a new subprocess, as you cannot change the runner of a program (in this case, bash) after it has started.
I’m not sure what you actually wanted, but hopefully this will clear it up for you.
Here is a concrete example. Make the file script.sh in your current directory with the contents:
#!/bin/bash export NEW_VAR="hello" whoami echo "Some text"
Make it executable with chmod +x script.sh .
Now observe what happens with bash:
> ./script.sh david Some text > echo $NEW_VAR > sudo ./script.sh root Some text > echo $NEW_VAR > source script.sh david Some text > echo $NEW_VAR hello > sudo source script.sh sudo: source: command not found
How to make a script run commands as root
I’m new to Ubuntu and bash scripts, but I just made runUpdates.sh and added this to my .profile to run it:
if [ -f "$HOME/bin/runUpdates.sh" ]; then . "$HOME/bin/runUpdates.sh" fi
The problem I’m having is, I want the script to run as if root is running it (because I don’t want to type my sudo password) I found a few places that I should be able to do sudo chown root.root
#!/bin/sh echo "user is $" #check for updates update=`cat /var/lib/update-notifier/updates-available | head -c 2 | tail -c 1`; if [ "$update" = "0" ]; then echo -e "No updates found.\n"; else read -p "Do you wish to install updates? [yN] " yn if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then echo -e 'No\n'; else echo "Please wait. "; echo `sudo apt-get update`; echo `sudo apt-get upgrade`; echo `sudo apt-get dist-upgrade`; echo -e "Done!\n"; fi fi #check for restart restartFile=`/usr/lib/update-notifier/update-motd-reboot-required`; if [ ! -z "$restartFile" ]; then echo "$restartFile"; read -p "Do you wish to REBOOT? [yN] " yn if [ "$yn" != "y" ] && [ "$yn" != "Y" ]; then echo -e 'No\n'; else echo `sudo shutdown -r now`; fi fi
I added the user is to debug, it always outputs my user not root, and prompts for the sudo password (since I’m calling the commands with sudo) or tells me are you root? (if I remove sudo) Also, is there a way to output the update commands stdout in real time, not just one block when they finish? (I also tried with the shebang as #!/bin/bash )