I am trying to write a script to login to several remote servers and execute a script in each server.
However, I'd like to pass a variable through ssh. Something like this:
var="/home/dir/"
ssh -T $mchname <<'ENDSSH'
$var"run_script" < input > output &
ENDSSH
This naive try does not work ($var is simply null). What would be the correct syntax? Thanks in advance.
Remove the quotes from around ENDSSH. They prevent expansion of variables within the here document.
Try this:
var="/home/dir/"
ssh -T $mchname VAR=$var 'bash -s'<<'ENDSSH'
$VAR"run_script" < input > output &
ENDSSH
Related
I sometimes use ssh to run multiple commands on a remote host like this:
ssh my_user#my_host "command1; command2"
utilizing double quotes to send both commands to the remote machine.
Now I would like to access an environment variable in one or both of the commands.
Here is a simplified example that illustrates what I have tried:
ssh my_user#my_host "echo $USER; echo $HOSTNAME"
This echos my user/hostname on the local machine, whereas I would like to see the names on the remote machine instead.
Using single quotes I can achieve what I want for a single command as follows:
ssh my_user#my_host echo '$USER'
but I don't get the behavior I want when I use single quotes inside the double quotes like this:
ssh my_user#my_host "echo '$USER'; echo '$HOSTNAME'"
How can I get the behavior I want with both commands being executed from a single ssh commmand?
(Please note that my actual commands are more complicated... I do realize that I can get both variables in a single command for my toy example as below, but this does not solve my real problem):
ssh my_user#my_host echo '$USER' '$HOST'
Just escape the $ using \.
ssh my_user#my_host "echo \$USER; echo \$HOSTNAME"
You can put the entire command to be run in single quotes, like so:
ssh my_user#my_host 'echo $USER; echo $HOSTNAME'
That will prevent your shell from substituting the environment variable values before passing them to the remote machine, but when they get to the remote machine they are unquoted so they get evaluated there.
Thanks to Guilherme Richter. That solution works! I will accept it once the 5 minutes has passed. I wanted to document that in the meantime I found another solution that avoids the double quotes instead of avoiding the single quotes by escaping the semicolon:
ssh user#host echo '$USER' \; echo '$USER'
I have a script I want to run on remote via ssh. It checks if there is a process running and should try to kill it, if it exists. Now, my code looks like this:
ssh my_prod_env << ENDSSH
...
pid=$(pgrep -f "node my_app.js")
echo $pid
# kill process with $pid
...
exit
ENDSSH
The problem lies here: I cannot capture output of pgrep command in variable. I tried with $(), backticks, pipe then read and maybe other approaches, but all without success.
I would like to do it all in one ssh session.
Now I am thinking the output of command goes to the output stream I cannot access in my script. I might be wrong, though.
Either way, help will be appreciated.
Ok, after you provided in comments more info what you want, I believe this is the correct answer to your question:
ssh my_prod_env -t 'pgrep -f "node my_app.js"'
This will call the command and leave you logged on the server
This is what fixes the thing - "escaping" the ENDSSH tag.
ssh my_prod_env << /ENDSSH
...
# capture output of remote commands in remote variables
...
ENDSSH
Problem was that my vars were local and I was trying to capture output of remote commands in them.
This question/answer helped me realize what is going on: How to assign local variable with a remote command result in bash script?
So, my question could be marked as duplicate or something similar, I guess.
I am passing variable from one shell script to another which is being executed on another remote server.
Script 1
echo "Identification No."
read id
export id
ssh atul#10.95.276.286 'bash -s' < data_file.sh
Script 2
echo "ID is ---- "$id
cd /abc/xyz/data/
cat data_abcxyz.txt|grep '|$id|'|wc -l
By this way I am not able to get any output even the id is also null in the second script.
I have also tried
ssh atul#10.95.276.286 'bash -s' < data_file.sh "$id"
But got no output.
Any help on this is greatly appreciated. I am using unix AIX.
export on one host is absolutely not going to affect an entirely different host... it doesn't even affect another shell running on the current host.
Your second attempt is better and might even work if your script were checking for positional arguments but it isn't. (It might not even work in that case as I'm not at all sure that the command line argument would make it through to the script through ssh and bash -s.
You might be able to do something more like:
ssh atul#10.95.276.286 "bash -s $id" < data_file.sh
to pass the argument to the remote bash directly but your script would still need to use positional arguments and not expecting named variables to already exist.
Exporting won't have any effects on the environment of remote scripts.
You can set up a remote script's environment by specifying the env variables on the command line before the actual command, which you can btw use for local commands too.
ssh atul#10.95.276.286 "id=$id bash -s" < data_file.sh
If you pass "$id" this way:
ssh atul#10.95.276.286 'bash -s' < data_file.sh "$id"
It'll be your script's first parameter, AKA "$1" and you'll be able to access it from your script that way.
Note that '|$id|' in your "Script 2" will be interpreted as a literal string, since you're using single quotes.
In one of my bash script I want to read and use the variable value from other script which is on remote machine.
How should I go ahead to resolve this. Any related info would be helpful.
Thanks in advance!
How about this (which is code I cannot currently test myself):
text=$(ssh yourname#yourmachine 'grep uploadRate= /root/yourscript')
It assumes that the value of the variable is contained in one line. The variable text now contains you variable assignment, presumably something like
uploadRate=1MB/s
There are several ways to convert the text/code into a real variable assignment in your current script, like evaluating the string or using grep. I would recommend
uploadRate=${text#*=}
to just remove the part up and including the =.
Edit: One more caveat to mention is that this only works if the original assignment does not contain variable references itself like in
uploadRate=1000*${kB}/s
ssh user#machine 'command'
will print the standard output of the remote command.
I would tell two ways at least:
1) You can simply redirect output to a file from remote server to your system with scp command...It would work for you.Then your script on your machine should read that file as an argument...
script on your machine:
read -t 50 -p "Waiting for argumet: " $1
It waits for output from remote machine,
Then you can
sshpass -p<password> scp user#host:/Path/to/file /path/to/script/
What you need to do:
You should tell the script from your machine, that the output from scp command is the argument($1)
2)Run script from your machine:
#!/bin/bash
script='
#Your commands
'
sshpass -p<password> ssh user#host $script
And you have also another ways to run script to do sth with remote machine.
I am taking input from user for a shell script, and want to run this script on different servers. I tried to pass the variables as follows:
USERNAME=****
HOSTS="**** ***** *****"
FOO=$1
BAR=$2
for HOSTNAME in ${HOSTS} ; do
ssh $USERNAME#$HOSTNAME bash << EOF
#script using FOO and BAR variables goes here
EOF
Login to the server is successful but variables are not being passed.
How can handle this situation without creating a temp file?
Do it like this:
VAR="something"
ssh $USERNAME#$HOSTNAME "
VAR=$VAR
export VAR
"
Possible Duplicate of this SuperUser Answer.
In a nutshell: You can pass values with a command similar to the following:
ssh username#machine VAR=value cmd cmdargs