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.


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.


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.


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

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.