Copie Linux vers le système de fichiers fat32: argument non valide

12

Lorsque je copie des fichiers d'une partition ext3 vers une partition fat32 en utilisant cp:

cp -R /ext3/stuff /fat32/partition/

J'obtiens des messages d'argument invalides pour tous les fichiers avec des deux-points et des points d'interrogation.

Existe-t-il un moyen d'obtenir que cp supprime les caractères non valides pour le système de fichiers cible?

edit: J'ai vérifié à nouveau les options de cp, et à moins que je sois stupide, il n'y a rien là-dedans. Je suis sûr que je pourrais écrire un script, mais il semble qu'il devrait y avoir une solution plus propre!

mo-seph
la source

Réponses:

10

Les suspects habituels lorsque vous voulez des copies complexes ou des renommages sont GNU cp, zmv de zsh, rsync et pax (ou cpio). Il n'y a pas de fonction de renommage dans cp, ni (je pense) dans rsync. Bien que zmv puisse renommer, cela ne correspond pas bien aux copies récursives. Mais pax peut le faire:

cd /ext3
pax -rw -s '/[*?:]/_/gp' stuff /fat32/partition

Cela change chacun *?:en _. Attention: peu testé. S'il y a des collisions, le dernier fichier copié l'emporte.

Gilles 'SO- arrête d'être méchant'
la source
Bien - je n'ai jamais utilisé pax auparavant. Merci de m'y avoir mis.
mo-seph
1
La barre oblique inverse crée également des problèmes pour vfat. Incluez-le également dans l'expression rationnelle. Merci!
lzap
La liste complète selon support.grouplogic.com/?p=1607 est: /? <> \: * | ”^. Il ne peut pas non plus se terminer par un espace ou un point et certains noms sont réservés. La page de manuel de Mtools donne une liste encore plus longue:,; :? + * = [] <> '"\ / |
dhill
Et une note différente et pour les personnes ayant le même problème que moi: pax ne prend pas en charge l'utilisation de -s en combinaison avec la commande de mise à jour -u. C'est-à-dire qu'il copiera toujours les fichiers renommés à nouveau, même s'ils existent déjà. Il m'a fallu des heures pour en savoir plus .
balu
11

Sur la base d'un article de Gilles, j'ai testé la liste suivante:

#!/bin/sh
touch questionmark?
touch less<
touch less\<
touch more\>
touch backslash\\
touch colon:
touch asterisk\*
touch pipe\|
touch inch\"
touch carret\^
touch comma,
touch semicolon\;
touch plus+
touch equals=
touch lbracket[
touch rbracket]
touch quote\'

J'ai essayé de copier cela sur la carte MicroSDHC du téléphone Android avec le système de fichiers vfat et la paxcommande affinée jusqu'à ce que tout fonctionne. Cela peut ne pas être suffisant pour Windows et Unicode:

pax -rw -s '/[?<>\\:*|\"]/_/gp' source dest

Vous pouvez également utiliser l'option -k pour vous assurer qu'il n'y a pas d'écrasements (en raison de collisions dans les noms de fichiers). Les deux listes que j'ai données dans le commentaire étaient différentes du comportement vfat de Linux.

dhill
la source
0

J'ai reçu l '"argument non valide" lors de la copie avec la clé USB cp -r source et j'ai découvert que la cause était un nom de fichier source se terminant par un espace. La suppression de l'espace a effacé le message. Le fichier avec un nom incorrect s'est produit dans ce cas BTW dans les répertoires du programme de messagerie.

JohanArnold
la source
0

J'avais juste besoin de faire cela, et bien que la paxréponse basée sur soit bonne, elle rencontrait toujours des problèmes avec les caractères accentués.

J'ai donc trouvé plus simple à utiliser taret à remplacer tous les caractères non autorisés par des traits de soulignement:

cd /parent-of-source
tar cf - Söurce | (cd /destination; tar xvf - --transform='s/[^A-Za-z0-9\/ ]/_/g')

Il est sans doute possible de proposer une meilleure liste de caractères autorisés que celle ci-dessus, mais cela fonctionne.

Chapelier Fou
la source
0

Après avoir lu les réponses à cette question très intéressante et fait quelques expériences avec la carte SD pour Android (exfat) et un système de divertissement automobile (vfat), je suis venu avec ce petit script bash.

#! /bin/bash

DST=$1
# copy music to FAT media

find music/ Music/ -type f | while read f ; do
    d=$DST/$( echo $f | sed 's/[^-A-Za-z0-9/._ ()]/_/g' )

    echo :$d:
    mkdir -p "$(dirname "$d")"
    cp -n "$f" "$d"

done

Il prend la destination (point de montage) comme argument et utilise findpour localiser tous les fichiers dans mon référentiel musical.

Pour chaque chemin de fichier, il calcule un chemin de destination et un nom de fichier en ajoutant la destination et en remplaçant tout caractère incriminé par un trait de soulignement _. J'utilise une liste blanche de caractères (lettres, chiffres, -, /, ., . (, )Et _) pour enlever toute ponctuation non désirée.

Selon les paramètres régionaux, cela laissera des lettres accentuées dans le chemin et le nom de fichier, ce qui est OK pour les systèmes de fichiers FAT modernes, comme il semble.

Pour chaque chemin et nom de fichier de destination, les répertoires sont créés selon les besoins à l'aide de mkdir -p, puis le fichier est copié, sauf s'il existait déjà.

Notez les "caractères de citation à divers endroits, ils sont nécessaires pour empêcher les chemins et les noms avec des espaces de se séparer.

Ber
la source