How to store output of sudo -S su -c <user> <command> to any variable - linux

I am trying to execute the following command but the output is not coming as required.
var=$(echo "<password>"|sudo -S su -l <user> -c "<command>")
Please help if anyone can?
Expected Result:
var=$(echo ""|sudo -S su -l -c "pwd")
echo $var /home/bhushan
$:
Actual Result:
echo $var
$:

You can use backticks
var=`sudo -S su -l -c ""`
or the $(command) syntax
var=$(sudo -S su -l -c "")
(keep in mind though that sudo -S su -l -c "" doesn't output anything so $var will be empty)

You can workaround it by storing the output of the command into a file, then change its permission so that all users will see it and in a following command load it from the file:
sudo -S "<command> > /tmp/sudocmd.out && chmod 644 /tmp/sudocmd.out"
var=$(cat /tmp/sudocmd.out)

Related

How to check if user has sudo privileges inside the bash script?

I would like to check if the user has sudo privileges. This is an approximate example of what I am trying to do. I am trying to get this to work across the following os: centos, ubuntu, arch.
if userIsSudo; then
chsh -s $(which zsh)
fi
Try with this:
$ sudo -v &> /dev/null && echo "Sudoer" || echo "Not sudoer"
Also, IDK how secure will be searching for his membership in the sudo group, i.e:
$ groups "$(id -un)" \
| grep -q ' sudo ' \
&& echo In sudo group \
|| echo Not in sudo group
Or:
$ getent group sudo \
| grep -qE "(:|,)$(id -un)(,|$)" \
&& echo in sudo group \
|| echo not in sudo group
sudo -l will display the commands that the user can run with sudo privileges. If there are no commands that can be run, sudo -l will return an error code and so you could try:
sudo -l && chsh -s $(which zsh)
Usually when you run an script you want to know if end it well or you got an error or what kind of error you got if there was any.
This is a more elaborated snippet, sudoer-script.sh:
## Define error code
E_NOTROOT=87 # Non-root exit error.
## check if is sudoer
if ! $(sudo -l &> /dev/null); then
echo 'Error: root privileges are needed to run this script'
exit $E_NOTROOT
fi
## do something else you
## means it was successfully executed
exit 0
Now you can reuse your script, pipe it or concatenate with other commands
sudoer-script.sh && ls
## in a script
if $(sudoer-script.sh); then
echo 'success'
fi
## capture error
stderr=$(./sudoer-script.sh 2>&1 >/dev/null)
echo $stderr
As a function:
is_sudoer() {
## Define error code
E_NOTROOT=87 # Non-root exit error.
## check if is sudoer
if ! $(sudo -l &> /dev/null); then
echo 'Error: root privileges are needed to run this script'
return $E_NOTROOT
fi
return 0
}
if is_sudoer; then
echo "Sudoer"
else
echo "Not sudoer"
fi

Nested bash command quote issues

I have an app that sends commands to bash like so:
/bin/bash -c "<command goes here>"
This works great but I have hit a problem with a slightly more complicated command. This command grabs a tar from an SSH server, shows a progress bar with pv and then saves it to a local user's directory.
su -c "ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar" localuser
Running this command on the command line manually works great but I can't for the life of me work out how to pass this as an argument to /bin/bash/.
I have tried:
/bin/bash -c "su -c "ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar" localuser"
And various combinations using different syntax but I am just guessing as I don't really understand why it's not working.
I have broken it down to a simpler example and realised it works if inner command uses single quote like this simple example that gets the home path:
bash -c "su -c 'cd ~ && pwd' localuser"
but trying that on larger command causes it to fail:
/bin/bash -c "su -c 'ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar' localuser"
It says no passwd entry for user /home so the command is getting broken up I guess buy the nested single quotes but im not sure how to fix this.
I tried putting double quotes outside the single quotes:
/bin/bash -c "su -c 'ssh -p 1234 remoteuser#123.123.123.123 "'cd /home/ && tar -cf - remoteuser/'" | pv > /home/staging/localuser/staging.tar' localuser"
But then it says it can't find the directory. It looks like I just need to tweak the command a bit but I can't figure it out, can anyone help?
It is a matter of quoting in the right way. There is more than one way to do this. I find double quotes easier to work with for this case:
echo "su -c \"ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar\" localuser"
Prints:
su -c "ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar" localuser
Which I think is what you are looking for. That is, escaping with \" any double quotes inside the outer double quotes. So try:
/bin/bash -c "su -c \"ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar\" localuser"
This is where here-documents come in handy:
bash <<'END'
su -c "ssh -p 1234 remoteuser#123.123.123.123 'cd /home/ && tar -cf - remoteuser/' | pv > /home/staging/localuser/staging.tar" localuser
END
Note the -c option has been removed: bash will read the commands from stdin.

Sudo and backticks?

When running the following command:
sudo sh -c "sed s/sda1-uuid/`blkid -s UUID -o value /dev/sda1`/ -i /etc/crypttab"
the result is wrong, because blkid -s UUID -o value /dev/sda1 is not executed with root privileges.
What am I doing wrong?
By trying the suggestions in the comments, the following command is now working as expected:
sudo sh -c 'sed s/sda1-uuid/$(blkid -s UUID -o value /dev/sda1)/ -i /etc/crypttab'

how to escape quote in ssh command

I want to install a the pub key for user test using the command below.
I know the root password and the user test does not exist.
cat test.pub | ssh root#127.0.0.1 "useradd -m test || su - test -c 'umask 077; mkdir /home/test/.ssh; cat >> /home/test/.ssh/authorized_keys'"
But the command does not work.
Error: Creating mailbox file: File exists
The problem is useradd -m test. I delete user test by userdel test && rm -rf /home/test. It should be userdel -r test.
The command below works:
cat test.pub | ssh root#127.0.0.1 "useradd -m test && su - test -c 'umask 077; mkdir /home/test/.ssh; cat >> /home/test/.ssh/authorized_keys'"

change user in linux script

User x run a script. Now I want to change the user in the script to User y.
#!/bin/sh
whoami
echo password | su y
whoami
But I get this:
x
su: must be run from a terminal
x
Thanks for your help.
This is working for me inside a bash script:
whoami;
sudo su $user << BASH
whoami;
BASH
Su cannot be ran in a Bash script. You can use sudo -u <user> <command> && however.
you can do:
su - $USER -l -m -c $CMD
-l provide an environment similar to the login env
-m preserves the current environment
-c runs the command
e.g. I use this to run nohup commands also
su - $USER -l -m -c "nohup $RUN_CMD > "$LOG" 2>&1 >> /dev/null&"

Resources