How to do ssh in a bash script with lot of commands? - linux

I tried to run the following command in a bash script but only till ./install.sh rereplica is called . Rest of the commands are not called at all.
ssh $node2user#$node2 "cd /tmp; tar -xf $mmCS.tar; cd $mmCS; ./install.sh csreplica; ./install.sh keepalived $vip low;./install.sh haproxy $node1:8080 $node2:8080 $vip:8080; ./install.sh confmongo $dbPath"

You can give ssh a script on standard input:
ssh $node2user#$node2 < my_script.sh

If I have to do execute a complex script using SSH, I usually write a script locally, copy it on the target machine with SSH and then execute it there:
scp foo.sh $node2user#$node2:
ssh $node2user#$node2 "bash ./foo.sh"
That way, I can debug the script simply by invoking it with bash -x and I can use the full power of BASH.
Alternatively, you can use
ssh $node2user#$node2 "set +x; cd /tmp; ..."

Related

Running linux commands inside bash script throws permission denied error

We have linux script in our environment which does ssh to remote machine with a common user and copies a script from base machine to remote machine through scp.
Script Test_RunFromBaseVM.sh
#!/bin/bash
machines = $1
for machine in $machines
do
ssh -tt -o StrictHostKeyChecking=no ${machine} "mkdir -p -m 700 ~/test"
scp -r bin conf.d ${machine}:~/test
ssh -tt ${machine} "cd ~/test; sudo bash bin/RunFromRemotevm.sh"
done
Script RunFromRemotevm.sh
#!/bin/bash
echo "$(date +"%Y/%m/%d %H:%M:%S")"
Before running Test_RunFromBaseVM.sh script base vm we run below two commands.
eval $(ssh-agent)
ssh-add
Executing ./Test_RunFromBaseVM.sh "<list_of_machine_hosts>" getting permission denied error.
[remote-vm-1] bin/RunFromRemotevm.sh:line 2: /bin/date: Permission denied
any clue or insights on this error will be of great help.
Thanks.
I believe the problem is the presence of the NOEXEC: tag in the sudoers file, corresponding to the user (or group) that's executing the "cd ~/test; sudo bash bin/RunFromRemotevm.sh" command. This causes any further execv(), execve() and fexecve() calls to be refused, in this case it's /bin/date.
The solution is obviously remove the NOEXEC: from the main /etc/sudoers file or some file under /etc/sudoers.d, whereever is this defined.

How to sudo run a local script over ssh

I try to sudo run a local script over ssh,
ssh $HOST < script.sh
and I tried
ssh -t $HOST "sudo -s && bash" < script.sh
Actually, I searched a lot in google, find some similar questions, however, I don't find a solution which can sudo run a local script.
Reading the error message of
$ ssh -t $HOST "sudo -s && bash" < script.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
makes it pretty clear what's going wrong here.
You can't use the ssh parameter -t (which sudo needs to ask for a password) whilst redirecting your script to bash's stdin of your remote session.
If it is acceptable for you, you could transfer the local script via scp to your remote machine and then execute the script without the need of I/O redirection:
scp script.sh $HOST:/tmp/ && ssh -t $HOST "sudo -s bash /tmp/script.sh"
Another way to fix your issue is to use sudo in non-interactive mode -n but for this you need to set NOPASSWD within the remote machine's sudoers file for the executing user. Then you can use
ssh $HOST "sudo -n -s bash" < script.sh
To make Edward Itrich's answer more scalable and geared towards frequent use, you can set up a system where you only run a one line script that can be quickly ported to any host, file or command in the following manner:
Create a script in your Scripts directory if you have one by changing the name you want the script to be (I use this format frequently to change 1 word for my script name and create the file, set permissions and open for editing):
newscript="runlocalscriptonremotehost.sh"
touch $newscript && chmod +x $newscript && nano $newscript
In nano fill out the script as follows placing the directory and name information of the script you want to run remotely in the variable lines of runlocalscriptonremotehost.sh(only need to edit lines 1-3):
HOSTtoCONTROL="sudoadmin#192.168.0.254"
PATHtoSCRIPT="/home/username/Scripts/"
SCRIPTname="scripttorunremotely.sh"
scp $PATHtoSCRIPT$SCRIPTname $HOSTtoCONTROL:/tmp/ && ssh -t $HOSTtoCONTROL "sudo -s bash /tmp/$SCRIPTname"
Then just run:
sh ./runlocalscriptonremotehost.sh
Keep runlocalscriptonremotehost.sh open in a tabbed text editor for quick updating, go ahead and create a bash alias for the script and you have yourself an app-ified version of this frequently used operation.
First of all divide your objective in 2 parts. 1) ssh to the host. 2) run the command you want as sudo. After you are certain that you can 1) access the host and 2) have sudo privileges then you can combine the two commands with &&. What x_cmd && y_cmd does is that the y_cmd gets executed after x_cmd has exited successfully.

