Передача скрипта на удалённый сервер и выполнение его там так чтобы при этом текст скрипта был встроен во "внешний" вызывающий bash-скрипт

Как в bash реализовать передачу скрипта на удалённый сервер по ssh и выполнение его там так, чтобы при этом текст скрипта был встроен во "внешний" вызывающий bash-скрипт? Возможно формулировка несколько непонятна, сейчас поясню на примере:

Допустим мне нужно снять показатели использования резидентной и виртуальной памяти веб-сервером httpd, я определяю pid процесса httpd через pid-файл и делаю это так:

cat /proc/$(cat /run/httpd/httpd.pid)/status | awk '/VmSize/{print $1 $2*1024}'
cat /proc/$(cat /run/httpd/httpd.pid)/status | awk '/VmRSS/{print $1 $2*1024}'

При этом, чтобы не делать два вызова ssh-клиента для выполнение каждой команды, а обойтись одним, я помещаю получившийся скрипт в многострочную переменную SCRIPT0, которую описываю через HereDoc, получается вот так (нужно понимать что это просто пример, реально может возникнуть ситуация, когда внутренний скрипт будет содержать не 2, а 200 строк, при этом хотелось бы, чтобы код остался удобочитаемым):

#!/bin/bash

SCRIPT0=$(cat << 'EOF'
   cat /proc/$(cat /run/httpd/httpd.pid)/status | awk -v OFS='' '/VmSize/{print $1,$2*1024," "}'
   cat /proc/$(cat /run/httpd/httpd.pid)/status | awk -v OFS='' '/VmRSS/{print $1,$2*1024}'
EOF
)

echo "$SCRIPT0" | /usr/bin/ssh -i /home/iskatel/id_rsa [email protected] /bin/bash | tr -d '\n'

Вроде всё работает. А теперь я хочу расширить задачу, сделать так, чтобы IP сервера и pid-файл передавались параметрами, чтобы скрипт был универсальным. Делаю так:

#!/bin/bash

SCRIPT0=$(cat << 'EOF'
   cat /proc/$(cat "$2")/status | awk -v OFS='' '/VmSize/{print $1,$2*1024," "}'
   cat /proc/$(cat "$2")/status | awk  -v OFS='' '/VmRSS/{print $1,$2*1024}'
EOF
)

echo "$SCRIPT0" | /usr/bin/ssh -i /home/iskatel/id_rsa iskatel@"$1" /bin/bash | tr -d '\n'

И не работает, внутри HereDoc параметр $2 не раскрывается.


Ответы (1 шт):

Автор решения: Iskatel

Пришло в голову другое решение, не делать так, чтобы параметр $2 раскрылся в HereDoc, экранируя знак доллара спецсимволами, как предложили в комментариях, а сделать так, чтобы параметр раскрылся за пределами HereDoc и передался во внутренний скрипт как уже локальный параметр и потом раскрылся там.

Короче сделал вот так:

#!/bin/bash

SCRIPT0=$(cat << 'EOF'
   cat /proc/$(cat "$1")/status | awk -v OFS='' '/VmSize/{print $1,$2*1024," "}'
   cat /proc/$(cat "$1")/status | awk  -v OFS='' '/VmRSS/{print $1,$2*1024}'
EOF
)

echo "$SCRIPT0" | /usr/bin/ssh -i /home/iskatel/id_rsa iskatel@"$1" /bin/bash -s "$2" | tr -d '\n'

Работает.

→ Ссылка