Как запустить цикл внутри heredoc при доступе к удаленной машине - PullRequest
0 голосов
/ 23 сентября 2018

Вот мой скрипт, в котором я использую локальную переменную внутри удаленной машины, используя heredoc.Но цикл под heredoc принимает только первое значение переменной.Цикл работает нормально внутри heredoc, но с теми же значениями.

#!/bin/bash
prod_web=($(cat /tmp/webip.txt));
new_prod_app_private_ip=($(cat /tmp/ip.txt));
no_n=($(cat /tmp/serial.txt));
ssh -t -o StrictHostKeyChecking=no ubuntu@${prod_web[0]} -p 2345 -v << EOF
set -xv
for (( x = 0; x < '${#no_n[@]}'; x++ ))
do
sudo su
echo '${no_n[x]}'
echo '${new_prod_app_private_ip[x]}'
curl -fIkSs https://'${new_prod_app_private_ip[x]}':9002 | head -n 1 
done
EOF

Итак, мой файл ip.txt содержит такие значения, как:

10.0.1.0
10.0.2.0
10.0.3.0

Мой файл serial.txt:

9
10
11

Итак, мой цикл запускается только для первого IP-адреса (присутствует в /tmp/ip.txt) на удаленном компьютере, три раза.Я хочу запустить его для всех трех IP-адресов.Мой удаленный ip присутствует в файле /tmp/webip.txt.

Застрял надолго, любая помощь приветствуется.Есть ли другое решение, с которым я могу пойти?

1 Ответ

0 голосов
/ 23 сентября 2018

Есть 2 среды.На вашей локальной машине и на удаленной машине.Вам нужно подумать, как передавать данные / переменные / состояния / объекты / дескрипторы между этими машинами.Если вы установили что-то на локальном компьютере (например, prod_web=($(cat /tmp/webip.txt));), а затем просто указали ssh на удаленном хосте (например, ssh user@host 'echo "${prod_web[@]}"'), переменная не будет видна / экспортирована на удаленный компьютер.Вы можете:

  • scp файлы {ip, serial} .txt и выполнить весь сценарий на удаленном компьютере, затем выполнить очистку, т.е.удалить файлы {ip, serial} .txt с удаленного компьютера
  • передать файлы {ip, serial} .txt каким-то образом объединить / присоединить / вставить в stdin ssh, а затем прочитать stdin на удаленииmachine
  • создает все команды для запуска на локальном компьютере, а затем передает предварительно подготовленные команды на удаленный компьютер, например ssh .... "$(for ...; do; echo curl ...; done)"

Я бы выбрал второй вариант, какМне нравится передавать все, используя каналы, и я не люблю убирать за собой - удаление временных файлов в случае ошибки может привести к путанице.

Мой сценарий, вероятно, будет выглядеть так:

#!/bin/bash 
set -euo pipefail
read -r host _ <webip.txt
paste serial.txt ip.txt | ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" '#!/bin/bash
set -euo pipefail
while read -r no_n ip; do
     for ((i = 0; i < no_n; ++i)); do
         printf "%s\n" "$no_n"
         printf "%s\n" "$ip"
         curl -fIkSs https://"$ip":9002 | head -n 1 
      done
done
'

Поскольку удаленный скрипт стал бы больше и менее дружественным к qouting, я бы сохранил его в другой remote_scripts.sh и выполнил бы ssh ... -m remote_scripts.sh.
Я не понимаю, что вы пытаетесь сделать с этим sudo su, что 100% не делает то, что вы хотите.
Если магическое число no_n - это количество раз, которое нужно выполнить этот локон, и у вас есть xargs, и вы не заботитесь об ошибках, вы можете просто сделать магию и сбить с толку oneliner:

#!/bin/bash 
set -euo pipefail
read -r host _ <webip.txt
paste serial.txt ip.txt | ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" 'xargs -n2 -- sh -c "seq 0 \"\$1\" | xargs -n1 -- sh -c \"curl -fIkSs https://\\\"\\\$1\\\":9002 | head -n 1\" -- \"\$2\"" --'

Подготовка всей команды к запуску может быть на самом деле более читабельной и может сэкономить некоторые неприятные указания для решения.Но это действительно зависит от того, насколько велики serial.txt и ip.txt и насколько велики команды, выполняемые на удаленной машине, так как вы хотите минимизировать количество байтов, передаваемых между машинами.
Здесь команды для запускасоздаются на локальной машине (т. е. "$ (...)" передается в ssh) и выполняются на удаленной машине:

# semi-readable script, not as fast and no xargs
ssh -t -o StrictHostKeyChecking=no -p 2345 -v ubuntu@"$host" "$(paste serial.txt ip.txt | while read -r serial ip; do 
   seq 0 "$serial" | while read -r _; do
         echo "curl -fIkSs \"https://$ip:9002\" | head -n 1"
   done

done) "

HERE-doc неразверните команды оболочки, так:

$ cat <<EOF
> echo 1
> EOF
echo 1

но вы можете использовать подстановку команд $( ... ):

$ cat <<EOF
> $(echo 1)
> EOF
1
...