Bash один-лайнер для атомного створення файлу, якщо його не існує


9

Я хочу однолінійку Bash, який атомно створює файл, якщо його не існує. Це по суті означає "якщо файл не існує, створити його", але гарантувати, що ніхто інший не вдається створити файл у невеликому просторі між виконанням if і створенням файлу.


Вибачте, я читаю "атомно" як "автоматично". Я видалив свою відповідь.
Аарон Коплі

Відповіді:


6

Крадіжка відповіді з різних коментарів та посилань на [SO]. Здається, існує метод, сумісний з POSIX , який не передбачає, mkdirяк я вже згадував у своїй початковій відповіді нижче

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

Це переспрямування на файл повертає 0 або відмовляється і повертається не нульовим, якщо файл вже існує.


Оригінальна відповідь

Вам доведеться скористатися mkdir- це атомно, або створюється каталог, і ви можете продовжувати, або він не створюється, тому вживайте відповідних дій.

Звичайно, mkdirфайл не створюється, але коли ви знаєте, що у вас є ексклюзивний доступ до каталогу, ви можете зробити потрібний файл у ньому.

Щодо одного лайнера - я це залишаю вам. Особисто я б написав це через кілька рядків, оскільки це буде більш ретельним.


Але noclobber від stackoverflow.com/q/13828544/1207760 - це більше те, чого хоче ОП.
Закон29

Ноклоббер - це взагалі хороша відповідь. Але це не працює для ksh88.
jrw32982 підтримує Моніку

1
@JohnWiersba, але питання стосується bash.
живіт

@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

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.