Page 1 sur 1

Apostrophe dans un nom de fichier sous Linux

Posté : 02 juin 2007, 11:38
par owsion
Bonjour,
Avez-vous une idée pour traiter les apostrophes dans les noms des fichiers? Par ex. la commande exec("ls -l /music/J'ai dix ans.mp3") ne fonctionne pas à cause de l'apostrophe.
Merci de votre aide.

Version PHP : 5.1.2

Posté : 02 juin 2007, 12:44
par jpaul
Bonjour,
As-tu essayé de protéger l'apostrophe avec une barre oblique inversée ?
Comme ceci :

Code : Tout sélectionner

exec("ls -l /music/J\'ai dix ans.mp3")

Posté : 02 juin 2007, 12:44
par Cyrano
Sous Linux, un nom de fichier ne peut comporter ni espaces ni caractères spéciaux : ceci ne fonctionne que sous Windows qui est beaucoup plus laxiste en la matière. Donc renomme tes fichiers si tu veux que ça fonctionne convenablement.

Posté : 02 juin 2007, 12:56
par owsion
Re à tous,

merci de vos réponses.
Pour jpaul, oui, j'ai essayé toute sorte d'échappement (antislash, double, triple, apostrophe, guillemet...) Rien ne fonctionne.

Pour Cyrano, lorsque j'envoie la commande ls via un telnet sur le serveur Linux, tout fonctionne parfaitement. J'ai néanmoins constaté que tous les espaces et caractères spéciaux étaient échappés par un antislash.

J'ai effectivement aussi pensé à remplacer l'apostrophe par "autre chose", mais la langue française à la fâcheuse manie d'en faire un usage fréquent (titre de chansons, de films,...).
Une solution codée serait donc la bienvenue.

Merci encore de vos conseils.

Posté : 02 juin 2007, 13:26
par Cyrano
Regarde sur le site le tuto sur l'upload de fichiers, il y a une partie sur la ré-écriture des noms de fichiers pour remplacer tous les caractères spéciaux.

Posté : 02 juin 2007, 16:31
par Ripat
As-tu songé à échapper l'espace?
echo exec("ls -l /tmp/j\'ai\ nonante\ ans.mp3" );

Posté : 03 juin 2007, 07:55
par owsion
Bonjour à toutes et tous,

merci de vos réponses.

