Explaining behaviour of sudo bash "$0" "$@";


Login or Register for Dates, Times and to Reply

 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Explaining behaviour of sudo bash "$0" "$@";
# 1  
Explaining behaviour of sudo bash "$0" "$@";

I've found this script part on the stackoverflow:
Code:
if [ $EUID != 0 ]; then
    sudo bash "$0" "$@";
    exit "$?";
 fi


I realized that sudo bash "$0" "$@"; is the only needed for me.


But the strange thing happens when I move this line outside the IF statement:


sudo bash "$0" "$@"; stops the code from running and only blinking dot stays with no progress further.


What happened here and how to make it properly work?

Moderator's Comments:
Mod Comment edit by bakunin: Please use CODE- (not ICODE-) tags for consecutive lines of code. Thank you.

Last edited by bakunin; 11-02-2018 at 01:54 AM..
# 2  
Quote:
Originally Posted by boqsc
Code:
if [ $EUID != 0 ]; then
    sudo bash "$0" "$@";
    exit "$?";
 fi

But the strange thing happens when I move this line outside the IF statement:


sudo bash "$0" "$@"; stops the code from running and only blinking dot stays with no progress further.
Not seeing from here what "$0" (the running programs name) and "$@" (a list of all comand line arguments to the running program) contains or any other parts of the environment you execute the snippet above in i can only speculate. The variable "EUID" is perhaps holding the "effective user ID", so the above reads: if you're not root already issue "sudo ...", which makes sense, because you need sudo to switch to root only if you aren't already root.

So my first guesses would be: either
- you try to use sudo as root and you have some sudo rule in place (or missing) that prevents correct execcution of whatever you try to execute, or
- your environment (especially "$0" and "$@" do not contain what you expect them to contain, maybe because of a switched context: switching to another user may cause settings to change, etc.) or
- There might be a reason for the following exit-statement. Leaving it out may prevent ending of the execution.

But to debug your script i'd have to see it and probably know a bit about your surroundings (OS, shell, version, ....) to do so. As long as you don't provide that you will be on your own.

I hope this helps.

bakunin
This User Gave Thanks to bakunin For This Post:
# 3  
The Shell Version
Code:
vaidas@SATELLITE-L855:~/Desktop$ $SHELL --version
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http:://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

The Operating System and Hardware
Code:
vaidas@SATELLITE-L855:~/Desktop$ hostnamectl
   Static hostname: SATELLITE-L855
         Icon name: computer-laptop
           Chassis: laptop
        Machine ID: c1218e1a57f94029932e84f87d12c20f
           Boot ID: 5704dbfac79f4d66852cb7c22b1abf2f
  Operating System: Ubuntu 18.10
            Kernel: Linux 4.18.0-10-generic
      Architecture: x86-64

The Full Code
Code:
#!/bin/bash

# Checking for Permissions (Some funny reminder that the script requires to be ran with elevated permissions)
sudo -n true 2> /dev/null
if [ $? = 1 ]
  then echo "please run as root"
       echo "haha you have no power here";
       echo "You need to enter password";
  # else echo "Your password is cached or running as Root";
fi

# Execute the Script with elevated permissions
if [ $EUID != 0 ]; then
    sudo bash "$0" "$@";
    exit "$?";
fi


declare commandOutput=$(apt-add-repository multiverse);
if echo "$commandOutput" | grep -q "distribution component is already enabled"; then 
  echo "multiverse repository is already enabled"; 
fi



Last edited by boqsc; 11-02-2018 at 07:32 AM..
# 4  
If you move the sudo outside the if (and therefore run it every time) the code will call itself every time, and call itself, and call itself..........

The exit is necessary because otherwise you will drop through and try to run the remainder of the script as a non-root user. An alternate to the exit might be to drop the current script and re-start it with sudo like this:-
Code:
if [ $EUID != 0 ]; then
    exec sudo bash "$0" "$@";
fi



