É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 echo
et 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é \n
peut ê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, echo
reste 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ù echo
sur certains systèmes étendront automatiquement les séquences d'échappement, d'autres nécessitent une -e
option 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, echo
est 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 printf
dans de nouveaux programmes.
En utilisant printf
Depuis la 4e édition Unix, la printf
commande 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 \n
garantit 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 printf
dispose 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 printf
utilisant $
:
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 printf
le %s
spécificateur de pour imprimer sous forme de chaîne, et l' E
opé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.