Forum général.général cygwin noms de fichiers avec espaces et tirets

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
22
juil.
2022

Bonjour,

Alors je suis certaine que le sujet a déjà été abordé ici, mais je suis nouvelle et c'est un tout petit peu compliqué de s'y retrouver sur ce forum.

J'utilise cygwin depuis de nombreuses années, mais hélas je n'ai jamais vraiment trouvé comment le configurer. Personne ne semble avoir jamais écrit de bouquin ou créé de site en français sur le sujet, ce qui m'a toujours étonnée car c'est un linux génial qui tient bien la route, et le peu que j'ai trouvé en anglais est imbuvable à lire.

Je demande donc à une âme charitable qui serait déjà passée par là de bien vouloir m'aider à faire en sorte que les chemins Windows comportant des espaces et/ou des tirets soient reconnus lors d'un ls sans être coupés en morceaux. A priori ce serait la variable d'environnement CYGWIN qu'il faudrait positionner, mais là aussi je ne comprends rien aux explications données en langage rosbif. Le grand défaut des "man" et autres ayant été de tous temps de ne pas comporter d'exemples significatifs…

Merci d'avance pour votre aide.

  • # exemple ?

    Posté par  (site web personnel, Mastodon) . Évalué à 2.

    Salut,
    Je n'ai pas souvenir d'avoir rencontré ce souci, mais je ne peux vérifier là. Peux-tu donner un exemple avec : chemin complet, résultat fourni par ls, résultat attendu ?

    “It is seldom that liberty of any kind is lost all at once.” ― David Hume

  • # séparation d'arguments

    Posté par  . Évalué à 4. Dernière modification le 22 juillet 2022 à 18:33.

    Bonjour

    Un caractère espace est considéré comme un caractère de séparation (d'arguments dans une ligne de commande(s) par exemple)

    Si tu veux utiliser un nom de fichier dans lequel il y a un caractère espace,
    comme par exemple pour un fichier qui serait nommé :
    nouveau fichier.txt

    il faut entourer ce nom de fichier par des guillemets comme ça :
    "nouveau fichier.txt"

    avec la commande ls ça donnerait :

    ls "nouveau fichier.txt"
    

    Sinon, comme le caractère espace est considéré comme un caractère de séparation,
    avec :

    ls nouveau fichier.txt
    

    la commande ls va rechercher 2 fichiers :
    - un fichier nommé nouveau
    - un fichier nommé fichier.txt

    et il comme est possible qu'aucun de ces fichiers n'existe dans le répertoire courant,
    alors ça va donner :

    michel@deb1104:~$ ls nouveau fichier.txt
    ls: impossible d'accéder à 'nouveau': Aucun fichier ou dossier de ce type
    ls: impossible d'accéder à 'fichier.txt': Aucun fichier ou dossier de ce type
    michel@deb1104:~$ 
    

    C'est le même principe pour les noms de chemin.

  • # caractère d'échappement

    Posté par  . Évalué à 4. Dernière modification le 22 juillet 2022 à 18:41.

    Une autre solution consiste à échapper le caractère espace en le faisant précéder du caractère \

    ce qui donne :

    michel@deb1104:~$ ls nouveau\ fichier.txt
    'nouveau fichier.txt'
    michel@deb1104:~$ 
    

    et aussi :

    michel@deb1104:~$ ls -l /home/michel/mon\ chemin\ avec\ des\ espaces/fichier.txt 
    -rw-r--r-- 1 michel michel 0 22 juil. 18:34 '/home/michel/mon chemin avec des espaces/fichier.txt'
    michel@deb1104:~$ 
    
  • # manuel bash

    Posté par  . Évalué à 1.

    Voir aussi :

    Le chapitre PROTECTIONS dans le manuel de l'interpréteur de commandes bash
    en lançant la ligne de commande suivante :

    man --pager='less -p "PROTECTIONS"' bash
    

    le même chapitre, mais dans la version originale (non traduite) du manuel de l'interpréteur de commandes bash
    en lançant la ligne de commande suivante :

    LANG=C man --pager='less -p "QUOTING"' bash
    
  • # auto-completion

    Posté par  . Évalué à 4.

    Tu peux aussi utiliser l'auto-completion automatique
    qui complétera pour toi le nom de la commande, de l'option, du fichier ou autre suivant le contexte.

    Supposons qu'il existe 3 fichiers nommés :

    nouveau_texte.txt
    nouveau fichier.txt
    nouveau plan pour devenir calife à la place du calife.txt

    et que je veuille utiliser un de ces trois fichiers à la suite de la commande ls

    mais que je n'aie pas du tout envie de me fatiguer à entrer tous ces caractères d'échappement avant chaque caractère espace, ou bien que je ne me souvienne plus très bien du nom entier du nom de fichier que je voudrais utiliser.

    Alors je vais le faire faire par l'auto-completion.


    Donc, je commence par entrer la commande que je veux utiliser, par exemple : ls
    et je ne vais entrer que les premières lettres du nom du fichier pour laisser l'auto-completion faire le reste.

    Je tape donc ls nouv ce qui donne :

    michel@deb1104:~$ ls nouv
    

    et, sans appuyer sur la touche entrée, je tape ensuite une seule fois sur la touche de tabulation,
    et voilà ce que ça donne :

    michel@deb1104:~$ ls nouveau
    

    s'il n'y avait qu'un seul fichier dont le nom commençait par les 4 lettres que j'avais tapées, en tapant ensuite sur la touche de tabulation l'auto-completion aurait automatiquement complété la ligne de commande avec le nom de ce seul fichier,
    et je n'aurais plus qu'à valider la ligne de commande affichée pour qu'elle soit lancée.

    Mais dans mon cas, il existe plusieurs noms de fichiers dont le nom commence par ces 4 lettres, alors l'auto-completion n'a pu ajouter que le début du nom qui est commun à ces trois noms de fichier : nouveau

    Comme ça m'énerve qu'il ne fasse pas ce que j'aimerai bien qu'il fasse,
    j'insiste alors en tapant deux fois de plus sur la touche de tabulation,
    et voilà ce que ça donne :

    michel@deb1104:~$ ls nouveau
    nouveau fichier.txt
    nouveau plan pour devenir calife à la place du calife.txt
    nouveau_texte.txt
    michel@deb1104:~$ ls nouveau
    

    à ce stade, il y a plusieurs possibilités :

    soit je tape le caractère _
    ce qui va donner :

    michel@deb1104:~$ ls nouveau_
    

    et si je tape ensuite sur la touche de tabulation, l'auto-completion complétera le nom du fichier, ce qui donnera :

    michel@deb1104:~$ ls nouveau_texte.txt 
    

    et je n'ai plus qu'à valider la ligne de commande affichée pour la lancer.


    … ou alors, je complète manuellement par le début d'un des deux autres noms de fichiers existants :

    en tapant à la suite, par exemple : \ f
    ce qui va donner :

    michel@deb1104:~$ ls nouveau\ f
    

    et si je tape ensuite sur la touche de tabulation, l'auto-completion complétera le nom du fichier, ce qui donnera :

    michel@deb1104:~$ ls nouveau\ fichier.txt 
    

    et je n'ai plus qu'à valider la ligne de commande affichée pour la lancer.


    ou alors je tape à la suite \ p
    ce qui va donner :

    michel@deb1104:~$ ls nouveau\ p
    

    et si je tape ensuite sur la touche de tabulation l'auto-completion complétera le nom du fichier,
    ce qui donnera :

    michel@deb1104:~$ ls nouveau\ plan\ pour\ devenir\ calife\ à\ la\ place\ du\ calife.txt 
    

    et je n'ai plus qu'à valider la ligne de commande affichée pour la lancer.

    et voilà.

  • # ls sans arguments

    Posté par  . Évalué à 3.

    @Gil Cot plein d'exemples sont donnés par MicP que je remercie pour ses explications détaillées, mais le problème est tout autre.

    En effet, je souhaite lister le contenu d'un dossier et donc je lance le ls seul. Et s'il existe dedans un dossier nommé par exemple "truc - machin", le ls va me ramener plusieurs noms pour dire ensuite qu'il ne trouve pas les fichiers truc, - et machin. Mon but étant de boucler sur la liste des noms pour faire un traitement (ici lancer des zips sur des noms de dossiers, donc créer une archive nommée 'truc - machin.7z').

    Ce qui est bête, c'est qu'en ligne de commande du bash les noms sont automatiquement escapés et/ou entourés par des quotes. C'est dans le script que le ls les morcèle. C'est sûrement une histoire de variable d'environnement, mais laquelle :/

    • [^] # Re: ls sans arguments

      Posté par  (site web personnel) . Évalué à 4.

      Si l'idée est d'itérer sur des chemins (fichiers, répertoires, autres — en appliquant ou non des filtres sur les noms, extensions, tailles, dates de dernière modification, profondeur de répertoires, etc.), la combinaison d'outils find et xargs est très largement supérieure à ls (même si en connaissant ls depuis toujours ou presque, c'est tentant et légitime de vouloir balancer sa sortie dans un tube).

      Quelques options pratiques pour la combinaison :

      • find : -print0
      • xargs : -0 et -r

      Quant à ls (même si je ne recommande pas de poursuivre dans cette voie), l'échappement est contrôlable via --quoting-style. Pour les détails d'implémentation, voir les fonctions et variables contenant quoting_style dans src/ls.c (paquet coreutils), notamment decode_switches().

      Debian Consultant @ DEBAMAX

    • [^] # Re: ls sans arguments

      Posté par  (site web personnel, Mastodon) . Évalué à 2.

      Ce que je demandais comme exemple, c'est un exemple de commande qui te pose problème avec ls

      En effet, je souhaite lister le contenu d'un dossier et donc je lance le ls seul. Et s'il existe dedans un dossier nommé par exemple "truc - machin", le ls va me ramener plusieurs noms pour dire ensuite qu'il ne trouve pas les fichiers truc, - et machin.

      Sans l'exemple on ne voit pas exactement de quoi tu parles. Là j'imagine que tu fais un ls truc - machin et que tu voudrais plutôt faire un ls "truc - machin" ou ls 'truc - machin' ou ls truc\ \-\ machin … Mais finalement non, tu étais dans un script

      Ce qui est bête, c'est qu'en ligne de commande du bash les noms sont automatiquement escapés et/ou entourés par des quotes. C'est dans le script que le ls les morcèle.

      OK, comme mentionné par Cyrille, il te faut utiliser le couple find et xargs et ne pas boucler sur le retour de ls parce-que le for sur le résultat va prendre chaque morceau délimité par un blanc et ne sait pas distinguer chaque chemin séparément.
      Met set +x avant le/la groupe/ligne d'appel de la boucle et set -x après et observe la sortie pour mieux comprendre la problématique.

      “It is seldom that liberty of any kind is lost all at once.” ― David Hume

      • [^] # Re: ls sans arguments

        Posté par  . Évalué à -3.

        Trop d'hostilité, laisse tomber.

        • [^] # Re: ls sans arguments

          Posté par  . Évalué à 4. Dernière modification le 23 juillet 2022 à 12:32.

          Quand on voit le nombre de réponses et leur longueur, on se demande ce qu'il te faut de plus. Tu t'attendais peut-être à un câlin ?

          Plus sérieusement, ce genre de réaction et l'absence de remerciements de ta part ne peuvent que dégoûter les gens d'aider.

          Enfin ça ne sert à rien de parler à un mur qui ferme son compte pour aller bouder.

          Les vrais naviguent en -42

    • [^] # Re: ls sans arguments

      Posté par  . Évalué à 1. Dernière modification le 23 juillet 2022 à 04:47.

      … C'est dans le script que le ls les morcèle …
      

      Dommage que tu le l'aies pas précisé dans ton premier message,
      car comme tu as pu le constater, le contexte (surtout celui-là) est très important,
      et si je l'avais connu, je ne me serai pas emm…bêté à rédiger tout ça pour rien.

      Et il manque encore des informations toutes aussi importantes, comme par exemple le nom de l'interpréteur de commandes qui va devoir utiliser ce script.

      Le but détaillé de ce script serait aussi un plus car il est fort possible que toutes les aides qui seront fournies ne servent à rien s'il existe finalement une méthode beaucoup plus simple pour arriver au même but.

      Il faudrait aussi un échantillon représentatif du ou des noms du ou des répertoires qui vont êtres utilisés ainsi que leur contenu car il est possible que certains caractères puissent ajouter d'autres contraintes ce qui pourrait entraîner un changement radical de méthode rendant de ce fait toutes les propositions qui seront faîtes inappropriées et donc inutiles.

      Finalement, un simple copié de ce que tu as déjà tenté de faire avec le résulta de ce que ça a donné sera beaucoup plus efficace qu'une description confuse qui prête logiquement à confusion.


      Par principe, n'utilise jamais la commande ls dans un script, et, si l'interpréteur de commandes qui va utiliser ton script est bien bash, alors lis le chapitre du manuel de l'interpréteur de commandes bash que je t'ai conseillé d'aller lire, ça te sera très certainement très utile et pas seulement dans le cas de l'utilisation de la commande ls

    • [^] # Re: ls sans arguments

      Posté par  . Évalué à 2.

      OK, je me doutais bien qu'il y avait autre chose.

      Précision avant de continuer (peut-être déjà faite dans les autres commentaires que je n'ai pas tous lu) : Cygwin n'est pas un Linux, c'est un environnement POSIX. L'OS reste Windows derrière.
      Exemple : j'ai découvert il y a longtemps que Cygwin permettait de créer des liens symboliques avec ln -s .... C'est fou, ça apparaît même dans l'explorateur de fichier Windows, avec un petit icône en forme de flèche jamais vu jusque-là. Et ça marche ! Jusqu'à ce que ça ne marche plus … C'est Windows …
      Fin de la parenthèse.

      Donc, en fait, l'idée est de traiter la sortie de ls. Le problème n'est pas dans le ls lui-même.

      • Solution 1 :
      ls <arguments> | while read f
      do
          jeFaisQuelqueChoseAvec "$f"
      done
      
      • Solution 2 :
      while read f
      do
          jeFaisQuelqueChoseAvec "$f"
      done< <(ls <arguments>)
      

      (NB: la syntaxe après le done, c'est de tête, non garantie. J'ai toujours un peu de mal à m'en rappeler sans avoir d'exemple sous les yeux)

      Le ls <arguments>) peut aussi bien être remplacé par un find comme suggéré dans d'autres commentaires. Ou toute autre combinaison de ce qui permet de créer et filtrer une liste de fichiers.

      Je laisse en exercice : déterminer pourquoi la solution 2 est le plus souvent à préférer sur la solution 1 …

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.