I hope that this helps,
Robin
This User Gave Thanks to rbatte1 For This Post:
# 5  
Quote:
Originally Posted by rbatte1
If you move the sudo outside the if (and therefore run it every time) the code will call itself every time, and call itself, and call itself..........
fi[/CODE]

I hope that this helps,
Robin

Yep, that's infinite loop, thanks for pointing that out. That might be the case.


The final version looks like this(only added comments that explains bahaviour):
(Any suggestions to make it more readable would be great)
Code:
#!/bin/bash

# Checking if the user who executed this script, needs to type password to execute sudo
sudo -n true 2> /dev/null
if [ $? = 1 ]
  then echo "please run as root"
       echo "haha you have not power here";
       echo "You need to enter password";
  # else echo "Your password is cached or running as Root";
fi

# Checking if this .sh script is ran with sudo
if [ $EUID != 0 ]; then
    #Run this whole .sh script with sudo 
    exec sudo bash "$0" "$@"
fi

declare commandOutput=$(apt-add-repository multiverse);
if echo "$commandOutput" | grep -q "distribution component is already enabled"; then 
  echo "multiverse repository is already enabled"; 
fi


Last edited by boqsc; 11-02-2018 at 09:24 AM..
# 6  
For starters, you almost never need to use $?, a normal if-statement will do. Written this way, you can kind of see the logic. "If not sudo, then ..."

Not sure if it's really a simplification but I'd add >&2, the traditional place for error messages. That way if someone uses this in a stream they can direct data output and error output separately.

You should have an exit after exec, in case the exec fails for whatever reason (i.e. path problems or something).

Then I'd label the section which is always intended to run as root.

Code:
#!/bin/bash

# If we can't run sudo without a password, complain and exit
if ! sudo -n true 2> /dev/null
then
       echo "please run as root" >&2
       echo "haha you have not power here" >&2
       echo "You need to enter password" >&2
       
       # Not sure if you want this or not?  Exits after printing error/warning
       exit 1
fi

# If EUID isn't zero, replace and re-run this script as root using sudo.
if [ "$EUID" -ne 0 ]
then
        exec sudo bash "$0" "$@"
        echo "exec failed" >&2
        exit 1
fi

#########################################
####### The below section always runs as root #########
#########################################

declare commandOutput=$(apt-add-repository multiverse);
if echo "$commandOutput" | grep -q "distribution component is already enabled"; then 
  echo "multiverse repository is already enabled" >&2
fi

The "replace and re-run" bit comes down to how exec really works: It causes the running program to replace itself with what you ask. Whether it succeeds or fails, after an

The >&2's make more likely that these messages get printed to the terminal, where these messages usually belong.


More could probably be done with apt-get, like checking its return value rather than just assuming it operates correctly.

Last edited by Corona688; 11-02-2018 at 01:56 PM..
This User Gave Thanks to Corona688 For This Post:
# 7  
Added curly braces for better readability, your suggestions were very good.


Code:
#!/bin/bash

# If we can't run sudo without a password, complain and exit
if ! (sudo -n true 2> /dev/null)
then
       echo "please run as root" >&2
       echo "haha you have not power here" >&2
       echo "You need to enter password" >&2
fi

# If EUID isn't zero, replace and re-run this script as root using sudo.
if [ "$EUID" -ne 0 ]
then
        exec sudo bash "$0" "$@"
        echo "exec failed" >&2
        exit 1
fi

#########################################
####### The below section always runs as root #########
#########################################

declare commandOutput=$(apt-add-repository multiverse);
if echo "$commandOutput" | grep -q "distribution component is already enabled"; then 
  echo "multiverse repository is already enabled" >&2
fi


Last edited by boqsc; 11-02-2018 at 03:43 PM..
Login or Register for Dates, Times and to Reply

Previous Thread | Next Thread
Thread Tools Search this Thread
Search this Thread:
Advanced Search

