I have an SSH command that is able to use variables defined in the script.
Example:
b="03-18-2022"
I'm able to pass this in to my ssh call and use it.
However I want to be able to define $b when I run the script: bash file.sh -b 03-18-2022
.. When I try doing this the SSH command cannot recognize the variable
CODE:
Getting the variable from the input:
while getopts ":b:" arg; do
case "${arg}" in
b) b="$OPTARG";;
esac
done
echo "Locally using begin: $b
printf -v b_str %q "$b"
ssh myserver "bash -s $b_str" << 'EOF'
b=$1
echo "remotely using $b"
The last echo works when the variable is defined in the script but not when it is passed in from the command line
Related
The below shell script snippet prints the environmental variable outside of sshpass, but not inside.
#!/bin/bash
[[ $1 = '' ]] && BRANCH="develop" || BRANCH=$1
echo $DESTINATION_FOLDER // prints from env
sshpass -p $PASSWORD ssh -o StrictHostKeyChecking=no $SERVER <<-'ENDSSH'
echo $DESTINATION_FOLDER // doesn't print anything, output: empty
exit
ENDSSH
Am I missing any option to be passed to the interactive mode with sshpass so that it can read environmental variables defined in the local system?
I suggest to replace 'ENDSSH' with ENDSSH to allow bash to interpret the variable in your here-document.
See: https://en.wikipedia.org/wiki/Here_document#Unix_shells
Below is an example of a ssh script using a heredoc (the actual script is more complex). Is it possible to use both local and remote variables within an SSH heredoc or command?
FILE_NAME is set on the local server to be used on the remote server. REMOTE_PID is set when running on the remote server to be used on local server. FILE_NAME is recognised in script. REMOTE_PID is not set.
If EOF is changed to 'EOF', then REMOTE_PID is set and `FILE_NAME is not. I don't understand why this is?
Is there a way in which both REMOTE_PID and FILE_NAME can be recognised?
Version 2 of bash being used. The default remote login is cshell, local script is to be bash.
FILE_NAME=/example/pdi.dat
ssh user#host bash << EOF
# run script with output...
REMOTE_PID=$(cat $FILE_NAME)
echo $REMOTE_PID
EOF
echo $REMOTE_PID
You need to escape the $ sign if you don't want the variable to be expanded:
$ x=abc
$ bash <<EOF
> x=def
> echo $x # This expands x before sending it to bash. Bash will see only "echo abc"
> echo \$x # This lets bash perform the expansion. Bash will see "echo $x"
> EOF
abc
def
So in your case:
ssh user#host bash << EOF
# run script with output...
REMOTE_PID=$(cat $FILE_NAME)
echo \$REMOTE_PID
EOF
Or alternatively you can just use a herestring with single quotes:
$ x=abc
$ bash <<< '
> x=def
> echo $x # This will not expand, because we are inside single quotes
> '
def
remote_user_name=user
instance_ip=127.0.0.1
external=$(ls /home/)
ssh -T -i ${private_key} -l ${remote_user_name} ${instance_ip} << END
internal=\$(ls /home/)
echo "\${internal}"
echo "${external}"
END
This is my sample Bash Script example.sh:
#!/bin/bash
# Reading arguments and mapping to respective variables
while [ $# -gt 0 ]; do
if [[ $1 == *"--"* ]]; then
v="${1/--/}"
declare $v
fi
shift
done
# Printing command line arguments through the mapped variables
echo ${arg1}
echo ${arg2}
Now if in terminal I run the bash script as follows:
$ bash ./example.sh "--arg1=value1" "--arg2=value2"
I get the correct output like:
value1
value2
Perfect! Meaning I was able to use the values passed to the arguments --arg1 and --arg2 using the variables ${arg1} and ${arg2} inside the bash script.
I am happy with this solution for now as it serves my purpose, but, anyone can suggest any better solution to use named command line arguments in bash scripts?
You can just use environment variables:
#!/bin/bash
echo "$arg1"
echo "$arg2"
No parsing needed. From the command line:
$ arg1=foo arg2=bar ./example.sh
foo
bar
There's even a shell option to let you put the assignments anywhere, not just before the command:
$ set -k
$ ./example.sh arg1=hello arg2=world
hello
world
How do I make $1 and $2 variables to the remote shell through ssh. Below is the sample,
#!/bin/bash
user_name="${1}"
shift
user_password="${1}"
shift
tenant_name="${1}"
realscript="/IDM_ARTIFACTS/reset.sh"
ssh -qT oracle#slc05pzz.us.oracle.com bash -c "'echo $user_name'" < "$realscript"
I am able to echo $user_name but not able to access it in $realscript.
Cant call using HERE tags or single quotes'' as the script doesn't have straight forward commands.
What other options do I have? Please help
I do not have your script, so I put a test one on my remote host:
$ realscript=/home/jack/show_params.sh
$ second="second one"
$ ssh TEST cat ${realscript}
#!/bin/bash
nParams=$#
echo There are ${nParams} parameters.
for (( ii=1; ii<=${nParams}; ii++ )); do
echo "$1"
shift
done
$ ssh TEST 'bash '${realscript}' "first one" '\'${second}\'
There are 2 parameters.
first one
second one
The quoting gets a bit weird, but you can pass into parameters variables with spaces.
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.