Execute single command in shell script without sudo - bash

I have a simple shell script that is run with sudo as most of the script requires it, yet one of the commands in the script is a Homebrew install, which cannot be executed with sudo..
So, my question is when executing a shell script with sudo how do I execute sub commands as the current user and then continue the remainder of the script with sudo.
Prompting the user to enter his password again is not really practical as the script takes really long to execute and would require waiting 5-10 min for the prompt.

The easiest way is to run the subcommand via sudo from within the script. The user id to run with can be obtained by $SUDO_USER (look at the output of sudo env):
sudo -u $SUDO_USER ./exec_as_normal_user.sh

Instantiate the shell using
sudo -u $USER_NAME bash
and execute the shell script by calling,
./program.sh

Related

Bash dropping out of sudo in a script

I need to execute an install script using sudo, but towards the end of the script, the script needs to drop out of sudo and continue as the regular user.
Example:
sudo ./install.sh
script runs and does what it needs to as root
su myscriptuser
service myscript start
Basically, the service myscript start needs to be run by the regular user, not by root.
su myscriptuser starts another shell in the name of myscriptuser and waits until it exits. Then it proceeds to run service myscript start in the name of root again.
What you need instead of the last 2 commands is sudo:
sudo -u myscriptuser service myscript start

Remove sudo permissions for one command

this is probably a really simple question. I apologize if it is a duplicate.
I want to know how to remove sudo permissions for one particular command. I've created a script that installs a bunch of .deb packages and it needs sudo to do that, but one command in it needs to run without sudo permissions, so how would I do that? I'm using Ubuntu and this is a bash script.
I'm calling my script: ROS_install
Here is part of the script:
sudo dpkg -i /home/forklift/Desktop/ROS/ros-hydro-laser-proc_0.1.3-0precise-20131015-2054-+0000_amd64.deb
sudo dpkg -i /home/forklift/Desktop/ROS/ros-hydro-urg-c_1.0.403-0precise-20131010-0128-+0000_amd64.deb
sudo rosdep init
sleep 2
rosdep update
The command "rosdep update" needs to be run without sudo permissions. I assumed that it was already, but I get a warning every time I run the script, and thus get locked out of the command after installation.
Rather than give the entire script elevated privileges, just give them to the actual commands that need them. That is, rather than
$ sudo my_script
modify my_script to use sudo only on those commands that need it. For instance, if this is your script:
command1
command2
command3
command4
command5
and command3 is the non-sudo command, modify your script to read
sudo command1
sudo command2
command3
sudo command4
sudo command5
In the process, think about whether command1 actually needs to run with sudo, or it it can run just as well without. In that way, you should be able to greatly reduce the number of commands that actually need to be run with sudo in your script.
If your command is running with full privileges, it also has the privilege to demote its own privileges, for good or for the duration of one command, by running su.
touch /privileged
su -c 'cp /privileged /tmp/not' nobody
I assume you are calling your script like:
sudo script.sh
And you do not want all of the commands within the script to run as root.
If your script is like:
apt-get install perl
apt-get install python
mv trash /home/user/
And you only want to run the first two commands as root you can specify a specific user for the third like:
su -c "mv trash /home/user/" user
Where user is the username you want to run the command as.
This will allow you to make a single sudo call at the parent level when you call the script.
If you don't want the username hardcoded, you can use a command like logname to get the username of the user that you are logged in as.
Just adding to the other answers, you can do this:
su -c "command" $SUDO_USER
Which will execute the command as the actual user who typed the sudo command
That's very useful when you are making scripts that require sudo to install something and write something in the user's $HOME

How do I run a shell script with administrator privileges through AppleScript without prompting for a password?

