Как установить переменные от find+exec?

Как насчет того, чтобы продолжиться как это:

  1. 1-й Rsync
  2. Сделайте ответ qmail 421 Service not available, closing transmission channel в баннере
  3. 2-й Rsync
  4. Восстановите исходную конфигурацию qmail (или переключитесь на другой сервер, я не уверен, что получил ту часть),

Таким образом, Вы полагались бы на то, что клиенты повторят позже для поставки электронной почты.

3
23.06.2014, 13:45
3 ответа
set -- "${LOCATION}/"*
while [ -s "$1" ] ; do shift ; done
[ -e "$1" ] && FLAG=1

Оболочка [ test ] может быть использована с оператором -size. Из man test:

-s FILE

-s FILE существует и имеет размер больше нуля

, что, впрочем, будет нелегко работать при рекурсивных поисках.

find будет, но, по сути, так же просто, как и установка булева значения, это действительно не очень подходит для данного случая. ls может выполнять рекурсивный поиск так же быстро, легко можно настроить размер файла в качестве первого поля для листинга и перечислять только одну запись на строку - гарантированно. Если вы хотите установить булевое значение переменной оболочки, основываясь на том, содержит ли рекурсивный список файлов файл размером 0, то ls - это лучший вариант - find только усложняет ситуацию. Что вас интересует, так это свойства файла, а не его местоположение. Здесь блестит ls, а grepping его вывод - это ветерок.

Вы можете сделать это легко:

ls -1aqRsp "$LOCATION" 2>&1 | grep -qv "^ *[^0]\|/"
FLAG=$(($?==0))

Это только установит FLAG в 1, если файл - скрытый . включенный файл точки - существует в $LOCATION или в одном из его дочерних каталогов с размером нуля. В противном случае $FLAG составляет 0.

.
1
27.01.2020, 21:31

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

Вы можете собрать имена файлов с помощью find и затем сгенерировать нужное вам письмо во втором проходе:

find . -type f -size 0 -print >> /var/tmp/find.sz0
...
0
27.01.2020, 21:31

ФЛАГ экспорта = 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
}
0
27.01.2020, 21:31

Теги

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