Test Your Knowledge in Computers #712
Difficulty: Medium
On a large scale, the ability to treat instructions as data is what makes assemblers, compilers, linkers, loaders, and other automated programming tools possible.
True or False?

9 More Discussions You Might Find Interesting

1. AIX

Apache 2.4 directory cannot display "Last modified" "Size" "Description"

Hi 2 all, i have had AIX 7.2 :/# /usr/IBMAHS/bin/apachectl -v Server version: Apache/2.4.12 (Unix) Server built: May 25 2015 04:58:27 :/#:/# /usr/IBMAHS/bin/apachectl -M Loaded Modules: core_module (static) so_module (static) http_module (static) mpm_worker_module (static) ... (3 Replies)
Discussion started by: penchev
3 Replies

2. Shell Programming and Scripting

Bash script - Print an ascii file using specific font "Latin Modern Mono 12" "regular" "9"

Hello. System : opensuse leap 42.3 I have a bash script that build a text file. I would like the last command doing : print_cmd -o page-left=43 -o page-right=22 -o page-top=28 -o page-bottom=43 -o font=LatinModernMono12:regular:9 some_file.txt where : print_cmd ::= some printing... (1 Reply)
Discussion started by: jcdole
1 Replies

3. Shell Programming and Scripting

Expect: spawn id exp5 not open while executing "expect "$" { send "sudo su -\r" }"

Hi All, i am trying to ssh to a remote machine and execute certain command to remote machine through script. i am able to ssh but after its getting hung at the promt and after pressing ctrl +d i am gettin the out put as expect: spawn id exp5 not open while executing "expect "$" {... (3 Replies)
Discussion started by: Siddharth shivh
3 Replies

4. UNIX for Dummies Questions & Answers

Using "mailx" command to read "to" and "cc" email addreses from input file

How to use "mailx" command to do e-mail reading the input file containing email address, where column 1 has name and column 2 containing “To” e-mail address and column 3 contains “cc” e-mail address to include with same email. Sample input file, email.txt Below is an sample code where... (2 Replies)
Discussion started by: asjaiswal
2 Replies

5. UNIX for Dummies Questions & Answers

"Help with bash script" - "License Server and Patch Updates"

Hi All, I'm completely new to bash scripting and still learning my way through albeit vey slowly. I need to know where to insert my server names', my ip address numbers through out the script alas to no avail. I'm also searching on how to save .sh (bash shell) script properly.... (25 Replies)
Discussion started by: profileuser
25 Replies

6. Solaris

The slices "usr", "opt", "tmp" disappeared!!! Help please.

The system don't boot. on the screen appears following: press enter to maintenance (or type CTRL-D to continue)...I checked with format command. ... the slices "0-root","1-swap","2-backup" exist. ...the slises "3-var","6-usr" -unassigned. :( (16 Replies)
Discussion started by: wolfgang
16 Replies

7. Shell Programming and Scripting

awk command to replace ";" with "|" and ""|" at diferent places in line of file

Hi, I have line in input file as below: 3G_CENTRAL;INDONESIA_(M)_TELKOMSEL;SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL My expected output for line in the file must be : "1-Radon1-cMOC_deg"|"LDIndex"|"3G_CENTRAL|INDONESIA_(M)_TELKOMSEL"|LAST|"SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL" Can someone... (7 Replies)
Discussion started by: shis100
7 Replies

8. Shell Programming and Scripting

cat $como_file | awk /^~/'{print $1","$2","$3","$4}' | sed -e 's/~//g'

hi All, cat file_name | awk /^~/'{print $1","$2","$3","$4}' | sed -e 's/~//g' Can this be done by using sed or awk alone (4 Replies)
Discussion started by: harshakusam
4 Replies

9. UNIX for Dummies Questions & Answers

Explain the line "mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'`"

Hi Friends, Can any of you explain me about the below line of code? mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'` Im not able to understand, what exactly it is doing :confused: Any help would be useful for me. Lokesha (4 Replies)
Discussion started by: Lokesha
4 Replies

Featured Tech Videos