Vous pouvez utiliser cat
avec le -A
option :du manuel :
-A, --show-all
equivalent to -vET
-E, --show-ends
display $ at end of each line
-T, --show-tabs
display TAB characters as ^I
-v, --show-nonprinting
use ^ and M- notation, except for LFD and TAB
Alors cat -A yourscrip.sh
vous montrera des personnages invisibles et étranges.
Une option consiste à regarder les caractères que vous essayez d'utiliser avec un visualiseur ou un éditeur hexadécimal. hexdump
est une bonne option si vous êtes limité au terminal.
$ hexdump -Cv <<"EOF"
> [ -f /etc/openvpn/client.conf ] && echo true
> EOF
00000000 5b 20 2d 66 20 2f 65 74 63 2f 6f 70 65 6e 76 70 |[ -f /etc/openvp|
00000010 6e 2f 63 6c 69 65 6e 74 2e 63 6f 6e 66 20 5d 20 |n/client.conf ] |
00000020 26 26 20 65 63 68 6f 20 74 72 75 65 0a |&& echo true.|
0000002d
Vous pouvez voir ici que le space
, close-square-brace
, space
sont corrects - 0x20
, 0x5D
, 0x20
.
Ces valeurs sont des codes ASCII, affichés en hexadécimal. Toute valeur en dehors de la plage 0x20
- 0x7E
n'est pas un "caractère imprimable " en ce qui concerne ASCII, et ne fonctionnera probablement pas bien avec les interfaces de ligne de commande.
Remarque : J'ai copié votre premier "cassé " ligne à utiliser dans le hexdump
exemple ci-dessus, donc quelque chose a remplacé l'espace not-an-ASCII-space avec un espace ASCII entre votre source d'origine et votre question rendue.
Pour répéter cela, procédez comme suit :
- Tapez
hexdump -Cv <<"EOF"
et appuyez sur Entrée - Collez le texte que vous souhaitez utiliser
- Tapez
EOF
sur une ligne à part, et appuyez sur Entrée
Les terminaux et les interfaces de ligne de commande ne gèrent pas bien les caractères spéciaux - comme vous l'avez découvert. Si vous n'êtes pas très prudent avec le formatage des documents, vous aurez également des problèmes avec Microsoft Word (et d'autres) en utilisant les "guillemets intelligents ", em-tirets, la liste continue...
Trouvez la différence :(le haut est "guillemets intelligents ", le bas est "guillemets droits ")
$ hexdump -Cv <<"EOF"
> “quoted string”
> EOF
00000000 e2 80 9c 71 75 6f 74 65 64 20 73 74 72 69 6e 67 |...quoted string|
00000010 e2 80 9d 0a |....|
00000014
Ici, les guillemets ouverts ne sont pas un simple guillemet ASCII ("
), mais sont une série Unicode / UTF-8 - 0xE2
, 0x80
, 0x9C
, ou U+201C
- que le terminal ne gérera pas comme on pourrait s'y attendre.
La suggestion de Kiwy de cat -A
fait aussi le travail :
$ cat -A <<"EOF"
> “quoted string”
> EOF
M-bM-^@M-^\quoted stringM-bM-^@M-^]$
Remarque : lors de l'utilisation de echo "..." | hd
, vous avez une chance que bash substitue des parties de la chaîne que vous essayez d'inspecter. Ceci est particulièrement préoccupant lorsque vous essayez d'inspecter les composants d'un script.
Par exemple, essayez :
$ echo "${USER}"
attie
$ echo "`whoami`"
attie
$ echo "$(whoami)"
attie
$ cat <<EOF
> ${USER}
> EOF
attie
Ces méthodes remplacent les composants par le texte pertinent. Pour éviter cela, utilisez l'une des approches suivantes. Notez l'utilisation de guillemets simples ('
), et un "ici cité " ("EOF"
).
$ echo '${USER}'
${USER}
$ echo '`whoami`'
`whoami`
$ echo '$(whoami)'
$(whoami)
$ cat <<"EOF"
> ${USER}
> EOF
${USER}
echo "<your command>" | hd
devrait marcher. Recherchez le retour arrière (0x08) ou les caractères avec des codes>=80. echo "<your command>" | wc -b
et vérifier que le nombre correspond à ce que vous voyez est également une bonne idée.
Copier des éléments à partir de fichiers produits par n'importe quoi avec "Office" dans son nom est dangereux, car ces logiciels prennent souvent la liberté de remplacer des caractères :en français, faites attention aux guillemets doubles remplacés par des "guillemets", en anglais aux guillemets simples remplacés par leur équivalents d'ouverture/fermeture. Le plus difficile que j'ai jamais trouvé était un espace insécable de largeur 0 au milieu d'un nom de fichier (3 jours d'indisponibilité du serveur...).