Pourquoi «ls» encapsule-t-il soudainement les éléments avec des espaces entre guillemets simples?

187

Je viens de remarquer que sur l'une de mes machines (sous Debian Sid), chaque fois que je tape lsun nom de fichier avec des espaces, il est entouré de guillemets simples.

J'ai immédiatement vérifié mes alias, pour les retrouver intacts.

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt
wyatt@debian630:~/testdir$ alias
alias ls='ls --color=auto'
alias wget='wget --content-disposition'
wyatt@debian630:~/testdir$

(image)

Un autre test, avec des fichiers contenant des guillemets simples dans leurs noms (répondant également à une demande de jimmij):

wyatt@debian630:~/testdir$ ls
'test 1.txt'  test1.txt  'thishasasinglequotehere'\''.txt'
wyatt@debian630:~/testdir$ touch "'test 1.txt'"
wyatt@debian630:~/testdir$ ls
''\''test 1.txt'\'''  test1.txt
'test 1.txt'          'thishasasinglequotehere'\''.txt'

(image)

mettre à jour avec la nouvelle sortie de coreutils-8.26 (ce qui est certes beaucoup moins déroutant, mais toujours irritant d’avoir par défaut). Merci à Pádraig Brady pour cette impression:

$ ls
"'test 1.txt'"   test1.txt
'test 1.txt'    "thishasasinglequotehere'.txt"

$ ls -N
'test 1.txt'  test1.txt
test 1.txt    thishasasinglequotehere'.txt

Pourquoi cela arrive-t-il? Comment puis-je l'arrêter correctement?

pour clarifier, j’ai moi-même réglé ls sur la sortie couleur automatique. Il ne met jamais de citations autour de choses avant.

Je suis en cours d'exécution bashet coreutils 8.25.

EDIT: Les développeurs de coreutils ont pensé (lien) que ce serait une bonne idée d’en faire un défaut global malgré la violation du principe de moindre étonnement ainsi que de plus de 46 ans de tradition UNIX.

Un moyen de résoudre ce problème sans recompiler?


MISE À JOUR - Octobre 2017 - Debian Sid a réactivé les citations d'échappement du shell par défaut. C'est juste en train de devenir ridicule. https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877582

Et au bas de la chaîne de réponse au rapport de bogue précédent, "le changement était intentionnel et restera". https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=813164#226

Je pensais que c'était réglé. Apparemment non.

MISE À JOUR: Avril 2019: Je viens de trouver un rapport de bogue volumineux en PHP causé par ce changement ls. Lorsque vous confondez les développeurs et générez de faux rapports de bogues, il est temps de repenser vos modifications.

Mise à jour: Android toybox lsfait maintenant quelque chose de similaire à cela, mais avec des barres obliques inverses au lieu de guillemets. L'utilisation de l'option -q rend les espaces rendus en tant que "points d'interrogation" (je n'ai pas vérifié ce qu'ils sont, car ce ne sont évidemment pas des espaces). Le seul correctif que j'ai trouvé jusqu'à présent sans enraciner le périphérique en question consiste à ajouter ceci dans un script et le source lors du lancement d'un shell. Cette fonction lsutilise des colonnes si elles se trouvent dans un terminal et imprime une ligne par ligne, tout en accédant lsaux espaces d’impression, mot pour mot, car elle passe par un canal.

ls() {
    # only way I can stop ls from escaping with backslashes
    if [ -t 1 ]; then
        /system/bin/ls -C "$@" |cat
    else
        /system/bin/ls "$@" |cat
    fi
}
Wyatt8740
la source
20
Encore une autre raison pour laquelle ne pas analyser la lscommande.
Jimmij
12
Cela semble étrange, mais si elle est activée uniquement lors de l'impression sur un terminal, cela a du sens. Vous pouvez voir clairement que vous avez un fichier 'test 1.txt' plutôt qu'un fichier 'test' et un autre '1.txt'. Essayez de ls | catvoir si ça s'en va. Si j'avais une machine à remonter le temps, je retournerais à Bell Labs ~ 1970 et essayerais de convaincre Ken Thompson que laisser de la place dans les noms de fichiers et de répertoires est une mauvaise idée. :-P
Bjorn Munch le
6
Quand j'ai vu cela pour la première fois, j'ai paniqué, pensant qu'un de mes scripts avait mal tourné et renommé tous mes fichiers '*'. J'imagine que je vais ajouter des lsalias à toutes mes machines pour m'en débarrasser ...
Expiation limitée
14
@LimitedAtonement, comme l'a souligné Lekensteyn , vous pouvez le faire avec une variable d'environnement QUOTING_STYLE=literalplutôt qu'un alias. (Je suppose que c'est une question de goût, mais je préfère la variable.)
LSpice
4
@BjornMunch, il existe deux solutions au problème de savoir s'il s'agit d'un fichier ou deux: 1) cherchez comment les colonnes sont dessinées et cela est assez évident. 2) liste un élément par ligne. Les deux sont plus beaux et plus lisibles que les guillemets simples.
Wyatt8740

