Bash one-liner для атомарного создания файла, если он не существует

9

Я хочу одну строчку Bash, которая атомарно создает файл, если он не существует. По сути, это означает «если файл не существует, создайте его», но при этом убедитесь, что никому больше не удастся создать файл в небольшом пространстве между выполнением if и созданием файла.

Рам Рахум
источник
Извините, я читаю «атомарно» как «автоматически». Я удалил свой ответ.
Аарон Копли

Ответы:

6

Кража ответа из различных комментариев и ссылок на [SO]. Кажется, есть POSIX-совместимый метод , который не включает, mkdirкак я уже упоминал в моем первоначальном ответе ниже

set -o noclobber # or set -C
{ > file ; } &> /dev/null

Это перенаправление в файл возвращает 0 или завершается ошибкой и возвращает ненулевое значение, если файл уже существует.


Оригинальный ответ

Вам придется использовать mkdir- это атомарно, либо каталог создается, и вы можете продолжить, либо он не создается, поэтому вы предпринимаете соответствующие действия.

Конечно, mkdirне создает файл, но как только вы узнаете, что имеете эксклюзивный доступ к каталогу, вы можете создать в нем нужный вам файл.

Что касается одного лайнера - я оставлю это на ваше усмотрение. Лично я бы написал это в несколько строк, так как это будет более понятным.

user9517
источник
Но noclobber от stackoverflow.com/q/13828544/1207760 - это больше, чем хочет OP.
Закон 29
Ноклоббер, в общем, хороший ответ. Но это не работает для ksh88.
jrw32982 поддерживает Монику
1
@JohnWiersba, но вопрос о Баш.
womble
@womble да, но в ответе упоминается POSIX, что может означать, что ответ относится к другим оболочкам. Ksh88 по-прежнему является стандартной оболочкой на некоторых серверах.
jrw32982 поддерживает Монику
0

Это файл или каталог? Если файл, вы можете использовать простую команду touch - если файл существует, он просто изменяет время последнего доступа. Если файл не существует, создается.

Ондра Снайпер Флидр
источник
0

Попробуй это. lnОбеспечивает функциональные возможности тест-и-набор.

touch lock.$$.tmp
if ln lock.$$.tmp lock.dat 2>/dev/null
then
    echo "File is mine"
else
    echo "Test and set failed"
fi
rm -f lock.$$.tmp
roaima
источник
0

Если вас не волнует имя файла, вы можете делегировать эту задачу утилите, например, mktemp

Create a temporary file or directory, safely, and print its name.
TEMPLATE must contain at least 3 consecutive `X's in last component.
If TEMPLATE is not spec‐ified, use tmp.XXXXXXXXXX, and --tmpdir is 
implied.  Files are created u+rw, and directories u+rwx, minus umask
restrictions.

Призвание:

filename=$(mktemp)
asdmin
источник