Как добавить время ожидания после оператора перед выполнением следующего оператора в unix

В Unix у меня есть код, похожий на следующий

find /dir -name "filename*" -type f -print | xargs rm

case "$?" in
     "0") status="SUCCESS";;
      *) status=FAILED";;
esac

Он возвращает FAILED, и я думаю, это потому, что оператор case выполняется до того, как файлы будут удалены. Возможно, если я добавлю некоторое время ожидания после первого оператора, я смогу быть уверен, что файл полностью удален. Если это так, то как добавить в сценарий время ожидания, например 60 секунд?

РЕДАКТИРОВАТЬ: я должен упомянуть, что файлы удаляются, но статус выхода не равен нулю.


person Jay    schedule 21.08.2012    source источник
comment
Я думаю, что команда sleep 60 может быть полезной.   -  person Blender    schedule 21.08.2012
comment
Я боялся, что использование сна может вызвать проблемы при последующих запусках. Если у меня МНОГО файлов, то сложно посчитать, сколько времени нужно добавить   -  person Jay    schedule 21.08.2012
comment
После использования сна и указанного времени, продолжается ли сценарий со следующего оператора или есть вероятность, что программа может быть полностью приостановлена?   -  person Jay    schedule 21.08.2012


Ответы (2)


То, что вы делаете, проблематично, если есть файлы со странными именами, которые соответствуют вашей спецификации файлов. Если вы направите вывод find в xargs, у вас возникнет проверенная временем проблема Разбор LS

[ghoti@pc ~/tmp2]$ touch $'one\ntwo.txt' "three four.txt"
[ghoti@pc ~/tmp2]$ find . -name "*txt" -type f -print | xargs rm
rm: ./three: No such file or directory
rm: four.txt: No such file or directory
rm: ./one: No such file or directory
rm: two.txt: No such file or directory

Почему бы просто не обрабатывать rm непосредственно в find?

find /dir -name "filename*" -type f -exec rm {} \;

Чтобы проверить свои результаты, вы можете взять $?:

find /dir -name "filename*" -type f -exec rm {} \;
result=$?
case "$result" in
etc, etc

(Я помещаю $? в переменную на случай, если будет полезно повторно использовать ее позже или если другие команды должны выполняться между find и местом, где оценивается возвращаемое значение.)

Или вы можете просто проверить успех напрямую:

if find /dir -name "filename*" -type f -exec rm {} \;
then
    echo "SUCCESS!"
else
    echo "FAIL!"
fi

ОБНОВЛЕНИЕ:

Согласно комментариям... Если вам не нужно рекурсивно перемещаться по подкаталогам, вероятно, достаточно цикла for.

for file in *.txt; do
  if ! rm "$file"; then
    echo "ERROR: failed to remove $file" >&2
  fi
done

Или, если вам не нужна детализация генерации ошибок в отдельных файлах:

rm *.txt || echo "ERROR" >&2

Я не думаю, что смогу сделать его еще меньше. :-П

person ghoti    schedule 22.08.2012
comment
Думаю, это было бы проще. Однако в этом случае 1. Имена файлов содержат только буквы, цифры и подчеркивание и никаких других специальных символов, даже пробелов. 2. Все файлы находятся в указанном каталоге и без подкаталогов. Поэтому я не вижу причин, по которым xargs потерпит неудачу. Проблема заключалась в том, что содержимое папки постоянно менялось, а иногда файлов вообще не было. поэтому xargs терпит неудачу без операндов и возвращает статус выхода 123. - person Jay; 23.08.2012
comment
Если вам не нужно перемещаться по каталогу, достаточно цикла for. for file in *.txt; do rm "$file"; done. Постарайтесь избежать проблемы Parsing LS. Даже если (или, может быть, потому что) это только иногда кусает вас за задницу, это плохая привычка. - person ghoti; 23.08.2012

Для начала я предполагаю, что «похоже на следующее» включает наличие обеих кавычек вокруг строкового литерала FAILED. Если нет, вам, вероятно, следует сначала исправить это.

очень маловероятно, что case начнется до завершения предыдущих процессов. Если не считать использования & для запуска чего-то в фоновом режиме, это просто не UNIX :-)

Первое, что вы должны сделать, это заменить оператор case на:

rc=$?
case $rc in
    0) status="SUCCESS";;
    *) status="FAILED"; echo rc=$rc;;
esac

чтобы узнать, что на самом деле представляет собой код возврата. Затем найдите man xargs ($? всегда является кодом выхода последней вещи в конвейере), который показывает вам возможные значения и их вероятные причины. Например:

EXIT STATUS
    xargs exits with the following status:
         0 if it succeeds
       123 if any invocation of the command exited with status 1-125
       124 if the command exited with status 255
       125 if the command is killed by a signal
       126 if the command cannot be run
       127 if the command is not found
         1 if some other error occurred.
    Exit codes greater than 128 are used by the shell to indicate
    that a program died due to a fatal signal.
person paxdiablo    schedule 21.08.2012
comment
Да, в FAILED есть двойные кавычки, извините за опечатку. - person Jay; 21.08.2012
comment
Кстати, есть ли разница в использовании 0 и 0 для оператора case? - person Jay; 21.08.2012
comment
@Jay, не должно быть - $? - это числовая переменная, которая всегда существует, поэтому вам вообще не нужно заключать ее в строку. Судя по тесту, который я только что провел, это не имеет значения. - person paxdiablo; 21.08.2012
comment
Только что проверил. Ничего не возвращает. значение rc пустое. - person Jay; 21.08.2012
comment
Я нахожу это несколько... озадачивающим. Вы используете bash? Если это так, $? всегда должно иметь значение. - person paxdiablo; 21.08.2012
comment
Когда я запустил скрипт, файлы БЫЛИ удалены, но статус выхода не был указан. Затем я снова запустил его, без файлов для удаления, статус выхода - 123, а результат статуса - FAILED. - person Jay; 21.08.2012