La sortie de ls a des returns à la ligne mais s'affiche sur une seule ligne. Pourquoi?

Je pense que je peux négliger un point relativement fondamental concernant la coquille. La sortie de la command ls sépare par défaut la sortie avec des returns à la ligne, mais le shell affiche la sortie sur une seule ligne.

Quelqu'un peut-il m'expliquer cela? J'avais toujours supposé que la sortie était simplement séparée par des espaces, mais maintenant que je vois la sortie séparée par des returns à la ligne, j'attendrais que la sortie soit affichée sur des lignes séparées.

Exemple:

cpoweradm@debian:~/lpi103-4$ ls text* text1 text2 text3 

od montre que la sortie est séparée par des returns à la ligne:

 cpoweradm@debian:~/lpi103-4$ ls text* | od -c 0000000 text 1 \ntext 2 \ntext 0000020 3 \n 0000022 

Si des returns sont présents, pourquoi la sortie ne s'affiche-t-elle pas comme:

 text1 text2 text3 

Lorsque vous dirigez la sortie, ls agit différemment.

Ce fait est caché dans la documentation d'information :

Si la sortie standard est un terminal, la sortie est en colonnes (sortingées verticalement) et les caractères de contrôle sont émis sous forme de points d'interrogation; sinon, la sortie est répertoriée une par ligne et les caractères de contrôle sont sortis tels quels.

Pour le prouver, essayez de courir

 ls 

et alors

 ls | less 

Cela signifie que si vous voulez que la sortie soit garantie d'un file par ligne, qu'elle soit canalisée ou redirigée, vous devez exécuter

 ls -1 

( -1 est le numéro un)

Ou, vous pouvez forcer ls | less ls | less de sortie dans les colonnes en cours d'exécution

 ls -C 

( -C est une capitale C)

Votre découverte met en évidence la principale raison pour laquelle l'parsing de la sortie de ls est toujours une mauvaise idée. Voir le wiki de Greg pour une explication complète .

Pensez à votre problème en sens inverse. Vous avez remarqué que ls fait parfois et parfois n'imprime pas les returns à la ligne entre sa sortie. Pour l'utiliser dans les scripts ou lorsqu'il est forcé par le drapeau -1 , il le fait. Une nouvelle ligne à la fin de chaque file. Ce qui ne garantit pas que chaque nouvelle ligne représente un nouveau nom de file . En fait, si un nom de file contient une nouvelle ligne elle-même, la sortie de ls sera absolument impossible à parsingr. Considérez ces noms de files:

 file1 file2\nfile3 file4 

Quand vous avez ls -1 un directory avec ça, vous obtiendrez quelque chose qui ressemble à ceci:

 file1 file2 file3 file4 

Voulez-vous pas naturellement asume il y avait quatre files? Donc, tous les scripts qui parsingnt la sortie de ls. En réalité, il existe trois files, l'un avec un nom délicat, mais vous ne seriez pas en mesure de le comprendre à partir de la sortie de ls. *

* A less que vous n'utilisiez le drapeau -l et que vous remarquiez que la sortie était borked, mais que vos scripts seraient encore étouffés.