I'm currently working on a bash script that installs and sets up various programs on a stock Linux system (currently, Ubuntu). Because it installs programs and copies a number of files to various folders that require elevated privileges, I've already done the standard "I need elevated privileges"-and-exit.
However, I would like, if possible, to be able to prompt the user for their sudo password and elevate the script's privileges automatically if the user doesn't run the script command with sudo (such as launching it from the GUI file manager), without the user having to restart the script.
As this is designed to run on stock Linux installs, any option that modifies the system won't work for my purposes. All options need to be contained to the script itself.
Is this possible within Bash? If so, what's the best (secure, yet concise) way to do this?
-
See also on AU: How to execute a script as super user first checking the user and getting pass from askpass if not super userMichael Mrozek– Michael Mrozek2012年01月10日 19:56:40 +00:00Commented Jan 10, 2012 at 19:56
-
@MichaelMrozek - Ah, the joys of having so many niche sites while trying to minimize fragmentation. And you know, the link you gave never once came up for me while searching Google.Shauna– Shauna2012年01月10日 20:19:50 +00:00Commented Jan 10, 2012 at 20:19
-
Also see How to enter password only once in a bash script needing sudo, Request root privilege from within a script,Create a sudo user in script with no prompt for password..., sudo with password in one command line?, How to prompt user for sudo password?, etcuser56041– user560412018年03月30日 17:53:38 +00:00Commented Mar 30, 2018 at 17:53
-
@jww you do realize that nearly all of those links were asked about 4 years after this one, right?Shauna– Shauna2018年04月06日 20:58:35 +00:00Commented Apr 6, 2018 at 20:58
-
1@Shauna - I'm guessing you have solved the problem by now. The links are for future visitors.user56041– user560412018年04月06日 21:04:37 +00:00Commented Apr 6, 2018 at 21:04
5 Answers 5
I run sudo
directly from the script:
if [ $EUID != 0 ]; then
sudo "0ドル" "$@"
exit $?
fi
-
3This will throw an error if
EUID
is not set for any reason – better quote it:[ "$EUID" != 0 ]
dessert– dessert2020年03月03日 08:11:08 +00:00Commented Mar 3, 2020 at 8:11 -
-
It seems that something like
sudo "$BASH_SOURCE" $(printf '%q ' "$@")
is a safer alternative, according to this comment.Sebastian Simon– Sebastian Simon2020年06月17日 00:25:10 +00:00Commented Jun 17, 2020 at 0:25 -
@SebastianSimon but it's bash-specific, while the script in the answer is POSIX-compliantxeruf– xeruf2021年03月31日 06:20:26 +00:00Commented Mar 31, 2021 at 6:20
-
@SebastianSimon Do you know what
"0ドル" "$@"
actually gets wrong? The comment you linked claims it fails on whitespace and glob characters due to splicing an array into a string, but that is not true in my testing, and I thought the whole point of the special handling bash does with"$@"
(rather than$@
or$*
) is that it specifically handles properly expanding into a series of arguments with exactly the same contents, (regardless of whitespace within any of the arguments).Ben– Ben2021年06月28日 23:05:14 +00:00Commented Jun 28, 2021 at 23:05
Add this as the first line of the script:
[ "$UID" -eq 0 ] || exec sudo bash "0ドル" "$@"
Change sudo
to gksu
or gksudo
if you prefer a graphical prompt.
-
Is there a way to do this on Debian, where there seems to be no sudo command?wrongusername– wrongusername2015年07月25日 18:23:14 +00:00Commented Jul 25, 2015 at 18:23
-
@wrongusername install
sudo
, it's much better than usingsu
. But if you really want, probablyexec su -c "0ドル" "$@"
Kevin– Kevin2015年07月27日 17:23:04 +00:00Commented Jul 27, 2015 at 17:23 -
This also won't inherit any environment variables from the current shell; use
exec sudo -E bash "0ドル" "$@"
to get that behavior.gntskn– gntskn2021年03月14日 18:06:37 +00:00Commented Mar 14, 2021 at 18:06
I suggest:
#!/bin/bash
if (($EUID != 0)); then
if [[ -t 1 ]]; then
sudo "0ドル" "$@"
else
exec 1>output_file
gksu "0ドル $@"
fi
exit
fi
# some example stuff
ls -l /root
echo "app: 0ドル"
for f; do
echo ">$f<"
done
-
What does
if [[ -t 1 ]];
check for?Shauna– Shauna2012年01月10日 20:05:21 +00:00Commented Jan 10, 2012 at 20:05 -
Ah, ok. I figured it had something to do with terminal vs GUI, but wasn't sure what the if statement itself was checking.Shauna– Shauna2012年01月10日 20:24:43 +00:00Commented Jan 10, 2012 at 20:24
An example script that I don't mind sharing::
#!/bin/bash
[ "$UID" -eq 0 ] || exec sudo "0ドル" "$@" && echo -n "sudo bash what: "
read WHAT
sudo $WHAT
-
[ "$UID" -eq 0 ] || exec sudo "0ドル" "$@"
-- Looks like a really efficient one liner! Nice!groovenectar– groovenectar2018年12月17日 18:41:38 +00:00Commented Dec 17, 2018 at 18:41 -
Would it make sense to use Effective UID here,
$EUDI
, or always the same outcome? E.g.,[[ "$EUID" -eq 0 ]] || exec sudo "0ドル" "$@"
groovenectar– groovenectar2018年12月17日 19:04:03 +00:00Commented Dec 17, 2018 at 19:04
I use visudo
to edit the sudoers
file as follows:
- In the line with your user, add this next to the username:
then save.ALL=(ALL) NOPASSWD: ALL
- When that user
he will be logged on as root without entering a password.sudo su -