Come usare un personaggio speciale come normale?


13

Molte domande come "Come digitare il carattere con virgolette doppie (")? " ci viene chiesto e non vogliamo ingombrare la nostra comunità con la stessa risposta (digitala come \"se non fosse racchiusa tra 's, "se racchiusa tra 's.) Quindi, la domanda è qui.

Non è possibile digitare caratteri speciali in un terminale come quelli normali, ad esempio questo comando fallirà:

echo Updates (11)

Quindi, come digitare questi caratteri nel terminale come se fossero normali?

!#$^&*?[](){}<>~;'"\|<space><tab><newline>

Non esiste una shell Unix che conosco dove il ritorno a capo è speciale. =, @E %sono speciali in alcune conchiglie in alcuni contesti.
Stéphane Chazelas,

@ StéphaneChazelas Umm ... il ritorno a capo ( ^M) funge da avanzamento riga ( ^J) per me (Ubuntu 14.04, sh).
EKons,

No, i driver di terminale trasforma ^Ma ^Jin ingresso, ma ^Mnon è speciale per la shell e non ha bisogno di quotate. Digita echo ^V^M | hde vedrai il carattere 0d (e lo 0a aggiunto da echo).
Stéphane Chazelas,

@ StéphaneChazelas Umm ... Non so cosa hdsia, forse xxdè meglio come visualizzatore esadecimale.
EKons,

Qualunque sia. Usa POSIX od -tx1o sed -n lxxd di vim se non lo hai hd. Alcuni sistemi hanno anche cat -vteocat -A
Stéphane Chazelas il

Risposte:


26

Dipende molto dalla shell. Controlla il manuale della shell per i dettagli.

Nota anche che alcuni personaggi sono speciali solo in alcuni contesti. Ad esempio, nella maggior parte delle shell *e ?sono speciali solo nei contesti di elenchi, in POSIX o shell simili a csh, ~è speciale solo all'inizio di una parola o seguendo alcuni caratteri come :. Lo stesso per =in zsh. In alcune shell, [è speciale solo se abbinato (con alcune restrizioni) a ].

In alcune shell come basho yash, anche i caratteri speciali come i delimitatori di token vuoti variano a seconda delle impostazioni locali.

Anche gli operatori di quotazione (per rimuovere il significato speciale di quei caratteri) variano notevolmente tra le shell.

Conchiglie tipo Bourne

Un riepilogo per le shell tipo Bourne (ovvero le shell che sono state chiamate essere chiamate shsu un sistema o un altro dagli anni '80):

Conchiglia Bourne

Personaggi speciali:

  • "\'&|;()^`<>$, spazio, newline e tab sono speciali nelle semplici righe di comando quando non sono quotati.
  • #(tranne nella versione precedente) è speciale all'inizio di una riga o seguendo uno spazio, una scheda o &|()^<>;`.
  • {e }sono speciali solo in quanto sono parole chiave della shell (quindi solo parole nella posizione di comando).
  • *?[sono speciali come operatori globbing, quindi solo in contesti di lista. Nel caso di [, è [...]che è l'operatore globbing, uno [o ]solo deve essere citato per rimuovere il significato speciale.
  • =è speciale in contesti in cui è trattato come un operatore di assegnazione. Cioè, in un semplice comando, per tutte le parole che non seguono un argomento (tranne dopo set -k).

Operatori di citazione

  • \cita tutti i caratteri speciali tranne newline ( \<newline>è un modo per continuare una lunga linea logica sulla successiva linea fisica , in modo tale sequenza venga rimossa). Si noti che i backtick aggiungono ulteriore complessità come al loro interno, \viene utilizzato per primo per sfuggire al backtick di chiusura e aiutare il parser. All'interno virgolette, \può essere utilizzato solo per sfuggire stessa ", $ed `( \<newline>è ancora una continuazione della riga). All'interno di un documento qui, lo stesso tranne per ". \è l'unico modo per sfuggire ai personaggi all'interno dei documenti qui.
  • "..."virgolette escape tutti i caratteri, ma per sé, \, $e `.
  • '...' le virgolette singole sfuggono a tutti i caratteri tranne a se stessa.

Conchiglie POSIX

Le shell POSIX si comportano principalmente come la shell Bourne, tranne che:

  • ^ non è più un personaggio speciale
  • ~è speciale in alcuni contesti
  • { è consentito essere speciale, quindi dovrebbe essere citato.

ksh

come POSIX tranne che:

  • {string}è speciale se la stringa contiene un non quotato ,(o ..in alcuni casi e con alcune versioni).
  • ksh93 ha un ulteriore operatore di quotazione speciale: $'...'con regole complesse. Tale operatore è anche trovato (con alcune variazioni) a bash, zsh, mkshe FreeBSD e busybox sh.
  • ksh93ha anche un $"..."operatore di quotazione che funziona come "..."se non fosse che la stringa è soggetta alla localizzazione (potrebbe essere configurata in modo che si traduca nella lingua dell'utente). mkshignora l' $in $"...".

bash

come ksh93ma:

  • nelle localizzazioni di caratteri a byte singolo, tutti i caratteri vuoti (in base alle impostazioni locali) sono considerati delimitatori (come spazio o scheda). In effetti, ciò significa che dovresti citare tutti i byte con l'ottavo bit impostato nel caso in cui possano essere caratteri vuoti in alcune impostazioni locali.
  • Quando l'espansione della cronologia csh è abilitata come in istanze interattive, !è speciale in alcuni contesti e le doppie virgolette non sempre la sfuggono. Ed ^è speciale all'inizio di un comando.

zsh

come ksh93ma:

  • stessa nota per l' bashespansione della cronologia csh
  • =è speciale come il primo carattere di una parola (si =lsespande in /bin/ls).
  • {e }può anche aprire e chiudere gruppi di comandi quando non delimitati (come nelle {echo text}opere come quelle di Bourne { echo text;}).
  • tranne che per il [solo, i [bisogni devono essere quotati anche se non chiusi con a ].
  • Con l' extendedglobopzione abilitata #, ^e gli ~operatori sono traballanti.
  • Con l' bracecclopzione, {non-empty-string}è speciale.
  • $"..." non è supportato.
  • come una stranezza speciale, ?non è speciale quando si segue un %(anche citato o espanso) all'inizio di una parola (per consentire la %?namespecifica del lavoro)
  • una rcquotesscelta (non abilitato per default) permette di entrare apici come ''virgolette singole all'interno à la rc(vedi sotto).

yash

come POSIXtranne quello.

  • tutti i caratteri vuoti sono considerati delimitatori.
  • Con l' brace-expandopzione, implementa l'espansione del controvento in stile zsh.

Per tutte le shell, ci sono alcuni contesti speciali in cui la quotazione funziona in modo diverso. Abbiamo già menzionato qui documenti e backtick, ma c'è anche [[...]]in ksh e alcune altre shell, POSIX $((...)), casecostrutti ...

Si noti inoltre che la quotazione può avere altri effetti collaterali quando si tratta di espansioni (con virgolette doppie) o quando viene applicato ai delimitatori di documenti qui. Disabilita anche le parole riservate e influenza l'espansione dell'alias.

Sommario

In shell tipo Bourne !#$^&*?[(){}<>~;'"`\|=, SPC, TAB, NEWLINE e alcuni byte con l'ottavo set di bit sono o possono essere speciali (almeno in alcuni contesti).

Per rimuovere il significato speciale in modo che vengano trattati alla lettera, si utilizza la citazione.

Uso:

  • '...' per rimuovere il significato speciale di ogni personaggio:

    printf '%s\n' '\/\/ Those $quoted$ strings are passed literally as
    single arguments (without the enclosing quotes) to `printf`'
  • \ per rimuovere il significato speciale di un solo personaggio:

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

    Sopra, solo il carattere spaziale preceduto da a \viene letteralmente passato a printf. Gli altri sono trattati dalla shell come delimitatori di token.

  • utilizzare "..."per citare i personaggi, pur consentendo l'espansione di parametro ( $var, $#, ${foo#bar}...), espansione aritmetica ( $((1+1)), anche $[1+1]in alcune conchiglie) e la sostituzione di comando ( $(...)o la vecchia forma `...`. In realtà, il più delle volte, si ha voglia di mettere quelle espansioni all'interno virgolette doppie in ogni caso, puoi usare \dentro "..."per rimuovere il significato speciale dei personaggi che sono ancora speciali (ma solo loro).
  • se la stringa contiene 'caratteri, puoi comunque utilizzare '...'per il resto e utilizzare altri meccanismi di quotatura che possono essere citati 'come "'"o \'o (dove disponibile) $'\'':

    echo 'This is "tricky", isn'\''t it?'
  • Usa la moderna $(...)forma di sostituzione dei comandi. Usa il vecchio solo `...`per compatibilità con la shell Bourne, cioè con un sistema molto vecchio, e solo nelle assegnazioni variabili, come in non usare:

    echo "`echo "foo bar"`"

    Che non funzionerà con la shell Bourne o le versioni AT&T di ksh. O:

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

    Che funzionerà con Bourne e AT&T ksh, ma non con yash, ma usa:

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

    che funzionerà con tutti.

    È anche impossibile nidificarli in modo portabile con virgolette doppie, quindi, di nuovo, utilizzare le variabili. Attenzione anche alla speciale elaborazione della barra rovesciata:

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

    Memorizzerà solo una barra rovesciata all'interno $var, poiché esiste un livello aggiuntivo di elaborazione della barra rovesciata (per \, `e $(e anche "quando quotato tranne in yash) nei backtick, quindi è necessario

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

    o

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

    anziché.

Famiglia csh

csh e tcsh hanno una sintassi significativamente diversa, sebbene ci sia ancora molto in comune con la shell Bourne in quanto condividono un patrimonio comune.

Personaggi speciali:

  • "\'&|;()^`<>$, spazio, newline e tab sono speciali ovunque quando non sono quotati.
  • #(csh è la shell introdotta #come leader dei commenti) è speciale all'inizio di uno script o seguendo uno spazio, una scheda o una nuova riga non quotati.
  • *?[ sono speciali come operatori di globbing, quindi in contesti di lista
  • {non-empty-string} è speciale (csh è la shell che ha introdotto l'espansione del controvento).
  • !e ^sono speciali come parte dell'espansione della storia (di nuovo, un'invenzione csh), e le regole di quotazione sono speciali.
  • ~ (l'espansione della tilde anche un'invenzione di csh) è speciale in alcuni contesti.

Operatori di citazione

Sono gli stessi della shell Bourne, ma il comportamento è diverso. tcsh si comporta come csh dal punto di vista della sintassi, scoprirai che molte versioni di csh hanno bug cattivi. Ottieni l'ultima versione di tcsh per ottenere una versione approssimativamente funzionante di csh.

  • \sfugge a un singolo carattere tranne newline (come per la shell Bourne). È l'unico operatore quotatore che può scappare !. \<newline>non lo sfugge ma lo trasforma da un separatore di comandi in un separatore di token (come lo spazio)
  • "..."sfugge tutti i caratteri eccetto se stesso, $, `, nuova riga e !. Contrariamente alla shell Bourne, non puoi usare \per scappare $e `dentro "...", ma puoi usare \per scappare !o newline (ma non se stesso tranne quando prima di una !o newline). Un letterale !è "\!"e un letterale \!è "\\!".
  • '...' sfugge a tutti i personaggi tranne se stesso !e newline. Come per le virgolette doppie, !e newline può essere evitato con la barra rovesciata.
  • la sostituzione dei comandi avviene solo tramite la `...`sintassi e difficilmente può essere utilizzata in modo affidabile.
  • la sostituzione delle variabili è anche progettata in modo piuttosto scorretto e soggetta a errori. Un $var:qoperatore aiuta a scrivere codice più affidabile che coinvolge variabili.

Sommario

Stai lontano da csh se puoi. Se non puoi usare:

  • virgolette singole per citare la maggior parte dei personaggi. !e newline ha ancora bisogno di a \.
  • \ può sfuggire alla maggior parte dei personaggi
  • "..."può consentire alcune espansioni al suo interno, ma è piuttosto buggy se incorporano caratteri di nuova riga e / o barra rovesciata, la cosa migliore potrebbe essere quella di utilizzare solo virgolette singole e $var:qper l'espansione variabile. È necessario utilizzare i loop se si desidera unire in modo affidabile elementi di un array.

rc famiglia

rcè la plan9shell e come i suoi discendenti esed akangaè stato portato su Unix e su unix-like. Questa è una shell con una sintassi molto più pulita e migliore e quella che tutti userebbero se non fossimo bloccati con shell tipo Bourne per la compatibilità con le versioni precedenti.

rc/akanga

Personaggi speciali

  • #;&|^$=`'{}()<>, SPC, TAB e NEWLINE sono sempre speciali se non quotati.
  • *?[ sono operatori sconvolgenti.

Operatore di citazione

'...'è l'unico operatore quotatore. Una lettera 'è scritta con ''virgolette singole come in:

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

es

espotrebbe essere visto come una shell sperimentale basata su rc.

Ha alcune differenze però. Quello di interesse per questo Q / A è che \è anche un operatore di quotazione (che cita tutti i caratteri speciali tranne newline) e può anche essere usato per introdurre sequenze di escape come \nper newline, \bbackslash ...

pesce

il pesce è un nuovo arrivato (circa 2005), è principalmente destinato all'uso interattivo e ha anche una sintassi significativamente diversa dalle altre conchiglie.

personaggi speciali

  • "'\()$%{}^<>;&|sempre speciale se non quotato (notare il %(per espansione pid) come una differenza significativa rispetto ad altre shell, e `non è speciale)
  • # (commento) speciale quando si seguono spazi, tab, newline o ;&|^<>
  • *?(ma non [...]) operatori ostili

Operatori di citazione

  • \cita un singolo carattere speciale tranne newline, ma attenzione fa anche il doppio come introduttore della sequenza di escape C ( \n, \b...). IOW, \nnon è un citato nma una nuova riga.
  • "..."cita tutto tranne se stesso $e backslash e backslash possono essere usati per sfuggire a quelli. \<newline>è una continuazione di linea (rimossa) all'interno "...".
  • '...'cita tutto tranne se stesso e \, e puoi usare la barra rovesciata per sfuggire a quelli.

Ho incluso solo quelli speciali in tutti i contesti (in modo che cagisca allo stesso modo \c, cnon venga riprodotto c: command not foundsu STDERR, ecc.) E ne sto parlando shqui. Inoltre, ricorda che questa è una domanda di "pulizia", ​​cioè è qui per coprire tutti questi personaggi, quindi non dovrai fare più di 19 domande. La domanda è stata pubblicata grazie a un incidente in cui sono state poste diverse domande per personaggi diversi, sicuramente vogliamo ripulire qui!
EKons,

Bene, ?[sono operatori che rubano, ma non è speciale in tutti i contesti, ma *sembra esserlo, perché è echo *gravemente echoil contenuto della directory corrente (non sfuggire a nulla). echo ?fa eco a un letterale ?e fa echo [eco a un letterale [. Inoltre, ]è anche un oberatore travolgente.
EKons,

1
@ ΈρικΚωνσταντόπουλος, *poiché un glob si espande in tutti i file ?non nascosti, [a-z]in file a carattere singolo non nascosti, in file il cui nome è un singolo carattere tra a e z e così via. Quando non corrispondono a nessun file (come nel tuo caso ?), a seconda della shell, si ottiene un errore di non corrispondenza o il modello si espande su se stesso. In ogni caso, anche su shell in cui si espandono a se stessi, devono essere citati nel caso in cui possano corrispondere a un file.
Stéphane Chazelas,

Ma, non come un glob, *si espande ancora a qualcosa.
EKons,

@ ΈρικΚωνσταντόπουλος, *è come ?, se non corrisponde (per il *solo caso , è lì che ci sono solo file nascosti nella directory corrente, perché a*è lì che non c'è nessun file il cui nome inizia con a...), o si espande in in sé (la maggior parte Bourne-come gusci), o solleva un errore di no-match ( csh, tcsh, fish(warning), zsh, bash -O failglob, primi shell di Unix), (o si espande per niente con l'opzione nullglob di alcune conchiglie o se c'è un altro modello che si espande a qualcosa in csh, tcsh, zsh -o cshnullglob, prime shell unix).
Stéphane Chazelas,

4

1. Fuga

Esci da tutti questi personaggi con un \, in questo modo (non funziona su newline / ritorni a capo):

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

2. Doppia citazione

Racchiudere l'intero testo in "s, in questo modo:

$ 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. Virgoletta singola

Come per le virgolette doppie, ma non esiste un token speciale.

$ proof=proveit;echo 'This should not read "proveit": $proof'
This should not read "proveit": $proof

1
Stai descrivendo il comportamento della fishshell, non delle shell tipo Bourne in cui la singola virgoletta cita ogni carattere (la barra rovesciata non è speciale all'interno '...'). Si noti che in fish, %è anche un personaggio speciale.
Stéphane Chazelas,

@ StéphaneChazelas Non so come fishfunzioni, ma la mia esperienza è che, in sh, echo '\\'echi \ ed echo '\''echi '.
EKons,

1
echo '\\'genera \ perché il tuo echoespande le sequenze di escape ANSI C (alcune echoimplementazioni ne hanno bisogno echo -e '\\'). printf '%s\n' '\\'uscite \\.
Stéphane Chazelas,

Nota che shnon identifica una particolare shell, ci sono e sono state chiamate molte shell diverse e spesso incompatibili sh.
Stéphane Chazelas,

@ StéphaneChazelas Oh okay, lo cambierò ora. A proposito, c'è \'un token speciale all'interno di una sequenza di caratteri a virgoletta singola?
EKons,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.