Как я могу использовать удар, если тест и находит команды вместе?

В первую очередь, я предлагаю занять место

for fname in `find . -type f`; do

с

find . -type f | while read -r fname; do

Затем, относительно sha1sum, это должно быть "фактически" уникально, означая, что вероятность, чтобы иметь в различные файлы с той же контрольной суммой, если значительно низкий, так, чтобы можно было безопасно принять это, уникальна.

25
29.08.2012, 02:50
5 ответов

[ и test синонимы (кроме [ требует ]), таким образом, Вы не хотите использовать [ test:

[ -x /bin/cat ] && echo 'cat is executable'
test -x /bin/cat && echo 'cat is executable'

test возвращает нулевой статус выхода, если условие является верным, в других отношениях ненулевым. Это может на самом деле быть заменено любой программой для проверки ее статуса выхода, где 0 указывает, что успех и ненулевой указывает на отказ:

# echoes "command succeeded" because echo rarely fails
if /bin/echo hi; then echo 'command succeeded'; else echo 'command failed'; fi

# echoes "command failed" because rmdir requires an argument
if /bin/rmdir; then echo 'command succeeded'; else echo 'command failed'; fi

Однако все вышеупомянутые примеры только тестируют против статуса выхода программы и игнорируют вывод программы.

Для find, необходимо будет протестировать, если вывод был сгенерирован. -n тесты для непустой строки:

if [[ -n $(find /var/log/crashes -name "app-*.log" -mmin -5) ]]
then
    service myapp restart
fi

Полный список тестовых аргументов доступен путем вызова help test в bash командная строка.

Если Вы используете bash (и нет sh), можно использовать [[ condition ]], который ведет себя больше очевидно, когда существуют пробелы или другие особые случаи в Вашем условии. Иначе это обычно - то же как использование [ condition ]. Я использовал [[ condition ]] в этом примере, как я делаю, когда это возможно.

Я также изменился `command` кому: $(command), который также обычно ведет себя точно так же, но более любезен с вложенными командами.

27
27.01.2020, 19:40
  • 1
    echo может перестать работать: попробовать echo 'oops' > /dev/full. –  derobert 29.08.2012, 01:52
  • 2
    Этот ответ бьет все вокруг корня проблемы, но корректно старается не упоминать точно, каково это. –  bahamat 30.08.2012, 01:05

find выйдет успешно, если не было никаких ошибок, таким образом, Вы не можете рассчитывать на его статус выхода, чтобы знать, нашел ли он какой-либо файл. Но, поскольку Вы сказали, можно рассчитать, сколько файлов это нашло, и протестируйте то число.

Это было бы что-то вроде этого:

if [ $(find /var/log/crashes -name 'app-*.log' -mmin -5 | wc -l) -gt 0 ]; then
    ...
fi

test (иначе [) не проверяет коды ошибок команд, это имеет специальный синтаксис, чтобы сделать тесты и затем выходит с кодом ошибки 0, если тест был успешен, или 1 иначе. Это if тот, который проверяет код ошибки команды, которую Вы передаете ему, и выполняет ее тело на основе его.

Посмотрите man test (или help test, если Вы используете bash), и help if (так же).

В этом случае, wc -l произведет число. Мы используем testопция -gt протестировать, если то число больше, чем 0. Если это, test (или [) возвратится с кодом выхода 0. if интерпретирует тот код выхода как успех, и он выполнит код в своем теле.

9
27.01.2020, 19:40

Это было бы

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)" ]; then

или

if test -n "$(find /var/log/crashes -name app-\*\.log -mmin -5)"; then

Команды test и [ … ] точно синонимичны. Единственной разницей является их имя и факт это [ требует закрытия ] как его последний аргумент. Как всегда, используйте двойные кавычки вокруг замены команды, иначе вывод find команда будет повреждена в слова, и здесь Вы получите синтаксическую ошибку, если будет больше чем один файл соответствия (и когда нет никаких аргументов, [ -n ] верно, тогда как Вы хотите [ -n "" ] который является ложью).

В ksh, ударе и zsh, но не в пепле, можно также использовать [[ … ]] который имеет различные правила парсинга: [ обычная команда, тогда как [[ … ]] другая конструкция парсинга. Вам не нужны двойные кавычки внутри [[ … ]] (хотя они не причиняют боль). Вам все еще нужно ; после команды.

if [[ -n $(find /var/log/crashes -name app-\*\.log -mmin -5) ]]; then

Это может потенциально быть неэффективно: если существует много файлов в /var/log/crashes, находка исследует их всех. Необходимо сделать, находят остановку, как только она находит соответствие, или вскоре после. С GNU находят (не встроил Linux, Cygwin), используйте -quit основной.

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print -quit)" ]; then

С другими системами, каналом find в head по крайней мере, выходить вскоре после первого соответствия (находка умрет от поврежденного канала).

if [ -n "$(find /var/log/crashes -name app-\*\.log -mmin -5 -print | head -n 1)" ]; then

(Можно использовать head -c 1 если Ваш head управляйте поддерживает его.)


С другой стороны, используйте zsh.

crash_files=(/var/log/crashes/**/app-*.log(mm-5[1]))
if (($#crash_files)); then
1
27.01.2020, 19:40

Это должно работать

if find /var/log/crashes -name 'app-\*\.log' -mmin -5 | read
then
  service myapp restart
fi
1
27.01.2020, 19:40

Вы можете сделать это, поместив вывод find в переменную, а затем используя тест bash для обработки различных интересующих вас случаев. Простой случай — есть ли какие-либо результаты или нет:

mycrashedapp=$(find /var/log/crashes/ -name myapp-\*\.log -mmin -5)
# if no crash then the variable is empty
if [[ -z "${mycrashedapp}" ]];then
  echo "myapp is behaving."
else
  service myapp restart
fi

На этом этапе вы можете при необходимости выполнить дальнейшую обработку, используя манипуляции с переменными в bash:

substr="/var/log/crashes"
parse=${mycrashedapp//"$substr"}
myappcrashedcount="$(((${#mycrashedapp} - ${#parse}) / ${#substr}))"

echo "myapp has crashed ${myappcrashedcount} times in total."

Вы можете выполнить дальнейшую обработку с помощью встроенного в bash сопоставления шаблонов регулярных выражений:

if [[ "${mycrashedapp}" =~ myapp-([0-9\-]*).log ]]; then
  echo "The dates and times that myapp has crashed:"
  echo ${BASH_REMATCH[1]}
fi
0
18.12.2020, 15:06

Теги

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