bash list postgresql databases over ssh connection - linux

I am doing some work on a remote Postgresql database.
When I log into the server this command works on bash:
$ psql -c "\l"
Remote login over ssh is possible using:
ssh user#server -C "cd /tmp && su postgres -c psql"
But why doesn't it work from this command?
ssh user#server -C " cd /tmp && su postgres -c psql -c '\l' "
→ bash: l: command not found
This is working, also "psql -l" but I don't understand why I have to use backslash 3 times here?
ssh user#server -C " cd /tmp && su postgres -c 'psql -c \\\l' "

Use several levels of quoting:
ssh user#server -C "cd /tmp && su postgres -c 'psql -c \"\\l\"'"
The double backslash is not strictly necessary since \l is no recognized escape sequence.

Related

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.

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

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)

Multiple commands in sudo over ssh in shell script

My script is as below.
#!/bin/bash
version = 1.1
echo "Enter username"
read UserName
ssh -t $UserName#server bash -c " '
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 -c "cd random; ./randomscrip xx-$version-yy"
'"
But this is not working.
Basically i want to do a ssh to a account. And then runSomeScript
Then do a sudo with user as user1 and then run commands cd random and ./randomscrip (with xx-Version-yy as argument) as the sudo user only.
But the commands inside sudo are not working.
Your quoting is a little careless. You're using double-quotes for the first and third levels of quoting, and the shell can't tell one from the other. Do something like this instead:
sudoScript="cd random; ./randomscrip xx-${version}-yy"
sshScript='
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 bash -c '"'${sudoScript}'"'
'
ssh -t ${UserName}#server "${sshScript}"
But beware that if you embed any single-quotes, it will still go wrong unless you add a layer of shell-quoting.
Finally, remove the spaces around = when you assign to version.

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