Как передать сложные команды оболочки через SSH для удаленного выполнения? Мои ошибки синтаксиса броска или интерпретируются локально!

У меня есть команда, подобная этой, которая говорит мне, если система имеет заполненный диск (> = 70% заполнен):

if [[ -n df -PTh|column -t|awk '{print $6 $7}'|awk -F"%" '{printf "%-9s %-5s\n",$1,$2}'|grep -v -e "Use" -e "Mounted"|awk '$1>70{printf "%-9s %-5s\n",$1,$2}' ]]; then echo "not present"; else echo ">70 is present"; fi

Я хотел бы выполнить вышеуказанную команду на удаленный сервер с использованием SSH. Нечто подобное:

ssh remoteserver "if [[ -n df -PTh|column -t|awk '{print $6 $7}'|awk -F"%" '{printf "%-9s %-5s\n",$1,$2}'|grep -v -e "Use" -e "Mounted"|awk '$1>70{printf "%-9s %-5s\n",$1,$2}' ]]; then echo "not present"; else echo ">70 is present"; fi"

Но когда я попробовал это, я получил следующую ошибку:

HOST: remoteserver bash: -c: line 0: syntax error in conditional expression bash: -c: line 0: syntax error near /home'
bash: -c: line 0:if [[ -n 92 /home'
3
задан 28 April 2014 в 14:57

1 ответ

Прежде всего, я бы сократил это военное преступление с помощью оператора awk / grep / awk / grep / awk / grep / etc до:

df | awk '$5~/([7-9]|10)[0-9]/'

Он делает все, что вам нужно проверить выход. Вы можете добавить предложение {print ...} в оператор awk, если вы действительно нуждались в симпатичном выводе, но, учитывая, что вы просто проверяете, чтобы увидеть , если есть вывод, давайте будем разумны об этом [.

Мы также можем сократить if / else. Я также исправил направление - твое было полностью изменено. Теперь вся команда выглядит следующим образом:

[[ -n $(df | awk '$5~/([7-9]|10)[0-9]/') ]] && echo 'ACHTUNG!' || echo 'No >=70s'

Я думаю, вы согласитесь, что это немного более назидательно.

Теперь вы, вероятно, могли бы избежать этого вручную и обернуть его в bash -c "...", но где в этом удовольствие? Вместо этого давайте сохраним команду в локальном файле (например, commands.txt), вы можете отправить ее на сервер следующим образом:

ssh user@host $(<commands.txt)

И вы можете оставить ее там. Вы можете добавить туда рабочую версию вашей оригинальной команды и отправить ее заново. Эта штука довольно надежная ... Но мы не хотим этого делать ... Не тогда, когда мы можем быть более умными (и обманчивыми) с помощью команды и покончить с скобками if (которые являются причинами проблемы с выходом из строя). ). [+1143]

В настоящее время мы выполняем df удаленно и обрабатываем его удаленно. Нам не нужно этого делать. Мы могли бы позволить ssh просто запустить df и затем обработать вывод локально. Это мгновенно устраняет проблему побега, но в настоящее время мы связаны логическими скобками [[ ]], которые сделают перезапись немного уродливой:

[[ -n $(ssh user@host df | awk '$5~/([7-9]|10)[0-9]/') ]] && .......

Гадость.
Мы лучше, чем это.
В отличие от обезьян и обезьян, которые ходили перед нами, у нас есть коды выхода.

Когда что-то завершается, оно может вернуть код. Эти коды означают различные вещи , но в целом 0 означает «я сделал именно то, для чего предназначен», а все, что выше, означает «я сделал плохо, Баус».

Условные перехватчики, такие как && и ||, обращаются к вводимому в них коду выхода, чтобы решить, запускаться или нет. В нашем случае это означает, что если мы скажем awk выйти ненулевым способом, мы можем управлять потоком кода:

ssh user@host df | awk '$5~/([7-9]|10)[0-9]/ {exit 1}' && echo 'No >=70s' || echo 'ACHTUNG!'

Это также означает, что он выйдет, как только обнаружит первый > = 70 значение Если бы у вас были миллионы дисков, это могло бы сэкономить вам секунд по сравнению с другими сценариями ведущих брендов. Так что да, просто чтобы подтвердить, что происходит в этой окончательной версии:

  1. Мы подключаемся к серверу и запускаем df удаленно
  2. Выходные данные передаются обратно в локальный экземпляр из awk
  3. awk проверяет, соответствует ли пятый столбец регулярному выражению для соответствия 70-100
  4. Если это так, он выходит из кода 1 и код || выполняется ( там используется диск, использованный более чем на 70%)
  5. Если этого не происходит, он выходит из кода 0 и выполняется код &&.

В предыдущих ревизиях у меня также была проверка NR>1 в операторах awk, но, учитывая, что мы явно проверяем значение пятого столбца (и он должен работать) мы можем смело пропустить это тоже.

0
ответ дан 28 April 2014 в 14:57

Другие вопросы по тегам:

Похожие вопросы: