Comment utiliser un caractère spécial comme un caractère normal?

13

De nombreuses questions comme "Comment taper le caractère de guillemet double (")? " sont demandés, et nous ne voulons pas encombrer notre communauté avec la même réponse (Tapez-le comme \"s'il n'était pas enfermé dans 's, "s'il est enfermé dans 's.) Donc, la question est ici.

Vous ne pouvez pas taper de caractères spéciaux dans un terminal comme ceux normaux, par exemple, cette commande échouera:

echo Updates (11)

Alors, comment taper ces caractères dans le terminal comme s'ils étaient normaux?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>
EKons
la source
Il n'y a pas de shell Unix que je connaisse où le retour chariot est spécial. =, @Et %sont spéciaux dans certains obus dans certains contextes.
Stéphane Chazelas
@ StéphaneChazelas Umm ... le retour chariot ( ^M) agit comme un saut de ligne ( ^J) pour moi (Ubuntu 14.04, sh).
EKons
Non, votre pilote de terminal se transforme ^Men ^Jentrée mais ^Mn'est pas spécial pour le shell et n'a pas besoin d'être cité. Tapez echo ^V^M | hdet vous verrez le caractère 0d (et le 0a ajouté par écho).
Stéphane Chazelas du
@ StéphaneChazelas Umm ... Je ne sais pas ce qui hdest, c'est peut xxd- être mieux en visionneur hexadécimal.
EKons
Peu importe. Utilisez POSIX od -tx1ou sed -n lxxd de vim si vous n'en avez pas hd. Certains systèmes ont également cat -vteoucat -A
Stéphane Chazelas

Réponses:

26

Cela dépend beaucoup de la coque. Consultez le manuel de votre coque pour plus de détails.

Notez également que certains caractères ne sont spéciaux que dans certains contextes. Par exemple, dans la plupart des shells, *et ?ne sont spéciaux que dans les contextes de liste, dans les shells POSIX ou csh, il ~n'est spécial qu'au début d'un mot ou à la suite de certains caractères comme :. Idem pour =en zsh. Dans certains shells, [n'est spécial que lorsqu'il est associé (avec certaines restrictions) par a ].

Dans certains shells comme bashou yash, les caractères spéciaux comme les délimiteurs de jetons vierges varient également en fonction des paramètres régionaux.

Les opérateurs de citation (pour supprimer la signification spéciale de ces caractères) varient également considérablement entre les shells.

Coquilles de type Bourne

