Pourquoi le Bourne Shell printf itère-t-il sur un argument %s ?

Lorsque vous travaillez avec des scripts shell, de nombreux programmeurs se retrouvent perplexes face à des comportements spécifiques des commandes. Un tel cas se présente lorsqu’on utilise la fonction printf du Bourne shell, surtout avec des arguments de chaîne. Si vous avez déjà rencontré une sortie inattendue en essayant d’afficher une variable avec printf, vous n’êtes pas seul ! Voyons pourquoi cela se produit et comment résoudre le problème.

Analyse du problème

Considérez le script shell simple suivant :

#! /bin/sh  
NAME="George W. Bush"  
printf "Hello, %s\n" $NAME  

Lorsque vous exécutez ce script, vous pourriez supposer que la sortie serait simple : Hello, George W. Bush. Cependant, à votre grande surprise, la ligne de commande retourne :

Hello, George  
Hello, W.  
Hello, Bush  

Que se passe-t-il ici ?

Le problème réside dans la manière dont le shell développe la variable. Lorsque vous utilisez $NAME sans guillemets, le shell divise le contenu de la variable NAME par des espaces, considérant chaque partie comme un argument distinct. Ainsi, printf est appelé avec trois arguments : George, W. et Bush. Chacun d’eux est traité individuellement, entraînant le comportement inattendu que vous constatez.

L’approche correcte

Pour éviter ce problème, vous devez encapsuler la variable entre guillemets. Voici la version corrigée de votre script :

#! /bin/sh  
NAME="George W. Bush"  
printf "Hello, %s\n" "$NAME"  

Pourquoi les guillemets sont-ils importants ?

Lorsque vous entourez $NAME de guillemets, vous indiquez au shell que l’intégralité du contenu — y compris les espaces — constitue un seul argument. Cela est essentiel pour les chaînes contenant des espaces, car cela les maintient intactes lors de l’expansion de la variable.

Alternatives : Pourquoi ne pas utiliser echo ?

Vous vous demandez peut-être pourquoi on ne devrait pas simplement utiliser echo à la place de printf. Voici une comparaison entre les deux dans un contexte utilisant un exemple différent :

#! /bin/sh  
FILE="C:\tmp"  
echo "Filename: $FILE"  

L’exécution de ce script donne :

Filename: C:    mp  

Ce comportement montre les problèmes qui peuvent survenir lors de l’utilisation de echo, notamment avec les barres obliques inverses et les séquences d’échappement. Selon la spécification POSIX pour echo : “Les nouvelles applications sont encouragées à utiliser printf plutôt qu’echo.” Cette recommandation reflète le comportement plus prévisible et la polyvalence de printf dans le formatage de la sortie.

Conclusion

En résumé, il est essentiel de se souvenir que lors de l’utilisation de printf dans des scripts shell, il est toujours préférable d’utiliser des guillemets autour des variables qui peuvent contenir des espaces ou des caractères spéciaux. Cela garantit que votre sortie se comporte comme prévu et évite toute surprise frustrante. Avec ce petit ajustement, vous pouvez utiliser printf avec confiance dans vos scripts pour une sortie propre et contrôlée !

En adoptant des bonnes pratiques comme celles-ci, vous vous retrouverez à créer des scripts shell plus robustes et fiables.