Comment imprimer les nouvelles lignes dans la sortie de ligne de commande

Étonnamment, amener les ordinateurs à fournir une sortie lisible aux humains n'est pas une mince affaire. Avec l'introduction de flux standard et spécifiquement de sortie standard, les programmes ont acquis un moyen de se parler en utilisant des flux de texte brut. Mais humaniser et afficher stdout est une autre affaire. Tout au long de l'ère informatique, la technologie a tenté de résoudre ce problème, de l'utilisation de caractères ASCII dans les écrans d'ordinateur vidéo aux commandes shell modernes telles que echoet printf.

Ces progrès n'ont pas été transparents. Le travail d'impression de la sortie vers un terminal est plein de bizarreries pour les programmeurs à naviguer, comme illustré par la tâche trompeusement non triviale d'étendre une séquence d'échappement pour imprimer des nouvelles lignes. L'extension de l'espace réservé \npeut être réalisée de multiples façons, chacune avec sa propre histoire et ses complications.

En utilisant echo

De son apparition dans Multics à son omniprésence de système moderne de type Unix, echoreste un outil familier pour amener votre terminal à dire «Bonjour tout le monde!» Malheureusement, des implémentations incohérentes entre les systèmes d'exploitation rendent son utilisation délicate. Là où echosur certains systèmes étendront automatiquement les séquences d'échappement, d'autres nécessitent une -eoption pour faire de même:

echo "the study of European nerves is \neurology" # the study of European nerves is \neurology echo -e "the study of European nerves is \neurology" # the study of European nerves is # eurology

En raison de ces incohérences dans les implémentations, echoest considéré comme non portable. De plus, son utilisation en conjonction avec l'entrée de l'utilisateur est relativement facile à corrompre par une attaque par injection shell utilisant des substitutions de commandes.

Dans les systèmes modernes, il n'est conservé que pour assurer la compatibilité avec les nombreux programmes qui l'utilisent encore. La spécification POSIX recommande l'utilisation de printfdans de nouveaux programmes.

En utilisant printf

Depuis la 4e édition Unix, la printfcommande portable est essentiellement la nouvelle et la meilleure echo. Il vous permet d'utiliser des spécificateurs de format pour humaniser l'entrée. Pour interpréter les séquences d'échappement de barre oblique inverse, utilisez %b. La séquence de caractères \ngarantit que la sortie se termine par une nouvelle ligne:

printf "%b\n" "Many females in Oble are \noblewomen" # Many females in Oble are # oblewomen

Bien qu'il printfdispose d'autres options qui en font un remplacement beaucoup plus puissant echo, cet utilitaire n'est pas infaillible et peut être vulnérable à une attaque de chaîne de format incontrôlée. Il est important pour les programmeurs de s'assurer qu'ils gèrent soigneusement les entrées des utilisateurs.

Mettre des nouvelles lignes dans des variables

Dans un effort pour améliorer la portabilité entre les compilateurs, la norme ANSI C a été établie en 1983. Avec l'utilisation de citations ANSI-C $'...', les séquences d'échappement sont remplacées en sortie conformément à la norme.

Cela nous permet de stocker des chaînes avec des retours à la ligne dans des variables qui sont imprimées avec les retours à la ligne interprétés. Vous pouvez le faire en définissant la variable, puis en l'appelant avec en printfutilisant $:

puns=$'\number\narrow\nether\nice' printf "%b\n" "These words started with n but don't make $puns" # These words started with n but don't make # umber # arrow # ether # ice

La variable développée est entre guillemets simples, qui est transmise littéralement à printf. Comme toujours, il est important de gérer correctement l'entrée.

Tour bonus: extension des paramètres de la coque

Dans mon article expliquant Bash et les accolades, j'ai couvert la magie de l'expansion des paramètres du shell. Nous pouvons également utiliser une extension,, ${[email protected]}pour interpréter les séquences d'échappement. Nous utilisons printfle %sspécificateur de pour imprimer sous forme de chaîne, et l' Eopérateur développera correctement les séquences d'échappement dans notre variable:

printf "%s\n" ${[email protected]} # umber # arrow # ether # ice

Le défi permanent de parler en humain

L'interpolation de chaîne continue d'être un problème délicat pour les programmeurs. En plus de faire en sorte que les langages et les shells s'accordent sur la signification de certains espaces réservés, l'utilisation correcte des séquences d'échappement correctes nécessite un souci du détail.

Une mauvaise interpolation de chaîne peut conduire à une sortie ridicule et introduire des vulnérabilités de sécurité, telles que des attaques par injection. Jusqu'à ce que la prochaine évolution du terminal nous fasse parler d'émojis, nous ferions mieux de faire attention lors de l'impression de sorties pour les humains.