Bash one-liner, aby atomowo utworzyć plik, jeśli nie istnieje

9

Chcę jedno-liniowy Bash, który atomowo tworzy plik, jeśli nie istnieje. Oznacza to w zasadzie „jeśli plik nie istnieje, utwórz go”, ale upewnienie się, że nikomu innemu nie uda się utworzyć pliku na małej przestrzeni między wykonaniem if a utworzeniem pliku.

Ram Rachum
źródło
Przepraszam, czytam „atomowo” jako „automatycznie”. Usunąłem swoją odpowiedź.
Aaron Copley

Odpowiedzi:

6

Kradzież odpowiedzi z różnych komentarzy i linków do [SO]. Wydaje się, że istnieje metoda zgodna z POSIX , która nie wymaga, mkdirjak wspomniałem w mojej oryginalnej odpowiedzi poniżej

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

To przekierowanie do pliku zwraca 0 lub kończy się niepowodzeniem i zwraca wartość niezerową, jeśli plik już istnieje.


Oryginalna odpowiedź

Musisz użyć mkdir- to atomowy, albo katalog zostanie utworzony i możesz kontynuować, albo nie zostanie utworzony, więc podejmij odpowiednie działania.

Oczywiście mkdirnie tworzy pliku, ale gdy wiesz, że masz wyłączny dostęp do katalogu, możesz utworzyć plik, który chcesz w nim znaleźć.

Co do jednej wkładki - pozostawię to tobie. Osobiście napisałbym to w kilku wierszach, ponieważ będzie to łatwiejsze w utrzymaniu.

użytkownik9517
źródło
Ale noclobber ze stackoverflow.com/q/13828544/1207760 to więcej tego, czego chce OP.
Ustawa 29
Noclobber jest ogólnie dobrą odpowiedzią. Ale to nie działa dla ksh88.
jrw32982 obsługuje Monikę
1
@JohnWiersba, ale pytanie dotyczy bash.
womble
@womble tak, ale w odpowiedzi wspomniano POSIX, co ktoś może uznać za odpowiedź na inne powłoki. Ksh88 jest nadal standardową powłoką na niektórych serwerach.
jrw32982 obsługuje Monikę
0

Czy to plik lub katalog? Jeśli plik, możesz użyć prostego polecenia dotykowego - jeśli plik istnieje, wystarczy zmodyfikować czas ostatniego dostępu. Jeśli plik nie istnieje, zostaje utworzony.

Ondra Sniper Flidr
źródło
0

Spróbuj tego. lnDostarcza test-i-Set funkcjonalności.

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
źródło
0

Jeśli nie zależy Ci na nazwie pliku, możesz przekazać to zadanie narzędziu, na przykład 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.

Wezwanie:

filename=$(mktemp)
asdmin
źródło