Un résumé pour les obus de type Bourne (c'est-à-dire les obus connus pour être appelés shsur un système ou un autre depuis les années 80):

Coquille de Bourne

Caractères spéciaux:

  • "\'&|;()^`<>$, l'espace, la nouvelle ligne et l'onglet sont spéciaux dans les lignes de commande simples lorsqu'ils ne sont pas cités.
  • #(sauf dans la première version) est spécial au début d'une ligne ou à la suite d'un espace, d'une tabulation ou d'un &|()^<>;`.
  • {et }ne sont spéciaux que dans la mesure où ce sont des mots-clés shell (donc uniquement des mots en position de commande).
  • *?[sont spéciaux comme opérateurs globbing, donc uniquement dans des contextes de liste. Dans le cas de [, c'est [...]qu'il s'agit de l'opérateur de globalisation, [ou ]il suffit de le citer pour supprimer la signification spéciale.
  • =est spécial lorsque dans des contextes où il est traité comme un opérateur d'affectation. C'est-à-dire, dans une commande simple, pour tous les mots qui ne suivent pas un argument (sauf après set -k).

Opérateurs de citation

  • \cite tous les caractères spéciaux, sauf la nouvelle ligne ( \<newline>est un moyen de continuer une longue ligne logique sur la ligne physique suivante , de sorte que la séquence soit supprimée). Notez que les backticks ajoutent une complexité supplémentaire, car ils \sont utilisés en premier pour échapper au backtick de fermeture et aider l'analyseur. À l'intérieur des guillemets doubles, \ne peut être utilisé que pour s'échapper ", $et `( \<newline>est toujours une continuation de ligne). À l'intérieur d'un document ici, même sauf pour ". \est le seul moyen d'échapper aux personnages à l'intérieur des documents.
  • "..."guillemets doubles échapper à tous les personnages , mais lui - même, \, $et `.
  • '...' les guillemets simples échappent à tous les caractères sauf à lui-même.

Coques POSIX

Les shell POSIX se comportent principalement comme le shell Bourne, sauf que:

ksh

comme POSIX sauf que:

  • {string}est spécial si la chaîne contient un non cité ,(ou ..dans certains cas et avec certaines versions).
  • ksh93 possède un opérateur de citation spécial supplémentaire: $'...'avec des règles complexes. Cet opérateur est également trouvé (avec quelques variantes) dans bash, zsh, mkshet FreeBSD et busybox sh.
  • ksh93a également un $"..."opérateur de citation qui fonctionne comme "..."sauf que la chaîne est sujette à la localisation (pourrait être configurée pour qu'elle se traduise dans la langue de l'utilisateur). mkshne tient pas compte de la $dans $"...".

bash

comme ksh93mais:

  • dans les paramètres régionaux de caractère à un octet, tous les caractères vides (selon les paramètres régionaux) sont considérés comme des délimiteurs (comme l'espace ou la tabulation). En effet, cela signifie que vous devez citer tous les octets avec le 8e bit défini au cas où il pourrait s'agir d'un caractère vide dans certains paramètres régionaux.
  • Lorsque l'expansion de l'historique csh est activée comme dans les instances interactives, elle !est spéciale dans certains contextes et les guillemets doubles n'y échappent pas toujours. Et ^est spécial au début d'une commande.

zsh

comme ksh93mais:

  • même note que pour l' bashexpansion de l'historique csh
  • =est spécial comme premier caractère d'un mot (se =lsdéveloppe en /bin/ls).
  • {et }peut également ouvrir et fermer des groupes de commandes lorsqu'ils ne sont pas délimités (comme dans des {echo text}travaux comme celui de Bourne { echo text;}).
  • sauf pour [seul, [besoins cités même s'ils ne sont pas fermés par un ].
  • Lorsque l' extendedgloboption est activée #, ^et ~sont des opérateurs de globalisation.
  • Avec l' braceccloption, {non-empty-string}c'est spécial.
  • $"..." n'est pas pris en charge.
  • comme bizarrerie spéciale, ?n'est pas spécial lorsque vous suivez un %(même entre guillemets ou développé) au début d'un mot (pour permettre la %?namespécification du travail)
  • une rcquotesoption (non activée par défaut) permet de saisir des guillemets simples comme à l' ''intérieur des guillemets simples à la rc(voir ci-dessous).

yash

comme POSIXsauf ça.

  • tous les caractères vides sont considérés comme des délimiteurs.
  • Avec l' brace-expandoption, implémente l'expansion d'accolade de style zsh.

Pour tous les shells, il existe certains contextes spéciaux où la citation fonctionne différemment. Nous avons déjà mentionné ici des documents et des astuces, mais il y a aussi [[...]]dans ksh et quelques autres shells, POSIX $((...)), caseconstructions ...

Notez également que la citation peut avoir d'autres effets secondaires en ce qui concerne les extensions (avec des guillemets doubles) ou lorsqu'elle est appliquée aux délimiteurs de document ici. Il désactive également les mots réservés et affecte l'expansion des alias.

Sommaire

Dans les shells de type Bourne !#$^&*?[(){}<>~;'"`\|=, SPC, TAB, NEWLINE et certains octets avec le 8ème bit sont ou peuvent être spéciaux (au moins dans certains contextes).

Pour supprimer la signification spéciale afin qu'ils soient traités littéralement, vous utilisez des guillemets.

Utilisation:

  • '...' pour supprimer la signification particulière de chaque caractère:

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
  • \ pour supprimer la signification spéciale d'un seul caractère:

    printf '<%s>\n' foo bar\ baz #comment

    Ci-dessus, seul le caractère espace précédé d'un \est passé littéralement à printf. Les autres sont traités par le shell comme des délimiteurs de jetons.

  • utiliser "..."pour obtenir des caractères , tout en permettant le développement des paramètres ( $var, $#, ${foo#bar}...), l' expansion arithmétique ( $((1+1))aussi $[1+1]dans quelques coquilles) et la substitution de commande ( $(...)ou l'ancienne forme `...`. En fait, la plupart du temps, vous ne voulez mettre ces extensions à l' intérieur les guillemets doubles dans tous les cas . Vous pouvez utiliser \dedans "..."pour supprimer la signification spéciale des caractères qui sont encore spéciaux (mais seulement eux).
  • si la chaîne contient du 'caractère, vous pouvez toujours utiliser '...'pour le reste et utiliser d'autres mécanismes de citation qui peuvent citer 'comme "'"ou \'ou (le cas échéant) $'\'':

    echo 'This is "tricky", isn'\''t it?'
  • Utilisez la $(...)forme moderne de substitution de commande. Utilisez uniquement l'ancien `...`pour la compatibilité avec le shell Bourne, c'est-à-dire pour un système très ancien, et uniquement dans les affectations de variables, comme dans ne pas utiliser:

    echo "`echo "foo bar"`"

    Ce qui ne fonctionnera pas avec le shell Bourne ou les versions AT&T de ksh. Ou:

    echo "`echo \"foo bar\"`"

    Qui fonctionnera avec Bourne et AT&T ksh, mais pas avec yash, mais utilisera:

    var=`echo "foo bar"`; echo "$var"

    qui fonctionnera avec tous.

    Il est également impossible de les imbriquer de manière portative avec des guillemets doubles, alors encore une fois, utilisez des variables. Méfiez-vous également du traitement spécial de barre oblique inverse:

    var=`printf '%s\n' '\\'`

    Ne stockera qu'une seule barre oblique inverse à l'intérieur $var, car il y a un niveau supplémentaire de traitement de barre oblique inverse (pour \, `, et $(et aussi "lorsqu'il est cité sauf dans yash)) dans les barres obliques inverses, vous devez donc soit

    var=`printf '%s\n' '\\\\'`

    ou

    var=`printf '%s\n' '\\\'

    au lieu.

Famille Csh

csh et tcsh ont une syntaxe sensiblement différente, bien qu'il y ait encore beaucoup de choses en commun avec le shell Bourne car ils partagent un héritage commun.

Caractères spéciaux:

  • "\'&|;()^`<>$, l'espace, la nouvelle ligne et l'onglet sont spéciaux partout lorsqu'ils ne sont pas cités.
  • #(csh est le shell qui a été introduit en #tant que leader du commentaire) est spécial au début d'un script ou à la suite d'un espace, d'une tabulation ou d'une nouvelle ligne sans guillemets.
  • *?[ sont spéciaux comme opérateurs globbing donc dans des contextes de liste
  • {non-empty-string} est spécial (csh est le shell qui a introduit l'expansion de l'accolade).
  • !et ^sont spéciaux dans le cadre de l'expansion de l'histoire (encore une fois, une invention csh), et les règles de citation sont spéciales.
  • ~ (l'extension tilde est également une invention csh) est spéciale dans certains contextes.

Opérateurs de citation

Ils sont les mêmes que pour le shell Bourne, mais le comportement diffère. tcsh se comporte comme csh du point de vue de la syntaxe, vous constaterez que de nombreuses versions de csh ont des bugs désagréables. Obtenez la dernière version de tcsh pour obtenir une version à peu près fonctionnelle de csh.

  • \échappe à un seul caractère sauf la nouvelle ligne (comme pour le shell Bourne). C'est le seul opérateur de citation qui peut s'échapper !. \<newline>ne l'échappe pas mais le transforme d'un séparateur de commandes en un séparateur de jetons (comme l'espace)
  • "..."échappe à tous les caractères sauf lui - même, $, `, et retour à la ligne !. Contrairement au shell Bourne, vous ne pouvez pas utiliser \pour échapper $et à l' `intérieur "...", mais vous pouvez utiliser \pour échapper !ou saut de ligne (mais pas lui-même sauf avant un !ou retour de ligne). Un littéral !est "\!"et un littéral \!est "\\!".
  • '...' échappe à tous les personnages sauf lui-même !et la nouvelle ligne. Comme pour les guillemets doubles, la !nouvelle ligne peut être échappée avec une barre oblique inverse.
  • la substitution de commande se fait uniquement via la `...`syntaxe et peut difficilement être utilisée de manière fiable.
  • la substitution de variables est également assez mal conçue et sujette aux erreurs. Un $var:qopérateur aide à écrire du code plus fiable impliquant des variables.

Sommaire

Éloignez-vous de csh si vous le pouvez. Si vous ne pouvez pas utiliser:

  • guillemets simples pour citer la plupart des caractères. !et newline a encore besoin d'un \.
  • \ peut échapper à la plupart des personnages
  • "..."peut autoriser certaines extensions, mais c'est assez bogué s'ils incorporent des caractères de nouvelle ligne et / ou de barre oblique inverse, le mieux peut être d'utiliser des guillemets simples uniquement et $var:qpour une expansion variable. Vous devrez utiliser des boucles si vous souhaitez joindre de manière fiable des éléments d'un tableau.

rc famille

rcest le plan9shell et comme ses descendants eset akangaa été porté sur Unix et unix-likes. C'est un shell avec une syntaxe beaucoup plus propre et meilleure et celle que tout le monde utiliserait si nous n'étions pas coincés avec des shells de type Bourne pour une compatibilité descendante.

rc/akanga

Caractères spéciaux

  • #;&|^$=`'{}()<>, SPC, TAB et NEWLINE sont toujours spéciaux lorsqu'ils ne sont pas cités.
  • *?[ sont des opérateurs globbing.

Opérateur de devis

'...'est le seul opérateur de cotation. Un littéral 'est écrit avec ''des guillemets simples comme dans:

 echo 'it''s so simple isn''t it?'

es

espourrait être vu comme un shell expérimental basé sur rc.

Il y a cependant quelques différences. L'intérêt de cette Q / R est qu'il \s'agit également d'un opérateur de citation (qui cite tous les caractères spéciaux sauf la nouvelle ligne) et peut également être utilisé pour introduire des séquences d'échappement comme \npour la nouvelle ligne, \bpour la barre oblique inverse ...

poisson

fish est un nouveau venu (vers 2005), est principalement destiné à une utilisation interactive et a également une syntaxe sensiblement différente des autres coquilles.

caractères spéciaux

  • "'\()$%{}^<>;&|toujours spécial lorsqu'il n'est pas cité (notez le %(pour l'expansion pid) comme une différence significative par rapport aux autres coques, et `n'est pas spécial)
  • # (commentaire) spécial lorsque vous suivez un espace, une tabulation, une nouvelle ligne ou ;&|^<>
  • *?(mais pas [...]) opérateurs de globbing

Opérateurs de citation

  • \cite un seul caractère spécial à l'exception de la nouvelle ligne, mais attention, il sert également d' introducteur de séquence d'échappement C ( \n, \b...). IOW, \nn'est pas une citation nmais une nouvelle ligne.
  • "..."cite tout sauf lui-même, $et la barre oblique inverse et la barre oblique inverse peuvent être utilisées pour y échapper. \<newline>est une continuation de ligne (supprimée) à l'intérieur "...".
  • '...'cite tout sauf lui-même et \, et vous pouvez utiliser une barre oblique inverse pour y échapper.
Stéphane Chazelas
la source
Je n'ai inclus que ceux spéciaux dans tous les contextes (donc cela cagit de la même manière que \c, cne c: command not foundsort pas sur STDERR, etc.) Et je parle shici. Rappelez-vous également qu'il s'agit d'une question de "nettoyage", c'est-à-dire qu'elle est là pour couvrir tous ces personnages, donc plus de 19 questions n'auront pas à être posées. La question a été postée grâce à un incident où différentes questions sont posées pour différents personnages, nous voulons sûrement nettoyer ici!
EKons
Eh bien, ?[sont les opérateurs englobement, mais n'est pas spécial dans tous les contextes, mais *semble être, parce que echo *mal echoes le contenu du répertoire courant (rien échapper). echo ?fait écho à un littéral ?et echo [fait écho à un littéral [. En outre, ]est également un observateur globulaire.
EKons
1
@ ΈρικΚωνσταντόπουλος, en *tant que glob s'étend à tous les fichiers ?non masqués, [a-z]aux fichiers à caractère unique non masqués, aux fichiers dont le nom est un caractère unique entre a et z et ainsi de suite. Quand ils ne correspondent à aucun fichier (comme dans votre cas pour ?), selon le shell, vous obtenez une erreur de non-correspondance ou le modèle se développe lui-même. Dans tous les cas, même sur le shell où ils s'étendent à eux-mêmes, ils ont besoin de devis au cas où ils pourraient correspondre à un fichier.
Stéphane Chazelas
Mais, pas en tant que glob, *se développe toujours à quelque chose.
EKons
@ ΈρικΚωνσταντόπουλος, *c'est comme ?si ça ne correspond pas (pour le cas *seul, c'est quand il n'y a que des fichiers cachés dans le répertoire courant, car a*c'est là qu'il n'y a pas de fichier dont le nom commence par a...), il se développe soit lui - même ( la plupart Bourne comme des coquilles), ou déclenche une erreur sans correspondance ( csh, tcsh,fish (avertissement), zsh, bash -O failglob, début des shells Unix), (ou par rien avec l'option nullglob de quelques coquilles ou s'il y a un autre motif qui se développe pour quelque chose dans csh, tcsh, zsh -o cshnullglob, les premiers shells unix).
Stéphane Chazelas
4

1. Échapper

Échappez tous ces caractères avec un \, comme ceci (ne fonctionne pas sur les retours à la ligne / retours chariot):

$ echo Use a \"\\\" symbol to escape characters.
Use a "\" symbol to escape characters.

2. Devis double

Mettez le texte entier en "s, comme ceci:

$ var=variables;echo "Enclose text in \"s. You can also use $var in them. `echo Surprise!!!`"
Enclose text in "s. You can also use variables in them. Surprise!!!

3. Devis unique

Identique à la citation double, mais il n'y a pas de jeton spécial.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof
EKons
la source
1
Vous décrivez le comportement du fishshell, pas des shells de type Bourne où la citation simple cite chaque caractère (la barre oblique inverse n'est pas spéciale à l'intérieur '...'). Notez que dans fish, %est également un caractère spécial.
Stéphane Chazelas
@ StéphaneChazelas Je ne sais pas comment ça fishmarche, mais mon expérience est que, dans sh, echo '\\'échos \ et echo '\''échos '.
EKons
1
echo '\\'sorties \ parce que vous echodéveloppez les séquences d'échappement ANSI C (certaines echoimplémentations en ont besoin echo -e '\\'). printf '%s\n' '\\'les sorties \\.
Stéphane Chazelas
Notez que shn'identifie pas un shell particulier, il y a et a eu beaucoup de shells différents et souvent incompatibles appelés sh.
Stéphane Chazelas
@ StéphaneChazelas Oh d'accord, je vais changer ça maintenant. Au fait, \'un jeton spécial se trouve-t-il dans une séquence de caractères entre guillemets simples?
EKons