Undefined variable in shell script by using ssh

I use shell script to run R program as following:
host_list="server#com" Directory="/home/program/" ssh -f "$host_list" 'cd $Directory && nohup Rscript L_1.R> L_1_sh.txt'
But it always says
Directory: Undefined variable.
SSH does not propagate all your environment variables. You're only setting on the environment of the local client ssh program, not on the server side. As a hack, just stick it inside the commands that ssh is running remotely, instead of the pre-command environment setup.
host_list="server#com" ssh -f "$host_list" 'Directory="/home/program/"; cd "$Directory" && nohup ...'
Here's a simpler version of the command that will let you test it without depending on your particular program setup.
ssh localhost Dir="/etc"; echo Dir is "$Dir"; cd "$Dir" && pwd && ps
I'm not sure but maybe you can try those:
In bash single quotes '' does not repace variables Manual
Try to use ${Directory} or change the variable name (maybe is
reserved)

How to cd on remote server via SSH bash script?

I have a bash script I'm using to connect to a remote server via ssh. That works, however I want the script to immediately pass the command of cd /some/dir after connecting. That doesn't seem to be working. Here's my code:
#!/bin/bash
echo "SSHing.."
ssh -i ~/.ssh/some-site.pem xxx#yyy.com
cd /some/dir
read
How can I have the cd command be executed right after SSH connection is established?
There are two easy ways to execute commands via SSH from inside the script:
1) ssh user#host 'command'
2)
ssh user#host <<<EOF
command1
command2
<...>
commandn
EOF
Normally you'd just edit your ~/.profile on the remote machine.
If that is not an option, you could do something like this:
ssh -t theserver.com 'cd /some/dir && bash -i'
You can use the following command
ssh user#watevr <the_cmd_to_be_executed>
You can try this :
ssh abc#hostname :/pathto/specific directory

logging on a remote machine

Is it possible to login to a particular folder of a remote machine, through shell script:
instead of ssh and then cd. Can I do it in one command?
Is it possible to copy a file on two different folders of a remote machine through scp in one go?
You can pass the cp command to ssh as follows:
ssh user#host "cp /path/to/folder1/file /path/to/folder2"
or combine with cd:
ssh user#host "cd /path/to/folder1; cp file /path/to/folder2"
I think there is no real solution to this. You can try ssh user#host bash -c "cd /tmp; bash -i" if your shell is bash. That will look a little like it could work, but you will quickly discover it's not really working. (Try to invoke an editor such as vi and you will see.)
You can also put cd /tmp into the ~/.bashrc on the remote end. This way, ssh user#host does what you ask for. But I guess you want to be able to go to different directories, so this won't fly either.
I think the best approach is to make it convenient to enter the cd command, e.g. using aliases. Then it's less typing.
The cleanest way for your first question is Expect:
#!/usr/local/bin/expect
spawn ssh user#host
expect -re {\$ $} ;# adjust to suit your prompt
send "cd some/dir\r"
interact
I'm unclear about your 2nd question: do you have 2 remote files that you want to copy to your local machine, or do you want to copy a file from one remote dir to another remote dir?
scp user#host:/path/to/file1 user#host:/path/to/file2 .
ssh user#host "cp /path/to/file1 /path/to/folder2/"

Resources