I want to have my AppleScript application run a Python script with sudo, but I don't want the application to prompt the user for a password (our users do not have sudo privileges).
The Python script has been added to the /etc/sudoers file appropriately (ALL ALL=NOPASSWD: /path/to/script.py). In the terminal, I can do (as a regular, non-privileged user):
$ sudo ./script.py
and it runs perfectly well. But in AppleScript when you try to do:
do shell script "sudo ./script.py"
You of course get the "sudo: no tty present and no askpass program specified" error. But if you change it to:
do shell script "./script.py" with administrator privileges
AppleScript insists on presenting a popup window to ask for the password. I have also tried passing a null password to sudo with a pipe:
do shell script "echo '' | sudo -S ./script.py"
but that also does not work. (I think it tries to run sudo individually first and then pass the command through, which won't work because the user doesn't have sudo privileges!)
I need a solution where AppleScript will run the Python script with sudo. I would prefer the script stays unreadable and un-executable by average users for security reasons, and is only executed through the AppleScript. (I know that, hypothetically, the users could call sudo script.py and it would run, but that's assuming they even know about sudoers; I'm trying to keep it as secure as possible while still usable).
I'm still pretty new to AppleScript, so any help would be greatly appreciated! Thanks!
When I added ALL ALL=NOPASSWD: /Users/myusername/a to sudoers and ran echo $'#!/bin/bash\nsay $(ls ~root|head -n1)'>~/a;chmod +x ~/a, do shell script "sudo ~/a" ran the script as root without requiring a password.
I'm guessing the problem is that you specified the path like do shell script "sudo ./script.py". Try to use do shell script "sudo ~/script.py" instead. The default working directory is for do shell script is / and not ~/.

How to first login using sudo and then run rest of Unix Shell script

I am working on Automating deployment script for which I have to run all steps as sudo user, when I try to sudo first in my script like below it prompt me for password and then rest of script doesn't execute, when i exit sudo then only it executes.
"sudo -u username bash"
Please help me how to achieve this or I have to first login using sudo and then only run my script ?
You can instead just run the script as sudo.
sudo sh ./script.sh
This way the entire script would run as a sudo user, and it would prompt only for once.
If you want to still use sudo -u you can use it like this, instead of:
sudo -u username bash
You can do:
sudo -u username sh ./script.sh

Changing to root user inside shell script

I have a shell script which needs non-root user account to run certain commands and then change the user to root to run the rest of the script. I am using SUSE11.
I have used expect to automate the password prompt. But when I use
spawn su -
and the command gets executed, the prompt comes back with root and the rest of the script does not execute.
Eg.
< non-root commands>
spawn su -
<root commands>
But after su - the prompt returns back with user as root.
How to execute the remaining of the script.
The sudo -S option does not help as it does not run sudo -S ifconfig command which I need to find the IP address of the machine.
I have already gone through these links but could not find a solution:
Change script directory to user's homedir in a shell script
Changing unix user in a shell script
sudo will work here but you need to change your script a little bit:
$ cat 1.sh
id
sudo -s <<EOF
echo Now i am root
id
echo "yes!"
EOF
$ bash 1.sh
uid=1000(igor) gid=1000(igor) groups=1000(igor),29(audio),44(video),124(fuse)
Now i am root
uid=0(root) gid=0(root) groups=0(root)
yes!
You need to run your command in <<EOF block and give the block to sudo.
If you want, you can use su, of course. But you need to run it using expect/pexpect that will enter password for you.
But even in case you could manage to enter the password automatically (or switch it off) this construction would not work:
user-command
su
root-command
In this case root-command will be executed with user, not with root privileges, because it will be executed after su will be finished (su opens a new shell, not changes uid of the current shell). You can use the same trick here of course:
su -c 'sh -s' <<EOF
# list of root commands
EOF
But now you have the same as with sudo.
There is an easy way to do it without a second script. Just put this at the start of your file:
if [ "$(whoami)" != "root" ]
then
sudo su -s "$0"
exit
fi
Then it will automatically run itself as root. Of course, this assumes that you can sudo su without having to provide a password - but that's out of scope of this answer; see one of the other questions about using sudo in shell scripts for how to do that.
Short version: create a block to enclose all commands to be run as root.
For example, I created a script to run a command from a root subdirectory, the segment goes like this:
sudo su - <<EOF
cd rootSubFolder/subfolder
./commandtoRun
EOF
Also, note that if you are changing to "root" user inside a shell script like below one, few Linux utilities like awk for data extraction or defining even a simple shell variable etc will behave weirdly.
To resolve this simply quote the whole document by using <<'EOF' in place of EOF.
sudo -i <<'EOF'
ls
echo "I am root now"
EOF
The easiest way to do that would be to create a least two scripts.
The first one should call the second one with root privileges. So every command you execute in the second script would be executed as root.
For example:
runasroot.sh
sudo su-c'./scriptname.sh'
scriptname.sh
apt-get install mysql-server-5.5
or whatever you need.

Resources