Réponses:

132

Préface : Même s’il peut être très satisfaisant de voter une réponse comme celle-ci et de s’appeler un jour, soyez assuré que les développeurs GNU ne s’intéressent pas aux votes SO, et que si vous voulez réellement les encourager à changer , vous devez envoyez-leur un courriel comme le décrit cette réponse.


" Pourquoi est-ce que ça se passe? "

Plusieurs développeurs de coreutils ont décidé qu'ils connaissaient mieux que des décennies de normes de facto.


" Comment puis-je l'arrêter correctement? "

http://www.gnu.org/software/coreutils/coreutils.html :

Rapports de bogues

Si vous pensez avoir trouvé un bogue dans Coreutils, veuillez envoyer un rapport de bogue le plus complet possible à <[email protected]> . Ce rapport sera automatiquement entré dans le suivi des bogues de Coreutils. Avant de signaler des bugs, veuillez lire la FAQ. Le document Comment poser des questions de manière intelligente constitue un guide très utile et souvent référencé sur la manière de rédiger des rapports de bogue et de poser de bonnes questions. Vous pouvez parcourir les publications précédentes et rechercher dans les archives de bug-coreutils.

Distros qui ont déjà rétrocédés  ce changement:

  • Debian coreutils-8.25-2
    • Y compris, par conséquent, vraisemblablement Ubuntu et toutes les centaines de dérivés basés sur Debian et Ubuntu

Distros inchangé:

  • openSUSE (déjà utilisé -N)

" Y a-t-il un moyen de résoudre ce problème sans recompiler? "

Les partisans voudraient que vous ...

revenir à l'ancien format en ajoutant -N à leur alias ls

… Sur toutes vos installations, partout, pour le reste de l'éternité.

Jan Kyu Peblik
la source
17
Le changement a été proposé sur la liste de diffusion et accepté par trois responsables de la maintenance de coreutils de constituer un avantage net. Nous sommes tout à fait ouverts aux arguments constructifs à ce sujet. Ceci est open source après tout, nous ne voulons pas dicter, mais seulement améliorer les choses. N'hésitez pas à répondre dans le fil de discussion sur coreutils à l' adresse lists.gnu.org/archive/html/coreutils/2016-02/msg00000.html (Au fait, il y avait une suggestion constructive visant à améliorer l'un des inconvénients esthétiques mentionnés, en ajoutant un espace pour améliorer l'alignement)
Pádraig Brady
31
@ PádraigBrady Réponse mise à jour. Voir des charges de déni dans votre fil de coreutils, cependant. L'essentiel est de créer davantage de travail pour les utilisateurs, et ce, au nom d'un système d'exploitation qui est un clone d'un système d'exploitation de 1970. Si les utilisateurs veulent quelque chose de différent, ils y adhèrent.
Jan Kyu Peblik
43
@ PádraigBrady Ce changement m'a énervé et m'a fait perdre plusieurs heures à chercher une cause et une solution. Je ne veux pas être négatif - je partage juste le point de vue d'une autre personne! La modification du comportement central a d'énormes implications ..
Mafrosis
52
En tant que personne qui utilise des systèmes * nix depuis 30 ans, je trouve les changements gratuits comme celui-ci très ennuyeux. Ils cassent des scripts de longue date, pour une chose. Ils violent également le principe de moindre surprise. "Opt-in" aurait dû être la valeur par défaut ici, comme indiqué ci-dessus.
Brian Clapper
28
@ PádraigBrady Ce n'est toujours pas le moyen de pousser de tels changements. Il aurait été bien plus constructif d’avoir opté pour ce comportement au lieu d’être actif par défaut. Cela suggère aussi faussement que les noms de fichiers sont stockés, bref, lsce que vous ne voyez plus, c’est ainsi. Cette fonctionnalité devrait être facultative, pas la valeur par défaut.
91