@Cyrano: J'ai lu attentivement le tuto ainsi que les renvois vers php.net. Intéressant, mais je n'y trouve quand même pas mon bonheur. En fait, j'ai référencé ma CD-thèque (ie fais des copies de mes CD en mp3) sur des disques montés sous Linux. Le tout est dans une BD mysql qui donne d'autres infos et permet des tris et recherches. Lorsque je choisis un fichier via mon mediacenter, le fichier est téléchargé et le nom est donné par la BD, tel que trouvé initialement sur le disque. J'ai donc, à la base, utilisé un logiciel d'analyse et de compression pour copier mes CD et ce logiciel a aussi extrait les apostrophes et les espaces...de là mon problème. La solution à laquelle j'aboutis est de remplacer les ' des noms de mes fichiers par un caractère valide non utilisé permettant ainsi de na pas perdre d'information lors d'une potentielle reconstruction de la base. Ce travail devrait être fait soit manuellement (très désagréable puisque j'ai >30'000 fichiers), soit par un programme avec les problèmes que ça suppose (par ex. j'avoue ignorer le comportement à l'exécution d'un programme Java sur le fs Linux...php ayant déjà montré ses limites!).

@Ripat: oui, ça aussi je l'ai essayé. Est-ce que chez toi ça fonctionne? Si oui, quelles versions as-tu de php et de Linux (Redhat?).

Posté : 03 juin 2007, 12:11
par Ripat
Debian etch / php5

Quel message d'erreur le shell renvoie t-il ? Fais une redirection de stderr vers stdout.
echo exec("ls -l /tmp/j\'ai\ nonante\ ans.mp3  2>&1"); 
Sinon lorsque tu fais un ls nom du fichier avec le tab completion du shell, qu'est-ce que ça donne à l'écran (en shell).

Posté : 03 juin 2007, 16:25
par owsion
Bonjour Ripat,

l'exécution dans le shell n'a pas l'air de donner le moindre résultat. Je fouille dans les logs.

Concernant l'exécution de ls, voici la commande et son résultat:

glycine> ls -l /volume2/music2/CD\ PRIVE/Alain\ Souchon/Alain\ Souchon/01\ -\ J\'ai\ dix\ ans.mp3
-rwxrwxrwx 1 guest users 4469114 Feb 3 2006 /volume2/music2/CD PRIVE/Alain Souchon/Alain Souchon/01 - J'ai dix ans.mp3

Merci de l'attention que tu as portée à mon problème.

Posté : 03 juin 2007, 20:45
par Ripat
Montre ton code PHP?

Posté : 03 juin 2007, 21:03
par Invité
Bonsoir Ripat

voici le code

Code : Tout sélectionner

echo "Result1 = ".exec("ls -l '/volume2/music2/CD PRIVE/Alain Souchon/Alain Souchon/10 - Papa mambo.mp3'"); echo "Result1* = ".exec("ls -l '/volume2/music2/CD\ PRIVE/Alain\ Souchon/Alain\ Souchon/10\ -\ Papa\ mambo.mp3'"); echo "Result2 = ".exec("ls -l '/volume2/music2/CD PRIVE/Alain Souchon/Alain Souchon/01 - J\'ai dix ans'"); echo "Result3 = ".exec("ls -l '/volume2/music2/CD\ PRIVE/Alain\ Souchon/Alain\ Souchon/01\ -\ J\'ai\ dix\ ans'");
Seule la première commande fonctionne. J'ai aussi tenté d'inverser les guillemets et les apostrophes, mais en vain. Merci de ton aide.

Posté : 03 juin 2007, 23:02
par Hubert Roksor
Pour info, je viens de tester ça avec succès sous PHP 5.2.2

fichier a b
exec('ls -l "a b"');
fichier a"b
exec('ls -l "a\\"b"');

Posté : 04 juin 2007, 13:09
par Ripat
Pourquoi encadres-tu le nom du fichier par des quotes? Que donne:
echo exec("ls -l /volume2/music2/CD\ PRIVE/Alain\ Souchon/Alain\ Souchon/01\ -\ J\'ai\ dix\ ans"); 

// et en cas d'échec:
echo exec("ls -l /volume2/music2/CD\ PRIVE/Alain\ Souchon/Alain\ Souchon/01\ -\ J\'ai\ dix\ ans 2>&1"); 
Tous les espaces doivent être échappés. Même ceux du path.

Edit

Et pourquoi pas les fonctions natives PHP?
filectime() — Renvoie la date de dernier accès à un inode
filegroup() — Lire le nom du groupe
fileinode() — Renvoie le numéro d'inode du fichier
filemtime() — Renvoie la date de dernière modification du fichier
fileowner() — Renvoie le nom du propriétaire du fichier
fileperms() — Renvoie les permissions affectées à un fichier
filesize() — Renvoie la taille d'un fichier
filetype() — Retourne le type de fichier

Posté : 07 juin 2007, 14:05
par owsion
Bonjour tout le monde,

désolé de répondre si tardivement (pour cause d'absence prof.). J'ai fait les tests que vous avez suggérés et dont je vous remercie. En vain. C'est sans doute lié à la version de PHP ou de Linux que j'utilise.

La proposition de passer par les fonctions natives est, à défaut, la meilleure car de cette façon ça marche. Etrange, non? Je conviens qu'on s'affranchit ainsi d'un niveau de guillemet/apostrophe.

Par ex., la commande:

Code : Tout sélectionner

echo "Taille: ".filesize("/volume2/music2/CD PRIVE/Alain Souchon/Alain Souchon/01 - J'ai dix ans.mp3");
fonctionne parfaitement.

Vu les modifs à répercuter dans le code, je serais quand même intéressé à trouver la solution du problème.

Merci et à bientôt.