Jeśli mam katalog zawierający niektóre pliki, których nazwy zawierają spacje, np
$ ls -1 dir1
file 1
file 2
file 3
Mogę z powodzeniem skopiować wszystkie z nich do innego katalogu, takiego jak ten:
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
Jednak dane wyjściowe find dir1 -mindepth 1
zawierają spacje bez znaku ucieczki:
$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3
Jeśli użyję print0
zamiast print
, dane wyjściowe nadal zawierają spacje bez znaczenia:
$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3
Aby ręcznie skopiować te pliki za pomocą cp
, musiałbym uciec od spacji; ale wydaje się, że nie jest to konieczne, gdy cp
pochodzą narzędzia find
, bez względu na to, czy używam polecenia, +
czy \;
na jego końcu.
Jaki jest tego powód?
find..exec
potrafi samodzielnie radzić sobie z dziwnymi nazwami plików.Pytanie składa się z dwóch części:
find
sobie z wywoływaniem programów-exec
bez problemów ze spacjami osadzonymi w nazwach plików, oraz-print0
opcja?Po pierwsze,
find
jest to wywołanie systemowe, a właściwie jedna z grupy powiązanych wywołań zwanych „exec” . Przekazuje nazwę pliku jako argument bezpośrednio do tego wywołania, które następnie jest przekazywane bezpośrednio (po utworzeniu nowego procesu) bez utraty informacji o nazwie pliku.POSIX
find
cechą+
jest wyjaśnione następująco w przesłankach :Ten „ w szczególności
-print0
podstawowy” odnosi się do GNUfind
ixargs
który rozwiązuje ten problem w inny sposób. Jest także obsługiwany przez FreeBSDfind
ixargs
. Jeśli dodałeś-0
opcję (patrz strona instrukcji ) doxargs
wywołania, wówczas ten program akceptuje linie zakończone znakami „null byte”. Z koleixargs
wywołuje exec -functions, aby wykonać swoją pracę. Główne rozróżnienie między-print0
i-0
a+
cechą polega na tym, że ten pierwszy przekazuje nazwy plików przez potok, a drugi nie. Programiści znajdują zastosowania dla prawie każdej funkcji; rury nie są wyjątkiem.Powrót do przykładu OP, w którym zastosowano
-t
opcjęcp
: nie znaleziono w POSIX cp . Jest to raczej rozszerzenie (inaczej „niestandardowa funkcja”) dostarczone przez GNU cp .-0
Rozszerzeniexargs
nie poprawi ten przykład, ale istnieją inne przypadki, w których może być skutecznie wykorzystywane-pamiętając, że istnieje alternatywa przenośny+
, który GNUfind
akceptuje.źródło
( To powinien być komentarz, ale jest za duży. )
Dla tych, którzy lubią wypróbować:
Utwórz skrypt zawierający parametry pozycyjne przekazane, wywołaj go
list_positional_parameters.sh
.Uruchom
find
go w katalogu $ dir:Zgodnie z oczekiwaniami we wszystkich wywołaniach jest tylko jeden parametr, nazwa pliku, niezależnie od tego, czy w nazwie znajdują się spacje.
źródło
printf
jakprintf '"%s"\n' "$@"
wydrukować wszystkie pozycyjnym argumentu cytowany dla inspekcji wzrokowej.