Je veux utiliser printf
pour imprimer une variable. Il est possible que cette variable contienne un %
signe de pourcentage.
Exemple minimal:
$ TEST="contains % percent"
$ echo "${TEST}"
contains % percent
$ printf "${TEST}\n"
bash: printf: `p': invalid format character
contains $
(echo
fournit la sortie souhaitée.)
Utilisez printf
dans sa forme normale:
printf '%s\n' "${TEST}"
De man printf
:
SYNOPSIS printf FORMAT [ARGUMENT]...
Vous devez jamais transmettre une variable à la chaîne FORMAT car cela peut entraîner des erreurs et des failles de sécurité.
Btw:
si vous voulez avoir %
signez dans le cadre du FORMAT, vous devez saisir %%
, par exemple.:
$ printf '%d%%\n' 100
100%
Vous ne devez jamais mettre de contenu variable dans la chaîne de format donnée à printf
. Utilisez-le à la place:
printf '%s\n' "${TEST}"
printf
prend un paramètre garanti, puis un certain nombre de paramètres supplémentaires en fonction de ce que vous passez. Donc quelque chose comme ça:
printf '%07.2f' 5
se transforme en:
0005.00
Le premier paramètre, appelé "format
", est toujours présent. S'il ne contient pas de %
strings, c'est simplement imprimé. Donc:
printf Hello
produit simplement Hello
(notamment, sans le retour à la ligne echo
ajouterait dans son mode par défaut). En s'attendant à ce que votre exemple fonctionne, vous avez été induit en erreur par votre propre abus (inconscient) de ce fait; car vous n'avez passé que des chaînes sans %
s dans format
, du point de vue de printf
, vous ne cessiez de lui demander de produire des choses qui ne nécessitaient aucune substitution, donc cela fonctionnait à peu près comme echo -ne
.
Si vous voulez faire cela à droite, vous voulez probablement commencer à former vos chaînes imprimables avec les capacités de substitution intégrées de printf
. Des lignes comme celle-ci apparaissent partout dans mon code:
printf '%20s: %6d %05d.%02d%%' "$key" $val $((val/max)) $((val*100/max%100))
Si vous voulez que ce que vous faites actuellement fonctionne, vous voulez echo -ne
, ainsi:
TEST="contains % percent"
echo -ne "${TEST}\n"
Cela préserve le comportement (discutable) d'interprétation \
s'échappe à l'intérieur de la variable. Il semble également un peu idiot de fournir -n
puis collez le \n
de retour, mais je vous le propose car c'est une recherche et un remplacement global que vous pouvez appliquer à tout ce que vous faites actuellement. Une version plus propre qui conserve encore \
les échappements travaillant dans la variable seraient:
TEST="contains % percent"
echo -e "$TEST"