Как правильно отформатировать оператор «if», передаваемый на удаленный сервер, при использовании «while read»? - PullRequest
1 голос
/ 01 октября 2019

Ubuntu 18
Bash 4.4.0

Я хочу передать оператор if, чтобы увидеть, существует ли каталог. Если это произойдет, я хочу некоторые команды, а затем файл. Я прочитал подобные посты, но Shellcheck жалуется на мое форматирование.

Сценарий:

#!/bin/bash

testing="yes"
scriptDir="/root/.work"
wDir="${scriptDir}/.nginx-fix"
if [ "$testing" = "no" ]; then
  hostfile="${scriptDir}/.zzz-hostnames"
else
  hostfile="${scriptDir}/.zzz-hostnames-tester"
fi

cd "$wDir"
while read fqdn; do
  { clear; echo ""; echo ""; echo "$hostname"; echo ""; }
  < /dev/null if ssh -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]'; then
    < /dev/null ssh -p 34499 root@"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
    < /dev/null scp -P 34499 nginx.conf root@"${fqdn}":/etc/nginx
    < /dev/null ssh -p 34499 root@"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
    < /dev/null ssh -p 34499 root@"${fqdn}" 'nginx -t'
  else
    exit 1;
  fi
done<"${hostfile}"

Жалоба Shellcheck:

root@me ~/.work/.nginx-fix # shellcheck .nginx-fixer.sh

In .nginx-fixer.sh line 13:
while read fqdn; do
^-- SC1073: Couldn't parse this while loop.
                 ^-- SC1061: Couldn't find 'done' for this 'do'.


In .nginx-fixer.sh line 15:
        < /dev/null if ssh -p 33899 root@"${fqdn}" '[ -d /etc/nginx ]'; then
                                                                        ^-- SC1062: Expected 'done' matching previously mentioned 'do'.
                                                                            ^-- SC1072: Expected "#". Fix any mentioned problems and try again.

Буду признателен за ваши мысли.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Вы можете реорганизовать скрипт в более ясную версию и удалить все </dev/null:

while read -r fqdn; do {
  { clear; echo ""; echo ""; echo "$hostname"; echo ""; }
  if ssh -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]'; then
    ssh -p 34499 root@"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
    scp -P 34499 nginx.conf root@"${fqdn}":/etc/nginx
    ssh -p 34499 root@"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
    ssh -p 34499 root@"${fqdn}" 'nginx -t'
  else
    exit 1;
  fi
} </dev/null; done < "${hostfile}"

Почти невидимые для глаз, я поместил все команды внутри do ... done внутри { .. } </dev/null. Таким образом, любая команда не будет читать из ${hostfile} и не будет связываться с while read.

Другой вариант - использовать выделенный дескриптор файла и передать его номер для чтения:

while read -r -u 10 fqdn; do
  { clear; echo ""; echo ""; echo "$hostname"; echo ""; }
  if ssh -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]'; then
    ssh -p 34499 root@"${fqdn}" 'mv /etc/nginx/nginx.conf /etc/nginx/.nginx-sept-30'
    scp -P 34499 nginx.conf root@"${fqdn}":/etc/nginx
    ssh -p 34499 root@"${fqdn}" 'sed -i "/honeypot/d" /etc/nginx/conf.d/*.conf'
    ssh -p 34499 root@"${fqdn}" 'nginx -t'
  else
    exit 1;
  fi
done 10<"${hostfile}"
1 голос
/ 01 октября 2019

Запуск сценария с помощью 'bash -n' укажет на 'настоящую' ошибку:

bash -n x.sh
x.sh: line 15: syntax error near unexpected token `then'
x.sh: line 15: `   < /dev/null if ssh -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]' ; then'

Вы не можете поместить перенаправление перед оператором 'if'. Переместите перенаправление в команду 'ssh' (часть условия if), например:

# USE:
if ssh < /dev/null -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]' ; then'

# AND NOT:
< /dev/null if ssh -p 34499 root@"${fqdn}" '[ -d /etc/nginx ]' ; then'

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...