POSIXly, vous utiliseriez paxen mode lecture + écriture avec l’ -loption:
pax -rwlpe -s /A/B/ dirA .
( -peConserve tous les attributs possibles des fichiers (dans ce cas seulement les répertoires) qui sont copiés, comme GNU cpde -afait).
Maintenant, bien que standard , cette commande n'est pas nécessairement très portable .
Premièrement, de nombreux systèmes basés sur GNU / Linux n'incluent pas paxpar défaut (même s'il s'agit d'un utilitaire POSIX non facultatif).
Ensuite, un certain nombre de bugs et de non-conformités avec quelques implémentations causent un certain nombre de problèmes avec ce code.
- à cause d’un bogue, Solaris 10
pax(au moins) ne fonctionne pas -rwlen combinaison avec -s. Pour une raison quelconque, il semble qu'il applique la substitution à la fois au chemin d'origine et au chemin copié. Donc ci-dessus, il essaierait d'en faire link("dirB/file", "dirB/file")au lieu de link("dirA/file", "dirB/file").
- sous FreeBSD,
paxne crée pas de liens physiques pour les fichiers de type symlink (comportement autorisé par POSIX). De plus, il applique également la substitution aux cibles des liens symboliques (comportement non autorisé par POSIX). Ainsi, par exemple, s'il y a un foo -> AAlien symbolique dans dirA, il deviendra foo -> BAdans dirB.
De plus, si vous voulez faire la même chose, mais avec des chemins de fichiers arbitraires dont le contenu est stocké dans $srcet $dst, il est important de réaliser que pax -rwl -- "$src" "$dst"crée la structure de répertoires complète de $srcinside $dst(qui doit exister et être un répertoire). Par exemple, si $srcest foo/bar, alors, $dst/foo/barest créé.
Si au lieu de cela, vous voulez $dstêtre une copie de $src, le plus simple est probablement de le faire comme:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && pax -rwlpe . "$absolute_dst")
(ce qui contournerait également la plupart des problèmes mentionnés ci-dessus mais échouerait si le chemin absolu de $dstfins se termine par des caractères de nouvelle ligne).
Maintenant, cela ne va pas aider sur les systèmes GNU / Linux où il n'y a pas pax.
Il est intéressant de noter que paxPOSIX a été créé pour fusionner les fonctionnalités des commandes taret cpio.
cpioest une commande Unix historique (à partir de 1977) par opposition à une invention POSIX, et il existe également une implémentation GNU (pas une pax). Ainsi, même s’il ne s’agit plus d’une commande standard (c’est le cas dans SUSv2), elle reste très courante et comporte un ensemble de fonctionnalités de base sur lesquelles vous pouvez généralement compter.
L'équivalent de pax -rwlserait cpio -pl. Pourtant:
cpio prend la liste du fichier d'entrée sur stdin par opposition aux arguments (délimité par une nouvelle ligne, ce qui signifie que les noms de fichier avec des caractères de nouvelle ligne ne sont pas pris en charge)
- Tous les fichiers doivent être spécifiés (généralement, vous alimentez la sortie de
find( findet cpioont été développés conjointement par les mêmes personnes)).
- les métadonnées ne sont pas préservées (certaines
cpioimplémentations ont des options pour en conserver, mais rien n’est portable).
Donc avec cpio:
absolute_dst=$(umask 077 && mkdir -p -- "$dst" && cd -P -- "$dst" && pwd -P) &&
(cd -P -- "$src" && find . | cpio -pl "$absolute_dst")
paxsur FreeBSD, lescp -aliens symboliques ne sont pas en liens durs.