A sample script can be as below:
#!/bin/bash sudo su ls /root
When using ./test.sh as the normal user, instead run ls as super user and exit, it switches to root; and when I logout, it executes ls /root as the normal user.
Can anybody tell me about the mechanism about it?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The commands in a script execute one by one, independently. The Script itself as the parent of all commands in the script, is another independent process and the su command does not and can not change it to root: the su command creates a new process with root privileges.
After that su command completes, the parent process, still running as the same user, will execute the rest of the script.
What you want to do is write a wrapper script. The privileged commands goes into the main script, for example ~/main.sh
#!/bin/sh ls /root
The wrapper script calls the main script with root permissions, like this
#!/bin/sh su -c ~/main.sh root
To launch this process you run the wrapper, which in turn launches the main script after switching user to the root user.
This wrapper technique can be used to turn the script into a wrapper around itself. Basically check to see if it is running as root, if not, use “su” to re-launch itself.
$0 is a handy way of making a script refer to itself, and the whoami command can tell us who we are (are we root?)
So the main script with built-in wrapper becomes
#!/bin/sh [ `whoami` = root ] || exec su -c $0 root ls /root
Note the use of exec. It means “replace this program by”, which effectively ends its execution and starts the new program, launched by su, with root, to run from the top. The replacement instance is “root” so it doesn’t execute the right side of the ||
Method 2
Use the following in script.
sudo su <<HERE ls /root HERE
The code between the HERE block will be run as root.
Method 3
Without further arguments su will run the login shell for root. That’s what the first line of your script actually does. When you exit, the login shell closes, su returns and your script continues execution, that is with the second line: ls /root. I think you can simply sudo ls /root to do what you want.
Method 4
Once you fire sudo su a new process with the effective userid (euid=EUID) of super user forked, hence we have new bash running at different process id (pid=PID) associated with the same terminal (tname=TTY).
Explanation
Suppose after firing ps -A | grep bash you have 21460 pts/2 00:00:00 bash as output. Now, when you execute ./test.sh both commands sudo su and ls /root will get spooled to PID 21460. After execution when you have root as active user hit ps -A | grep bash again, you will notice a new bash running on PID say, 21570. Exiting from root bash will kill newly forked bash reverting to user's bash and hence executes the spooled command ls /root before releasing the prompt.
Method 5
If you need a script to run with root privileges, put this in the beginning of it:
if [ ! $(whoami)=”root” ]; then
exec sudo ”$0” ”<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="99bdd9">[email protected]</a>”
echo ”Error: failed to execute sudo” >&2
exit 1
fi
This will re-execute the script with the same parameters, but prefixed with sudo. If the sudo command succesfully starts, it replaces the first script process (because of exec) and only the sudoed version will go forward. If the line after exec sudo gets executed, it means the shell failed to even start sudo and something is really wrong.
If the user is authorized to run the script, sudo may or may not request a password; if a wrong password is entered or the user is not authorized to run the script as root, a standard sudo error message will be displayed.
If succesful, sudo will start the script a second time, now running with root privileges. The if expression will now skip the exec sudo... step and continue into the rest of the script.
So the processes will be:
- parent: the command line session where the user runs the script
- child: initially the shell running the script as the user, but turns into
sudobecause ofexec - grandchild: a shell running the script as root.
Method 6
so here is your typical used case
1.in your bash there are lines which executes without sudo
2.also in your bash there are lines which needs a super user
3.after the execution of lines which required superused preivelage you want
the control back into your script and then go on with usual business
well if thats what you need here is a sample
#!/bin/bash
if [[ $(cat /proc/net/dev |grep br0) ]]; then
echo “Creating bridge”
pwd
cd ../../
cd /proc/sys/net
pwd
modprobe br_netfilter
cd bridge
sudo -s
for f in bridge-nf-*; do echo 0 > $f;done
brctl show
echo “type exit to continue”
cd ../../../../
cd /home/shino/Desktop/openwrt_virt
pwd
fi
just check the line sudo -s thats all you need save this into a bash and try thank me later
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0