POSIXly, ви б використовували pax
в режимі читання + запису з -l
опцією:
pax -rwlpe -s /A/B/ dirA .
( -pe
Зберігає всі можливі атрибути файлів (в даному випадку тільки каталоги), які копіюються, як GNU cp
«s -a
робить).
Тепер, хоч і стандартна , ця команда не обов'язково є дуже портативною .
По-перше, багато систем на базі GNU / Linux pax
за замовчуванням не включають (навіть якщо це необов'язкова утиліта POSIX).
Тоді, кілька помилок та невідповідностей із кількома реалізаціями спричиняють ряд проблем із цим кодом.
- через помилку, Solaris 10
pax
(принаймні) не працює при використанні -rwl
в поєднанні з -s
. З якоїсь причини, здається, застосовується підміна як до оригінального, так і до скопійованого шляху. Отже вище, це намагатиметься зробити link("dirB/file", "dirB/file")
замість цього link("dirA/file", "dirB/file")
.
- у FreeBSD
pax
не створює жорстких посилань для файлів типу symlink (поведінка, дозволена POSIX). Мало того, але це також застосовує підстановку до цілей символьних посилань (поведінка, яку не дозволяє POSIX). Наприклад, якщо в ньому є foo -> AA
симпосилання dirA
, воно стане foo -> BA
в dirB
.
Крім того, якщо ви хочете зробити те саме, але з довільними шляхами до файлів, вміст яких зберігається $src
і $dst
, важливо усвідомити, що pax -rwl -- "$src" "$dst"
створюється повна структура каталогу $src
всередині $dst
(що має існувати і бути каталогом). Наприклад, якщо $src
є foo/bar
, то $dst/foo/bar
створюється.
Якщо замість цього ви хочете $dst
бути копією $src
, найпростіше, мабуть, зробити це як:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(що також вирішить більшість проблем, згаданих вище, але не вдасться, якщо абсолютний шлях $dst
закінчується символами нового рядка)
Тепер це не допоможе в системах GNU / Linux там, де їх немає pax
.
Цікаво зазначити, що pax
створений POSIX для об'єднання функцій команд tar
та cpio
.
cpio
- це історична команда Unix (з 1977 р.) на відміну від винаходу POSIX, а також є реалізація GNU (не pax
одна). Тож навіть якщо це вже не стандартна команда (хоча це було в SUSv2), вона все ще дуже поширена, і є основний набір функцій, на який зазвичай можна покластися.
Еквівалент pax -rwl
був би cpio -pl
. Однак:
cpio
приймає список вхідного файлу на stdin на відміну від аргументів (новий рядок, що означає, що імена файлів із символами нового рядка не підтримуються)
- Усі файли повинні бути вказані (як правило, ви подаєте їм вихід
find
( find
і cpio
були розроблені спільно тими самими людьми)).
- метадані не зберігаються (у деяких
cpio
реалізаціях є параметри збереження деяких, але нічого портативного).
Так і з cpio
:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
pax
, на FreeBSD,cp -a
не посилається на жорстке посилання.