Both sudo -s and sudo su makes user root. is there any some difference?
With sudo -s
with sudo su
From man sudo:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password
database entry. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is
specified, an interactive shell is executed.
So -s keeps your current shell (bash in this case), while omitting it uses the shell of the root user (sh). Myself, I prefer sudo -Es to keep both my shell and environment variables.
Related
This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 1 year ago.
I need to run a script which needs to be run with root privileges remotely. Therefore I add "sudo su" command at the start of the script. However the ssh just login the remote server and stuck at sudo su command, and it does not continue from next line in the script.
server.sh
sudo -s
sudo apt-get update
sudo apt-get upgrade
client.sh
scp -i "$key.pem" server.sh "$dns:/tmp"
ssh -tt -i "$key.pem" $dns "bash /tmp/server.sh"
server.sh and client.sh is at the same local directory. When I run ./client.sh, server.sh which is run remotely stuck at first line and does not continue with "sudo apt-get update" command. What is the reason of this behavious and is there a solution?
When you run the command sudo -s you change the user and the rest of the script is lost because it is in a new shell.
Remove the line sudo -s and try running the script again.
Note: it is important to remember that the user running sudo must be in the /etc/sudoers file with the username ALL=(ALL) NOPASSWD:ALL permissions.
sudo -s with no command starts a new, interactive shell. The following commands won't execute until it exits. See man sudo.
If you are already running apt-get via sudo, and sudo does not require a password, why do you need the sudo -s?
You can use
ssh user#ip '[command]'
to run [command] on the remote host. If you have a user with root privileges (aka. sudo) and if you can use commands without passwords (NOPASSWD:[command,list or ALL]) this is the safest way i can suggest however if you want the script to run on the remote server and triggered by the local computer you can always
ssh user#ip 'sudo /bin/bash /home/[user]/server.sh'
This would work as well. You can also use "scp" command to copy the script and then delete it with ssh again for automated one-script approach.
When attempting to execute sudo in a docker container using alpine 3.8 I get the following output.
I am logged into the container using docker exec -i -t MYIMAGE /bin/bash
bash-4.4$ whoami
payara
bash-4.4$ sudo -s
bash-4.4$ whoami
payara
bash-4.4$ su root
su: incorrect password
bash-4.4$
My docker file contains the following user related commands to try and setup a user specifically for payara. I want sudo to work correctly though, if possible.
DockerFile
FROM "alpine:latest"
ENV LANG C.UTF-8
ENV http_proxy 'http://u:p#160.48.234.129:80'
ENV https_proxy 'http://u:p#160.48.234.129:80'
RUN apk add --no-cache bash gawk sed grep bc coreutils git openssh-client libarchive libarchive-tools busybox-suid sudo
RUN addgroup -S payara && adduser -S -G payara payara
RUN echo "payara ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
# CHANGE TO PAYARA USER
USER payara
... rest of setup.
From man sudo:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password database entry.
You have neither SHELL variable set, nor correct (interactive) default shell set in /etc/passwd for user payara. This is because you are creating a system user (-S) - this user has a default shell /bin/false (which just exits with exit code 1 - you may check with echo $? after unsuccessfull sudo -s).
You may overcome this in different ways:
a) specify the SHELL variable:
bash-4.4$ SHELL=/bin/bash sudo -s
bed662af470d:~#
b) use su, which will use the default root's shell:
bash-4.4$ sudo su -
bed662af470d:~#
c) just run the required privileged commands with sudo directly, without spawning an interactive shell.
I have a script that copies files between servers. I am using the lsof command to make sure that the file is not being written to before being moved. The user running the script and the user writing to the file are different, so I need to sudo to the file owner. Here is the relevant line in the sudoers file :
userA ALL=(userB:userB) NOPASSWD: ALL
In the main script (ran as userA), I have tried calling sudo then the subscript containing the lsof command:
sudo su - userB -c 'source ./getOpenFiles.sh'
getOpenFiles.sh has this one line:
#!/bin/bash
lsofResult=$(/usr/sbin/lsof "${sourcePath}")
I have also tried calling the subscript:
source ./getOpenFiles.sh
Then have the first line of the subscript be the sudo:
#!/bin/bash
sudo su - banjobs
lsofResult=$(/usr/sbin/lsof "${sourcePath}")`.
Neither solution is working.
What you actually want is something more like:
lsofResult=$(sudo -u banjobs lsof "${sourcePath}")
Let's go over why the other approaches didn't work one-at-a-time:
Running source under sudo su -c
sudo su - userB -c 'source ./getOpenFiles.sh'
...uses sudo to run su, which runs sh -c 'source ./getOpenFiles.sh'. This doesn't work for several independent reasons:
sh -c 'source ./getOpenFiles.sh' relies on the source keyword being available in /bin/sh, but this is a bash extension.
Even if your /bin/sh is provided by bash, this still defeats the purpose of using source: By starting a new copy of /bin/sh and sourcing your script into that, you're defining the variable in the new shell, not in the original shell that started sudo su.
Running sudo su - banjobs, followed by lsofResult=$(/usr/sbin/lsof "${sourcePath}")
...means that lsofResult=$(...) doesn't run until after sudo su - banjobs exits. If sudo su - banjobs has exited, then the current user isn't banjobs any more, so the sudo command has no effect whatsoever on the lsof.
Demonstrating, in detail, how to test this (for folks who don't have a banoff or userB account on their system):
# place relevant contents in sourceme.bash
# switching from lsof to fuser for this test since OS X lsof does not accept a directory
# as an argument.
cat >sourceme.bash <<'EOF'
lsofResult=$(sudo -u root fuser "${sourcePath}" 2>&1)
EOF
# set sourcePath in the outer shell
sourcePath=$PWD
source sourceme.bash
declare -p lsofResult
...yields, on my system, output akin to the following:
declare -- lsofResult="/Users/chaduffy/tmp: 17165c 17686c 17687c 17688c 17689c 17690c"
...showing that the code in question did in fact work as described.
This question already has answers here:
How to fix 'sudo: no tty present and no askpass program specified' error?
(30 answers)
Closed 6 years ago.
I have a shell script which creates a user and executes another script as that user
sudo useradd -m devops
sudo passwd devops
sudo adduser devops sudo
su - devops -c "sh /path/to/myscript.sh"
This script creates the user,sets the password and adds user to sudo group as expected.
myscript.sh contains commands which uses sudo previlages. (sudo apt-get update, sudo apt-get install software-properties-common etc.). And other commands like ssh-keygen,curl and wget.
All commands except the one's with sudo are executed correctly and producing results as excepted.
But commands having sudo fails by giving the error "no tty present and no askpass program specified"
Why does this happen in this case and how can I overcome this?
I have seen similiar questions but will be thankful if I get a clear explanation in this context,thank you.
Try to replace this:
su - devops -c "sh /path/to/myscript.sh"
with this:
sudo -u devops -H sh -c "sh /path/to/myscript.sh"
The -c option of su doesn't support interactive mode:
-c, --command COMMAND Specify a command that will be invoked by
the shell using its -c.
The executed command will have no controlling terminal. This option
cannot be used to execute interractive programs which need a
controlling TTY.
(man su)
By the way, I wouldn't use sudo within a script everywhere. The script might simply require root permissions. Within the script you might drop privileges where necessary by means of the above-mentioned sudo command.
While installing QT, I met this command:
sudo -s chmod u+x QtSdk-offline-linux-x86_64-v1.2.1.run
I wonder what -s means here.And it seems similar here:
sudo -s ./QtSdk-offline-linux-x86_64-v1.2.1.run -style cleanlooks
sudo -s runs a shell with root privileges
"The -s (shell) option runs the shell specified by the SHELL
environment variable if it is set or the shell as specified in
passwd(5). If a command is specified, it is passed to the shell for
execution. Otherwise, an interactive shell is executed."
From here.
As mentioned in the comments above, check out the man info:
Type man sudo to your command line.
Find -s in the list of commands for a good explanation.