Vous pouvez choisir un style de citation :

ls --quoting-style=literal

Le même que:

ls -N

ou:

QUOTING_STYLE=literal ls

Faites-en un alias, ou définissez-le export QUOTING_STYLE=literaldans le .bashrccomportement antérieur à 8.25.

cuonglm
la source
11
semble un peu bizarre je dois faire cela pour obtenir un comportement normal unix-y. En outre, je veux l'ancien défaut. Je ne pense pas que s’échapper était l’ancien défaut - je pense que cela imprimait exactement ce qui était réellement là.
Wyatt8740
9
Pour les comportements antérieurs à 8.25, utilisez-les export QUOTING_STYLE=literaldans votre base.
Lekensteyn le
2
ou utiliser -N, semble-t-il. Je suis en train de compiler ma propre version car j'ai déjà un référentiel personnel configuré.
Wyatt8740
2
@LSpice J'ai édité le post pour l'utiliser à la literalplace de escape(je crois que @cuonglm voulait juste montrer comment changer le style, sans cibler spécifiquement le escapestyle).
Lekensteyn
5
Cette réponse mérite plus de votes positifs. Il aborde directement ce que le questionneur a demandé en évitant une réponse bureaucratique. En effet, l'approche variable d'environnement semble assez élégante. (Personnellement, je préfère le nouveau comportement car il favorise une action C & P plus efficace), mais ls est assez intelligent pour se comporter de la même manière quand une redirection est utilisée, donc aucun dommage pour les scripts qui utilisent la sortie de ls.
Marcelo
42

Quelques points sur le changement.

  • Il a été introduit dans Coreutils v8.25 et son alignement a été amélioré dans v8.26.
  • Cela ne se produit que lors de la sortie sur des terminaux afin de ne pas casser les scripts
  • Il désambiguise la sortie pour les utilisateurs pour les fichiers contenant des espaces
  • Il assainit la sortie, donc il est sécuritaire de copier et coller
  • La sortie est maintenant toujours valide pour être copiée et collée dans le shell
  • Les utilisateurs peuvent revenir à l'ancien format en ajoutant -N à leur alias ls
Pádraig Brady
la source
7
mon dernier exemple n'est pas ambigu? Peut-être pas - mais c'est certainement déroutant et prend plus de temps à déchiffrer. Je pense que c'est un changement horrible (aucune infraction ne vous est destiné). Merci pour le pourboire alias cependant.
Wyatt8740
27
Remarque: cette modification a été introduite dans Coreutils 8.25 ( commit , écrit par le même Pádraig que celui-ci). Personnellement, je pense que ce comportement est sous-optimal, il rompt l'alignement chaque fois qu'un espace apparaît dans un nom de fichier.
Lekensteyn le
10
Toutes mes excuses. Apparemment, vous citez en toute sécurité les citations de shell au moins. Je n'aime toujours pas ça. les options sont bonnes - mais modifier le comportement par défaut très bien spécifié d'un utilitaire principal Unix vieux de plusieurs décennies de manière à en diminuer la véracité ne peut être qu'une mauvaise idée.
mikeserv
12
@ PádraigBrady Alors, allez-vous rester lscassé? Regardez tous ces arguments contre votre changement. Personne n'en veut. Peut-être qu'il est temps de s'excuser auprès du monde entier et de l'annuler.
Chris Warrick
6
@ PádraigBrady Donc, malgré les nombreuses personnes qui ont expliqué en quoi cela est erroné, cassé, etc., vous ne pourrez toujours pas revenir en arrière afin que la valeur par défaut ne soit pas modifiée? Contrairement à ce que vous pensez, ce changement confond pas sans ambiguïté. Suggérer que les personnes définissent une variable d'environnement ou un alias est asinine, au mieux.
Mark