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не посилається на жорстке посилання.