У меня есть команда, подобная этой, которая говорит мне, если система имеет заполненный диск (> = 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'
Прежде всего, я бы сократил это военное преступление с помощью оператора 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 значение Если бы у вас были миллионы дисков, это могло бы сэкономить вам секунд по сравнению с другими сценариями ведущих брендов. Так что да, просто чтобы подтвердить, что происходит в этой окончательной версии:
df
удаленно awk
awk
проверяет, соответствует ли пятый столбец регулярному выражению для соответствия 70-100 ||
выполняется ( там используется диск, использованный более чем на 70%) &&
. В предыдущих ревизиях у меня также была проверка NR>1
в операторах awk
, но, учитывая, что мы явно проверяем значение пятого столбца (и он должен работать) мы можем смело пропустить это тоже.