Где хранятся пользовательские папки виртуальных пользователей с dovecot IMAP?

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

{   head -n "$((num_lines_before_insert))"
    grep key temp_file; sed \$d
}   <desired.txt
$(  cat 

Итак, для большинства оболочек (включая bash и zsh , но не тире или yash ) , когда вы получаете here_document, оболочка создает временный файл с уникальным именем в $ {TMPDIR: - / tmp} , exec s это на дескриптор входного файла, который вы указываете - (или, по умолчанию, просто 0) - и незамедлительно удаляет его. К тому времени, когда он используется в качестве входных данных для вашей команды, это файл un_ named - он не имеет оставшихся ссылок на какую-либо файловую систему и просто ожидает, пока ядро ​​очистит его, прежде чем он полностью исчезнет. Это правильный файл - его данные существуют где-то на диске (или, по крайней мере, в VFS в вероятном случае tmpfs ) , и ядро ​​будет гарантировать, что он продолжит делать это в по крайней мере, пока вы не освободите дескриптор файла.

Таким образом - до тех пор, пока ваша оболочка получает фактический файл поддержки для heredoc - они представляют собой очень безопасные и простые средства обработки временных файлов, поскольку они полностью записаны, и все имена файловых систем уже удалены из них раньше, чем когда-либо. вы их читаете. Таким образом, их данные не могут быть изменены во время работы.

Вышеупомянутый блок сначала записывает временный файл с помощью cat и сохраняет любые / все завершающие пустые строки из подстановки команды с помощью echo - который добавляет одну строку в хвост файла. Из оператора { составной команды } вывод трех его команд записывается в желаемый.txt - две из которых, в свою очередь, читают из наследственного документа заголовок и конец исходного файла - и команда grep , которая вставляет совпадение с вашим ключом .

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

Если ваша оболочка не получает фактический файл для heredocs, вы можете эмулировать то, что она делает ...

{   set "$$" "${TMPDIR:-/tmp}" "$@"
    exec <"$2/$(  set  -C
         >"$2/$1" cat  &&
         echo "$1")"  >&1 
    rm -- "$2/$1";shift 2
    head "-n$((before))"
    grep ... keyfile; cat
} source_file

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

Вот тест, который я провел, чтобы продемонстрировать это:

cd /tmp
set "$$" "${TMPDIR:-/tmp}" "$@"
seq 5000000 >test
printf line\ %s\\n 1 2 3 4 5 >test2
{   exec <"$2/$(  set  -C
         >"$2/$1" cat  &&
         echo "$1")"  >&1 
    rm -- "$2/$1";shift 2
    head -n2500000
    grep 3 test2;cat
} test

Сначала были созданы два файла - один с именем / tmp / test , который состоял всего из 5 миллионов пронумерованных строк, как написано в seq ] и второй под названием / tmp / test2 , который состоял всего из 5 строк вроде ...

line 1
line 2
line 3
line 4
line 5

Затем я запустил указанный выше блок, затем я сделал ...

sed -n '1p;$p;2499999,2500002l' 

...что, что интересно, заняло практически столько же времени, что и операция вставки, и напечатано:

1
2499999$
2500000$
line 3$
2500001$
5000000
5000001 test

Вот как это работает:

  1. Перенаправление 1 важно - оно устанавливает O_RDWR в stdout и гарантирует, что при записи в файл каждый процесс перезаписывает предыдущее содержимое файла. Другими словами, это означает, что исходный / целевой файл никогда не усекается, а скорее переписывается с головы до пят.
  2. Подстановка команды для exec выполняет часть racy как можно скорее (или как только я знаю) . В подгруппе команд noclobber установлен , поэтому, если «$ {TMPDIR: - / tmp} / $$» уже существует, раскрытие результатов в exec , который в интерактивной оболочке сразу же остановит весь процесс, или, в сценарии, вызовет завершение сценария со значимой ошибкой, поскольку оболочка не может exec каталог как стандартный ввод.
  3. Внутри команды sub cat копирует исходный_файл во временный файл, который еще не существует, а echo записывает имя в стандартный вывод.
  4. Как только все дескрипторы файлов станут exec ed rm unlink () , они станут новым временным файлом, так что его единственное мимолетное утверждение о существовании сейчас - только что назначенное перенаправление.
  5. head перебирает строки размером 2,5 мил и записывает первые строки размером 2,5 мил source_file . Дело в том, чтобы искать в обоих файлах равные смещения.
    • Помните, что эта часть могла бы быть более эффективной в отношении ввода-вывода, если вновь созданный файл tmp находится в tmpfs, а исходный файл находится на диске, если ввод-вывод был здесь перевернуто, и head читается из файла на диске и записывается в файл в RAM.
    • Если вы хотите это сделать, вам нужно будет выполнить exec "$ (... head ... & 0 , чтобы сделать файл tmp доступным для чтения / записи и, возможно, использовать head / tail с указанным количеством строк в конце. В этом случае число даже не обязательно должно быть точным - вы можете перебрать в цикле ввод аналогичным образом - увеличивая смещение только немного за раз. Встроенная оболочка read может использоваться для проверки EOF - или wc может использоваться при разомкнутом цикле.
    • Это потому, что cat , вероятно, просто зависнет на stdin, потому что он никогда не увидит EOF.
  6. grep считывает некоторые данные из другого файла и записывает их в исходный_файл , перезаписывая только то количество байтов, которое было прочитано из другого места.
  7. cat исправляет любое несоответствие grep , которое могло быть вызвано только записью того, что осталось от его stdin, в его stdout 1 source_file .

0
02.02.2018, 13:09
0 ответов

Теги

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