Как насчет того, чтобы продолжиться как это:
421 Service not available, closing transmission channel
в баннереТаким образом, Вы полагались бы на то, что клиенты повторят позже для поставки электронной почты.
set -- "${LOCATION}/"*
while [ -s "$1" ] ; do shift ; done
[ -e "$1" ] && FLAG=1
Оболочка [ test ]
может быть использована с оператором -s
ize. Из man test
:
-s FILE
-s FILE
существует и имеет размер больше нуля
, что, впрочем, будет нелегко работать при рекурсивных поисках.
find
будет, но, по сути, так же просто, как и установка булева значения, это действительно не очень подходит для данного случая. ls
может выполнять рекурсивный поиск так же быстро, легко можно настроить размер файла в качестве первого поля для листинга и перечислять только одну запись на строку - гарантированно. Если вы хотите установить булевое значение переменной оболочки, основываясь на том, содержит ли рекурсивный список файлов файл размером 0, то ls
- это лучший вариант - find
только усложняет ситуацию. Что вас интересует, так это свойства файла, а не его местоположение. Здесь блестит ls
, а grep
ping его вывод - это ветерок.
Вы можете сделать это легко:
ls -1aqRsp "$LOCATION" 2>&1 | grep -qv "^ *[^0]\|/"
FLAG=$(($?==0))
Это только установит FLAG
в 1
, если файл - скрытый . включенный файл точки
- существует в $LOCATION
или в одном из его дочерних каталогов с размером нуля. В противном случае $FLAG
составляет 0
.
find
подбирает новый дочерний процесс, когда вы делаете -exec
. Ни один дочерний процесс не может изменить родительское окружение.
Вы можете собрать имена файлов с помощью find
и затем сгенерировать нужное вам письмо во втором проходе:
find . -type f -size 0 -print >> /var/tmp/find.sz0
...
ФЛАГ экспорта = 1
выполняется в экземплярах sh
, вызванных find
. Окружение процесса никогда не копируется обратно в его родительский элемент. Процесс оболочки, который устанавливает только переменную среды и завершает работу, не дает долговременных результатов.
Если вы хотите проверить, соответствует ли find
какому-либо файлу, вы можете просто проверить, пуст ли его вывод. Чтобы избежать потенциального создания длинного списка файлов только для того, чтобы отбросить его, как только будет доказано, что он не пустой, вы можете усечь вывод find
при первой возможности. GNU find имеет предикат -quit
, и вы также можете легко указать ему, чтобы он отображал один символ. В следующем фрагменте FLAG
заканчивается пустым, если совпадений нет:
FLAG=$(find "$LOCATION" -size 0 -type f -printf 1 -quit \;)
Следующий вариант устанавливает для FLAG
значение 0 или 1:
FLAG=$(find "$LOCATION" -size 0 -type f -printf 1 -quit \;)
[ -n "$FLAG" ] || FLAG=0
Если вы хотите сохранить переносимость, вы можете заставить find
печатать совпадения и оставить только первую строку; find
умрет от SIGPIPE после того, как голова
закроет свою сторону трубы.
if [ -n "$(find "$LOCATION" -size 0 -type f -print | head -n 1 \;)" ]; then
FLAG=1
else
FLAG=0
fi
Если это был просто упрощенный пример и вам нужно установить более сложные переменные, существует несколько возможных подходов. Назову лишь пару распространенных.
Zsh имеет множество вариантов использования find
, встроенных благодаря квалификаторам glob . Следующий фрагмент устанавливает файлов
в список файлов, соответствующих find $ LOCATION -size 0 -type f
:
files=(**/*(.DL0))
Ksh и bash также имеют рекурсивные глобусы, если включены с set -o globstar
и shopt -s globstar
соответственно. Однако имейте в виду, что с bash до 4.2 **
рекурсивно превращается в символические ссылки на каталоги, что обычно нежелательно. Дальнейшую обработку можно выполнять в оболочке.
FIGNORE= # include dot files in wildcard matches (the ksh way)
GLOBIGNORE=.:.. # include dot files in wildcard matches (the bash way)
for x in **/*; do
done
Если ни одно из совпадающих имен файлов не содержит символов новой строки, вы можете проанализировать вывод команды find
как список с разделителями новой строки.
find "$LOCATION" -size 0 -type f ! -name '*
*' -print | {
while read -r empty_file; do
…
done
}