I am unable to echo the ssh which i looge in using bash script - bash

#!/bin/bash
read -p 'please enter the ssh server name: ' ssh_name
ssh ${ssh_name} 'bash' <<'EOF'
echo ${ssh_name}
exit
EOF

Because you put single quotes around your heredoc limit string it does not expand the variables in place, so it tries to do the variable expansion on the server side, where that variable is not set.
If you want to have the variables expanded locally, just do not use the single quotes around EOF:
read -p 'please enter the ssh server name: ' ssh_name
ssh ${ssh_name} 'bash' <<EOF
echo ${ssh_name}
exit
EOF
This will expand ssh_name on the local side then echo will see the already expanded string on the remote end and echo it.
If you want to pass that variable to the other side, you could make it part of the command you're executing:
read -p 'please enter the ssh server name: ' ssh_name
ssh ${ssh_name} remote_name="$ssh_name" 'bash' <<'EOF'
echo ${remote_name}
exit
EOF
(though you do not have to change the name of the variable, I just did that to highlight that it's available on the remote side).
here is some good reading about heredocs and herestrings.

Becuase $ssh_name is set in the shell you are calling ssh from, and you are trying to echo $ssh_name from within the ssh session itself, where it is not set.
If you move the echo statement to after the EOF or before the ssh statement, then you will find that it works just fine.

Related

Pass along variables via ssh

I'm trying to pass along variables via ssh, and wrote two short testscripts (bash)
This one is to the execute the script on the other side (and it works, at least partially)
I start it with executing: 'mms test alpha one'
#!/bin/bash
sshpass -p (password) ssh hellfire#192.168.0.11 'bash /scripts/mms2 "$#"'
The second script that are executed is:
#!/bin/bash
echo "$#" >/scripts/test1.txt
This script is only for testing if the parameters are are transfered.
So far it creates the text file, but it's empty, so I have no idea if there's wrong with both or only one of the script.
Basically I want to pass a set of variables to the script on the server, these variables can contain spaces.
Anybody have any tips?
I found out by #Gordon Davidsson comment that the $(printf "%q " "$#") could be used to send it as a string, so the remote server didn't interpret the variables as different commands.
My new and working script is:
#!/bin/bash
sshpass -p (password) ssh hellfire#192.168.0.11 "bash /scripts/mms2 $(printf "%q " "$#")"

Passing environment variables over ssh for remote expansion

I am trying to pass an environment variable to my shell script, and then echo out what I passed in. In this example $HOME is an environment variable already set.
./my_script.ksh $HOME
#! /usr/bin/ksh
my_var=${1}
echo "You sent: ${my_var}"
I want my output to be You sent: $HOME but instead it is evaluating it and is producing You Sent: /home/blah/usr
The point of this is that I plan on doing an SSH command that I need to pass $my_var too un-evaluated (aka be $HOME) because $HOME across each server is a different value and for the SSH command I want it to use the value from the server it is SSH'ing too. so was hoping to just pass it in so during the SSH it would evaluate correctly
Here is an example of what I want to have happen. Let's assume $HOME is already set on Server1 and Server2 like:
Server1 $HOME: /home/blah/usr
Server2 $HOME: /home/superblah/newusr
From Server1 execute my_script.ksh $HOME
The script is the same as above with one extra line of:
ssh my_user#Server2 "echo Server got: $my_var"
What my output currently is:
You sent: /home/blah/usr
Server got: /home/blah/usr
What I want is just that ssh command to produce:
Server got: /home/superblah/newusr
Thanks.
You can prevent resolving the variable by wrap it in single quotes
./my_script.ksh '$HOME'
I tried it like this:
[host1]$ echo $HOME
/home/user1
[host1]$ ssh user2#host2 echo '$HOME'
/home/user2
[host1]$
envsubst can be used to substitute strings of the form $HOME or $foo with the value of like-named environment variables. Thus:
#!/usr/bin/env ksh
my_var=$1
my_var_subst=$(envsubst <<<"$my_var")
echo "You sent: ${my_var}"
echo "Interpreted as: ${my_var_subst}"
...will emit:
You sent: $HOME
Interpreted as: /home/superblah/newusr
when invoked with ./myscript '$HOME'.
Note that one needs to be careful when passing values over SSH, as SSH implicitly runs sh -c "$*" with the arguments passed -- concatenating them together with whitespace and evaluating that single string as a shell command. Thus, running your command over ssh may look like:
ssh somehost $'./myscript \'$HOME\''
...or...
ssh somehost "./myscript \$HOME"
...or, to make it easier, let the shell do the escaping work for you:
remote_command=$(printf '%q ' ./myscript '$HOME')
ssh somehost "$remote_command"

ssh bash receive variable from a remote file

I need to read the variable from a remote file over SSH and compare it. But I get a variable in the wrong format. how to do it correctly?
#!/bin/bash
pass='dpassspass'
user='root#10.10.19.18'
IP="10.2.1.41"
path=/sys/variable/serv
#not work## No such file or directory# write=$(sshpass -p $ovhpass ssh -t $user echo "$IP" > $path)
sshpass -p $pass ssh -t $user << EOF
echo "$IP" > $path
EOF
my_var=$(sshpass -p $pass ssh -t $user "cd /sys_ovh; ./serv.bash")
echo mystart-"$my_var"-myend
read=$(sshpass -p $pass ssh -t $user cat $path)
echo start-"$read"-end
echo start-"$IP"-end
if [ "$read" == "$IP" ]; then
echo "run"
fi
output:
Connection to 10.10.19.18 closed.
-myendt-10.2.1.41
Connection to 10.10.19.18 closed.
-endt-10.2.1.41
start-10.2.1.41-end
Where I make a mistake? How to take data from the SSH?
The vars my_var and read are filled with a string ending with '\r', telling echo to go back to the first column. I think this is a problem with your local script. You can correct that with
tr -d "\r" < myfile > myfile2
Your fundamental problem comes from using unquoted here documents for the commands. You should properly understand in which order the shell interprets these contructs.
ssh remote cmd >file
executes cmd remotely, but first redirects the output from the ssh command to the local file.
ssh remote "cmd >’$file'"
The quotes cause the redirection to be part of the remote command line. The variable file is interpreted first, by the local shell, though.
ssh remote 'cmd >"$file"`
The single quotes prevent the local shell from modifying the command before sending it. Thus, he variable interpolation and the redirection are both handled by the remote shell, in this order.
So your commented-out "not work" command could easily be fixed with proper quoting. However, it will be much more elegant and efficient to use a single remote session, and execute all the commands in one go. Mixing the local variable IP with remote variables calls for some rather elaborate escaping, though. A major simplification would be to pass the value on standard input, so that the entire remote script can be single quoted.
#!/bin/bash
pass='dpassspass'
user='root#10.10.19.18'
IP="10.2.1.41"
result=$(echo "$IP" |
sshpass -p "$pass" ssh -t "$user" '
path=/sys/variable/serv
cat > "$path"
cd /sys_ovh
./serv.bash
cat "$path"')
echo mystart-"${result%$'\n'*}"-myend
echo start-"${result#*$'\n'}"-end
echo start-"$IP"-end
if [ "${result#*$'\n'}" == "$IP" ]; then
echo "run"
fi
The output from the remote shell is two lines; we pick it apart by using the shell's prefix and suffix substitution operators.

is it possible to use variables in remote ssh command?

I'd like to execute several commands in sequence on a remote machine, and some of the later commands depend on earlier ones. In the simplest possible example I get this:
ssh my_server "echo this is my_server; abc=2;"
this is my_server
abc=2: Command not found.
ssh my_server "echo this is my_server; abc=2; echo abc is $abc"
abc: undefined variable
For a bit of background info, what I actually want to do is piece together a path and launch a java application:
ssh my_server 'nohup sh -c "( ( echo this is my_server; jabref_exe=`which jabref`; jabref_dir=`dirname $jabref_exe`; java -jar $jabref_dir/../jabref.jar` $1 &/dev/null ) & )"' &
jabref_dir: Undefined variable.
That way, whenever jabref gets updated to a new version on the server, I won't have to manually update the path to the jar file. The jabref executable doesn't take arguments, but launching it with java -jar does, which is why I have to juggle the path a bit.
At the moment I have the list of commands in a separate script file and call
ssh my_server 'nohup sh -c "( ( my_script.sh &/dev/null ) & )"' &
which works, but since the ssh call is already inside one script file it would be nice to have everything together.
In this example
ssh my_server "echo this is my_server; abc=2;"
abc is set on the remote side, so it should be clear why it is not set on your local machine.
In the next example,
ssh my_server "echo this is my_server; abc=2; echo abc is $abc"
your local shell tries to expand $abc in the argument before it is ever sent to the remote host. A slight modification would work as you expected:
ssh my_server 'echo this is my_server; abc=2; echo abc is $abc'
The single quotes prevent your local shell from trying to expand $abc, and so the literal text makes it to the remote host.
To finally address your real question, try this:
jabref_dir=$( ssh my_server 'jabref_exe=$(which jabref); jabref_dir=$(dirname $jabref_exe);
java -jar $jabref_dir/../jabref.jar > /dev/null; echo $jabref_dir' )
This will run the quoted string as a command on your remote server, and output exactly one string: $jabref_dir. That string is captured and stored in a variable on your local host.
With some inspiration from chepner, I now have a solution that works, but only when called from a bash shell or bash script. It doesn't work from tcsh.
ssh my_server "bash -c 'echo this is \$HOSTNAME; abc=2; echo abc is \$abc;'"
Based on this, the code below is a local script which runs jabref on a remote server (although with X-forwarding by default and passwordless authentication the user can't tell it's remote):
#!/bin/bash
if [ -f "$1" ]
then
fname_start=$(echo ${1:0:4})
if [ "$fname_start" = "/tmp" ]
then
scp $1 my_server:$1
ssh my_server "bash -c 'source load_module jdk; source load_module jabref; java_exe=\$(which java); jabref_exe=\$(which jabref); jabref_dir=\$(echo \${jabref_exe%/bin/jabref});eval \$(java -jar \$jabref_dir/jabref.jar $1)'" &
else
echo input argument must be a file in /tmp.
else
echo this function requires 1 argument
fi
and this is the 1-line script load_module, since modulecmd sets environment variables and I couldn't figure out how to do that without sourcing a script.
eval `/path/to/modulecmd bash load $1`;
I also looked at heredocs, inspired by How to use SSH to run a shell script on a remote machine? and http://tldp.org/LDP/abs/html/here-docs.html. The nice part is that it works even from tcsh. I got this working from the command line, but not inside a script. That's probably easy enough to fix, but I've got a solution now so I'm happy :-)
ssh my_server 'bash -s' << EOF
echo this is \$HOSTNAME; abc=2; echo abc is \$abc;
EOF

Send a variable to a remote server with ssh

Im trying to do log into a file (in a remote server lets say /home/test/log.txt) what is stored in $var. Im trying with
ssh test#$192.168.1.35 "echo "var" >> /home/test/log.txt"
y also tried
ssh test#$192.168.1.35 "echo "$var" >> log.txt"
but the both didnt work
any help?
You're using double quotes, so the variable expansion will happen locally. You should use single quotes, so that the command gets sent unaltered.
In the same way as echo '$var' gives $var while echo "$var" displays the contents, this way the server sees $var instead of the contents of the local $var.
So:
ssh test#$192.168.1.35 'echo $var >> /home/test/log.txt'
will create a file on the remote computer, with the value of the remote $var in it.
If you do
ssh test#$192.168.1.35 'echo $var' >> /home/test/log.txt
you get a file on the local computer with the value of the remote $var in it.
If you do
ssh test#$192.168.1.35 "echo $var >> /home/test/log.txt"
it stores the value of your local $var in the file on the remote system.
(Also, if it only involves the remote system, you should probably use a shell script, or maybe cron if you want it to happen automatically.)
Try:
ssh test#192.168.1.35 "echo '$var' >> /home/test/log.txt"
Did you try:
ssh test#$192.168.1.35 'echo "$var" >> /home/test/log.txt'
This should work. Assuming var was set on your computer and not the remote.
Here is the correct way to put some text from a linux machine in an already existing file on another linux machine:
echo 'text' | ssh test#$192.168.1.35 'cat >> /remote_file_path'

Resources