POSIXly, useresti pax
in modalità read + write con l' -l
opzione:
pax -rwlpe -s /A/B/ dirA .
( -pe
Conserva tutti i possibili attributi di file (in questo caso solo directory) che vengono copiati, come GNU cp
's -a
fa).
Ora, sebbene standard , quel comando non è necessariamente molto portatile .
Innanzitutto, molti sistemi basati su GNU / Linux non includono pax
per impostazione predefinita (anche se si tratta di un'utilità POSIX non opzionale).
Quindi, una serie di bug e non conformità con alcune implementazioni causano una serie di problemi con quel codice.
- a causa di un bug, Solaris 10
pax
(almeno) non funziona se utilizzato -rwl
in combinazione con -s
. Per qualche motivo, sembra che applichi la sostituzione sia al percorso originale che a quello copiato. Quindi sopra, tenterebbe di fare un po ' link("dirB/file", "dirB/file")
invece di link("dirA/file", "dirB/file")
.
- su FreeBSD,
pax
non crea hardlink per file di tipo symlink (un comportamento consentito da POSIX). Non solo, ma applica anche la sostituzione alle destinazioni dei collegamenti simbolici (un comportamento non consentito da POSIX). Così, per esempio, se c'è un foo -> AA
link simbolico a dirA
, diventerà foo -> BA
in dirB
.
Inoltre, se vuoi fare lo stesso ma con percorsi di file arbitrari il cui contenuto è archiviato $src
e $dst
, è importante rendersi conto che pax -rwl -- "$src" "$dst"
crea l'intera struttura di directory di $src
inside $dst
(che deve esistere ed essere una directory). Ad esempio, se $src
è foo/bar
, quindi, $dst/foo/bar
viene creato.
Se invece vuoi $dst
essere una copia di $src
, il più semplice è probabilmente farlo come:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(che aggirerebbe anche la maggior parte dei problemi sopra menzionati ma fallirebbe se il percorso assoluto $dst
termina in caratteri di nuova riga).
Ora questo non sarà di aiuto sui sistemi GNU / Linux dove non c'è pax
.
È interessante notare che è pax
stato creato da POSIX per unire le funzionalità dei comandi tar
e cpio
.
cpio
è un comando Unix storico (dal 1977) in contrapposizione a un'invenzione POSIX, e c'è anche un'implementazione GNU (non una pax
). Quindi, anche se non è più un comando standard (era in SUSv2), è comunque molto comune e c'è un set base di funzionalità su cui di solito puoi fare affidamento.
L'equivalente di pax -rwl
sarebbe cpio -pl
. Però:
cpio
accetta l'elenco di file di input su stdin anziché su argomenti (delimitato da nuova riga, il che significa che i nomi di file con caratteri di nuova riga non sono supportati)
- Tutti i file devono essere specificati (in genere si alimenta l'output di
find
( find
e cpio
sono stati sviluppati congiuntamente dalle stesse persone)).
- i metadati non vengono conservati (alcune
cpio
implementazioni hanno opzioni per preservarne alcune, ma nulla di portatile).
Quindi con cpio
:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
pax
su FreeBSDcp -a
non sono presenti collegamenti simbolici.