LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Assigning several variables at once in single ssh session (https://www.linuxquestions.org/questions/programming-9/assigning-several-variables-at-once-in-single-ssh-session-4175479717/)

keif 10-05-2013 11:55 AM

Assigning several variables at once in single ssh session
 
Hello all,

I currently have a script that does four separate ssh sessions to get variable information from a remote host:

Code:

WDvr=`ssh root@$STORE ls -l /usr1/vision/bin/wd | awk '{print $5}'`
OSfr=`ssh root@$STORE uname -a | awk '{print $3}' | cut -c 1-6`
Ship=`ssh root@$STORE printf '%s\n' /usr1/vision/bin/REL=SHIP* | cut -c 26-36`
Tapp=`ssh root@$STORE ls -l /usr1/vision/bin/tapp | awk '{print $5}'`

Is there a way I can just ssh in once and then set all the variables one at a time?

Thanks, Keith

druuna 10-05-2013 12:53 PM

Have a look at this:
Code:

#!/bin/bash

allVars=( $( ssh root@$STORE \
  ls -l /usr1/vision/bin/wd | awk '{print $5}' ; \
  uname -a | awk '{print $3}' | cut -c 1-6` ; \
  printf '%s\n' /usr1/vision/bin/REL=SHIP* | cut -c 26-36 ; \
  ls -l /usr1/vision/bin/tapp | awk '{print $5}' ) )

WDvr="${allVars[0]}"
OSfr="${allVars[1]}"
Ship="${allVars[2]}"
Tapp="${allVars[3]}"

echo $WDvr
echo $OSfr
echo $Ship
echo $Tapp

This uses allVars as an array. allVars=( .... )

I do assume in the above example that each separate command produces 1 entry. This doesn't account for anything going wrong with any of the 4 commands......

EDIT: Added the previous missing Tapp part (sorry 'bout that).

keif 10-05-2013 02:11 PM

Quote:

Originally Posted by druuna (Post 5040588)

EDIT: Added the previous missing Tapp part (sorry 'bout that).

No need to be sorry. I'm grateful for the help!

I changed my commands to something simple so I can start from scratch (See the various 'pwd' commands below).

I found that the first variable is being set on the remote host. But the following three are being set on my local machine:

Code:

#!/bin/sh
for STORE in `cat /home/techs/upg-11.38.05.00/test.txt`
do
        allVars=( $( ssh root@$STORE \
                pwd ; \
                pwd ; \
                pwd ; \
                pwd ) )
                        OSfr="${allVars[0]}"
                        Ship="${allVars[1]}"
                        WDvr="${allVars[2]}"
                        Tapp="${allVars[3]}"
echo $OSfr
echo $Ship
echo $WDvr
echo $Tapp
done

Here's the output of the script:

Code:

[techs@ts-01 scripts]$ ./allVars-script.sh
/root
/home/techs/scripts
/home/techs/scripts
/home/techs/scripts

The first 'pwd' comes back with 'root' (As it should per the remote host).

The next 3 'pwd' commands comes back with '/home/techs/scripts', which is where I am working on my local box. So after executing the first command correctly, the script is leaving the remote host and executing the latter 3 locally.

Is there anything off hand that you can see that might be resulting in this action? Thanks again for getting me this far. I'll keep hammering at it. Keith

colucix 10-05-2013 02:20 PM

The problems are the semicolon after the pwd commands. If you write
Code:

ssh root@$STORE pwd; pwd; pwd; pwd;
the shell interprets this line as 4 different commands and only the first one is actually executed on the remote host. You have to protect the semi-colons from the local shell by means of double quotes, so that the whole command line is passed to the remote host as a single string:
Code:

ssh root@$STORE "pwd; pwd; pwd; pwd;"
Hope this helps.

keif 10-05-2013 02:55 PM

Quote:

Originally Posted by colucix (Post 5040614)
The problems are the semicolon after the pwd commands.

Thank you for taking the time to explain. That most certainly solves the local host issue.

I'm currently working no another problem with this script, so if anyone has some insight to this please feel free to share. Here it goes:

I added my first command to the script (Replacing the 'pwd' test). The good news is it's setting the first variable correctly. The bad news is, it's setting the second variable with part of the first command:

Code:

#!/bin/sh
for STORE in `cat /home/techs/upg-11.38.05.00/test.txt`
do
       
        allVars=( $( ssh root@$STORE \
                "du -b /usr1/vision/bin/wd | awk '{print $1}'; \
                pwd ; \
                pwd ; \
                pwd" ) )
                        WDvr="${allVars[0]}"
                        OSfr="${allVars[1]}"
                        Ship="${allVars[2]}"
                        Tapp="${allVars[3]}"
echo "WD - $WDvr"
echo "OS - $OSfr"
echo "SP - $Ship"
echo "TP - $Tapp"

Here's the output:

Code:

WD - 78740                # Correct
OS - /usr1/vision/bin/wd  # Incorrect: it's assigning part of the first command to $OSfr
SP - /root
TP - /root

I'm still trying different things, but any help would be appreciated. Thanks, Keith

colucix 10-06-2013 12:34 AM

Again a problem of protecting the remote command from the local shell. This time is the $1 in the awk command that must be escaped, otherwise it results in a null string (if you don't pass arguments to the script) and awk simply prints out the whole string, which is
Code:

78740 /usr1/vision/bin/wd
This is the reason why two elements (space separated) are assigned to the array. To avoid that you can escape the $ sign using a backslash:
Code:

"du -b /usr1/vision/bin/wd | awk '{print \$1}'; \
Ciao.

druuna 10-06-2013 03:19 AM

@keif: I was focusing too much on the array part and completely overlooked the details of the ssh command. As already explained by colucix, you need to take make sure commands aren't interpreted locally.

These 2 links might help with that:
- The Bash Parser
- (POSIX) Shell Command Line Processing

And here's a working version (tested this time...) based on your examples:
Code:

#!/bin/bash

for STORE in $( cat /home/techs/upg-11.38.05.00/test.txt )
do
  allVars=( $( ssh root@$STORE "\
                du -b /usr1/vision/bin/wd | awk '{ print \$1 }' ; \
                uname -a | awk '{ print \$3 }' | cut -c 1-6 ; \
                pwd ; " ) )

  WDvr="${allVars[0]}"
  OSfr="${allVars[1]}"
  Ship="${allVars[2]}"

  echo "WD - $WDvr"
  echo "OS - $OSfr"
  echo "SP - $Ship"

done


keif 10-06-2013 03:39 PM

Quote:

Originally Posted by colucix (Post 5040798)
Again a problem of protecting the remote command from the local shell. This time is the $1 in the awk command that must be escaped, otherwise it results in a null string (if you don't pass arguments to the script) and awk simply prints out the whole string, which is
Code:

78740 /usr1/vision/bin/wd
This is the reason why two elements (space separated) are assigned to the array. To avoid that you can escape the $ sign using a backslash:
Code:

"du -b /usr1/vision/bin/wd | awk '{print \$1}'; \
Ciao.

colucix,

Thank you for explaining this. It's working great now. I may have bashed my head against the wall a lot on this one, but I learned a heck of a lot. Thanks for your help.

keif 10-06-2013 03:40 PM

Quote:

Originally Posted by druuna (Post 5040824)
@keif: I was focusing too much on the array part and completely overlooked the details of the ssh command. As already explained by colucix, you need to take make sure commands aren't interpreted locally.

These 2 links might help with that:
- The Bash Parser
- (POSIX) Shell Command Line Processing

And here's a working version (tested this time...) based on your examples:
Code:

#!/bin/bash

for STORE in $( cat /home/techs/upg-11.38.05.00/test.txt )
do
  allVars=( $( ssh root@$STORE "\
                du -b /usr1/vision/bin/wd | awk '{ print \$1 }' ; \
                uname -a | awk '{ print \$3 }' | cut -c 1-6 ; \
                pwd ; " ) )

  WDvr="${allVars[0]}"
  OSfr="${allVars[1]}"
  Ship="${allVars[2]}"

  echo "WD - $WDvr"
  echo "OS - $OSfr"
  echo "SP - $Ship"

done


druuna, that was it. It's working like a charm. Thanks again for your help. This is something I can use in many things and now that I know it, life is going to be a little easier :-)


All times are GMT -5. The time now is 05:53 AM.