bashawksshquotesremote-execution

SSH Remote Code Execution Script over Jumphost (Nested Quotes)


Consider the following infrastructure: ServerA ---> ServerB ---> ServerC

I want to get large files from ServerC (thus filtering them first) and save them on ServerA by running a script on ServerA.

The following command successfully retrieves all filenames matching my pattern and saves it in variable $myfiles:

myfiles=$(ssh root@$serverB -C $"\
          ssh -o StrictHostKeyChecking=no root@$serverC -C $'\
          (find . -name "mypattern" | sort)' </dev/null")

Instead of just transmitting the data I have to filter them first with the following command:

grep mypattern $myfile | awk -F '[| =]+' '{print $1 "/" $2 "/" $3, $4}' OFS=';'

Now, here I am running into nested quoting issues because awk splits the command with its single quotes:

while read myfile
do
   output=$( ssh root@$serverB -C $"\
             ssh -o StrictHostKeyChecking=no root@$serverC -C $'\
             (grep mypattern $myfile | awk -F '[| =]+' '{print $1 "/" $2 "/" $3, $4}' OFS=';')'\
             </dev/null")
   # do something with $output
done <<< "$myfiles"

Is there any way to get it run in this nested way?

Note: The ssh jumphost flag should not work as ServerC can only be accessed using the ssh command with StrictHostKeyChecking flag on ServerB.

Exchanging the quotes from single to double leads to a similar issue. I have also tried preparing the command as string, function and in a separate file without success.


Solution

  • What I would do, using shell here-doc:

    while read file; do
       output=$(
           ssh root@$serverB <<-EOF1
                 ssh -o StrictHostKeyChecking=no root@$serverC <<-EOF2
                 grep mypattern $myfile | awk -F '[| =]+' '{print \\\$1 "/" \\\$2 "/" \\\$3, \\\$4}' OFS=';'
                 EOF2
            EOF1
       )
       # do something with $output
    done <<< "$myfiles"
    
    

    In the left part of here-doc, you have to use tabs, not spaces.