GNU/Linux >> Linux Esercitazione >  >> Linux

Come utilizzare un carattere speciale come normale nelle shell Unix?

Vengono poste molte domande come "Come digitare il carattere tra virgolette (")?" e non vogliamo ingombrare la nostra community con la stessa risposta (digitala come " se non racchiuso in ' s, " se racchiuso tra ' s.) Quindi, la domanda è qui.

Non puoi digitare caratteri speciali in un terminale come quelli normali, ad es. questo comando fallirà:

echo Updates (11)

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

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

Risposta accettata:

Dipende molto dal guscio. Controlla il manuale della tua shell per i dettagli.

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

In alcune shell come bash o yash , anche i caratteri speciali come i delimitatori di token vuoti variano in base alle impostazioni internazionali.

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

Proiettili simili a Bourne

Un riassunto per le shell tipo Bourne (ovvero le shell che sono note per essere chiamate sh su qualche sistema dagli anni '80):

Guscio Bourne

Caratteri speciali:

  • "'&|;()^`<>$ , spazio, nuova riga e tab sono speciali nelle righe di comando semplici quando non sono tra virgolette.
  • # (tranne nella versione precedente) è speciale all'inizio di una riga o dopo uno spazio, una tabulazione o &|()^<>;` senza virgolette .
  • { e } sono speciali solo in quanto sono parole chiave della shell (quindi solo parole nella posizione di comando).
  • *?[ sono speciali come operatori di globbing, quindi solo in contesti di elenco. Nel caso di [ , è [...] questo è l'operatore di globbing, sia [ o ] basta citare solo per rimuovere il significato speciale.
  • = è speciale quando si trova in contesti in cui viene 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 quotazione

  • virgolette tutti i caratteri speciali tranne newline (<newline> è un modo per continuare una lunga logica linea sul prossimo fisico riga, in modo che la sequenza venga rimossa). Nota che i backtick aggiungono ulteriore complessità poiché al loro interno, viene utilizzato prima per sfuggire al backtick di chiusura e aiutare il parser. Tra virgolette doppie, può essere usato solo per sfuggire a se stesso, " , $ e ` (<newline> è ancora una continuazione di riga). All'interno di un here-document, lo stesso tranne per " . è l'unico modo per sfuggire ai caratteri all'interno di questi documenti.
  • "..." le doppie virgolette sfuggono a tutti i caratteri tranne se stessi, , $ e ` .
  • '...' virgolette singole sfuggono a tutti i caratteri tranne se stessi.

Shell POSIX

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

  • ^ non è più un carattere speciale
  • ~ è speciale in alcuni contesti
  • { può essere speciale, quindi dovrebbe essere citato.

ksh

come POSIX tranne che:

  • {string} è speciale se la stringa contiene un , senza virgolette (o .. in alcuni casi e con alcune versioni).
  • ksh93 ha un ulteriore operatore di virgolette speciale:$'...' con regole complesse. Quell'operatore si trova anche (con alcune variazioni) in bash , zsh , mksh e FreeBSD e busybox sh .
  • ksh93 ha anche un $"..." operatore di virgolette che funziona come "..." tranne per il fatto che la stringa è soggetta a localizzazione (potrebbe essere configurata in modo che si traduca nella lingua dell'utente). mksh ignora il $ in $"..." .
  • da ksh93r , ksh93 supporta lo stile csh (non abilitato per impostazione predefinita) con -H / -o histexpand in shell interattive) che rende ^ all'inizio dei comandi e ! speciale. ! è quindi speciale in alcuni contesti (non quando è seguito da spazio o TAB né in qui documenti) e non è sfuggito alle virgolette doppie. Solo la barra rovesciata (non tra virgolette doppie) e le virgolette singole sfuggono.

bash

come ksh93 ma:

  • nelle impostazioni locali con caratteri a byte singolo, tutto vuoto (a seconda della locale) i caratteri sono considerati come delimitatori (come spazio o tabulazione). In effetti, ciò significa che dovresti citare tutti i byte con l'ottavo bit impostato nel caso in cui possano essere un carattere vuoto in alcune impostazioni locali.
  • l'espansione della cronologia csh è abilitata per impostazione predefinita nelle istanze interattive, con le stesse note di ksh93 sopra, tranne che nelle versioni più recenti di bash , ! inoltre non è speciale a volte, se seguito da un " .

zsh

come ksh93 ma:

  • stessa nota di bash per l'espansione della cronologia csh
  • = è speciale come primo carattere di una parola (=ls si espande in /bin/ls ).
  • { e } può anche aprire e chiudere gruppi di comandi quando non sono delimitati (come in {echo text} funziona come { echo text;} di Bourne ).
  • tranne [ da solo, [ esigenze citate anche se non chiuse con un ] .
  • Con il extendedglob opzione abilitata, # , ^ e ~ sono operatori di globbing.
  • Con il braceccl opzione, {non-empty-string} è speciale.
  • $"..." non è supportato.
  • come stranezza speciale, ? non è speciale quando si segue un % (anche tra virgolette o espansi) all'inizio di una parola (per consentire il %?name specifica del lavoro)
  • un rcquotes opzione (non abilitata per impostazione predefinita) consente di inserire virgolette singole come '' tra virgolette singole à la rc (vedi sotto).
Correlati:LVM ha un impatto sulle prestazioni?

yash

come POSIX tranne quello.

  • tutti i caratteri vuoti sono considerati delimitatori.
  • Con il brace-expand opzione, implementa l'espansione delle parentesi graffe in stile zsh.

Per tutte le shell, ci sono alcuni contesti speciali in cui le citazioni funzionano in modo diverso. Abbiamo già menzionato qui documenti e backtick, ma c'è anche [[...]] in ksh e poche altre shell, POSIX $((...)) , case costruisce...

Si noti inoltre che le virgolette possono avere altri effetti collaterali quando si tratta di espansioni (con virgolette doppie) o quando applicato a delimitatori di documenti qui. Disabilita anche le parole riservate e influisce sull'espansione dell'alias.

Riepilogo

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

Per rimuovere il significato speciale in modo che siano trattati alla lettera, usi le virgolette.

Usa:

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

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

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

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

  • usa "..." per citare i caratteri pur consentendo l'espansione dei parametri ($var , $# , ${foo#bar} …), espansione aritmetica ($((1+1)) , anche $[1+1] in alcune shell) e sostituzione di comando ($(...) o la vecchia forma `...` . In realtà, la maggior parte delle volte, vuoi comunque mettere quelle espansioni tra virgolette doppie. Puoi usare entro "..." per rimuovere il significato speciale dei caratteri che sono ancora speciali (ma solo loro).

  • se la stringa contiene ' carattere, puoi ancora usare '...' per il resto e usa altri meccanismi di citazione che possono citare ' come "'" o ' o (ove disponibile) $''' :

    echo 'This is "tricky", isn'''t it?'
    
  • Usa il moderno $(...) forma di sostituzione del comando. Usa solo il vecchio `...` per compatibilità con la shell Bourne, cioè con sistemi molto vecchi, e solo nelle assegnazioni di variabili, come in non usare:

    echo "`echo "foo bar"`"
    

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

    echo "`echo "foo bar"`"
    

    Che funzionerà con Bourne e AT&T ksh, ma non con yash (Modifica 2020: solo nella versione 2.41 e precedenti, tuttavia, è stato modificato in 2.42 / bug report / commit), ma usa:

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

    che funzionerà con tutti.

    Anche nidificarli in modo portatile con virgolette doppie è impossibile, quindi, ancora una volta, usa le variabili. Fai attenzione anche alla speciale elaborazione della barra rovesciata:

    var=`printf '%sn' '\'`
    

    Memorizzerà solo una barra rovesciata all'interno di $var , perché è disponibile un ulteriore livello di elaborazione della barra rovesciata (per , ` e $ (e anche " quando citato tranne in yash )) all'interno dei backtick, quindi è necessario uno dei due

    var=`printf '%sn' '\\'`
    

    o

    var=`printf '%sn' '\'
    

    invece.

Famiglia Csh

csh e tcsh hanno una sintassi significativamente diversa, anche se c'è ancora molto in comune con la shell Bourne poiché condividono un'eredità comune.

Caratteri speciali:

  • "'&|;()^`<>$ , spazio, nuova riga e tabulazione sono speciali ovunque se non citati.
  • # (csh è la shell che ha introdotto # come leader del commento) è speciale all'inizio di uno script o dopo uno spazio, una tabulazione o una nuova riga senza virgolette.
  • *?[ sono speciali come operatori di globbing, quindi in contesti di elenco
  • {non-empty-string} è speciale (csh è la shell che ha introdotto l'espansione delle parentesi graffe).
  • ! e ^ sono speciali come parte dell'espansione della storia (di nuovo, un'invenzione csh) e le regole per le virgolette sono speciali.
  • ~ (tilde espansione anche un'invenzione csh) è speciale in alcuni contesti.

Operatori di quotazione

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 brutti bug. Ottieni l'ultima versione di tcsh per ottenere una versione approssimativamente funzionante di csh.

  • esegue l'escape di un singolo carattere eccetto newline (come per la shell Bourne). È l'unico operatore di virgolette che può sfuggire a ! . <newline> non gli sfugge ma lo trasforma da separatore di comandi a separatore di token (come lo spazio)
  • "..." esegue l'escape di tutti i caratteri tranne se stesso, $ , ` , nuova riga e ! . Contrariamente alla shell Bourne, non puoi usare per sfuggire a $ e ` dentro "..." , ma puoi usare per sfuggire a ! o newline (ma non se stesso tranne quando prima di un ! o nuova riga). Un letterale ! è "!" e un letterale ! è "\!" .
  • '...' esegue l'escape di tutti i caratteri tranne se stesso, ! e nuova riga. Come per le virgolette, ! e newline può essere preceduto da una barra rovesciata.
  • La sostituzione dei comandi avviene solo tramite il `...` sintassi e difficilmente può essere utilizzato in modo affidabile.
  • Anche la sostituzione delle variabili è progettata piuttosto male e soggetta a errori. Un $var:q operatore aiuta a scrivere codice più affidabile che coinvolge variabili.
Correlati:dove si trovano le operazioni speciali di incollaggio di Excel in Fogli Google?

Riepilogo

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

  • virgolette singole per citare la maggior parte dei caratteri. ! e newline hanno ancora bisogno di un .
  • può sfuggire alla maggior parte dei caratteri
  • "..." può consentire alcune espansioni al suo interno, ma è piuttosto buggato se incorporano caratteri di nuova riga e/o barra rovesciata, la cosa migliore potrebbe essere usare solo virgolette singole e $var:q per espansione variabile. Dovrai utilizzare i loop se desideri unire elementi di un array in modo affidabile.

rc famiglia

rc è il plan9 shell e come i suoi discendenti es e akanga è stato portato su Unix e simili a unix. 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

Caratteri speciali

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

Operatore di quotazione

'...' è l'unico operatore di virgolette. Un letterale ' è scritto con '' tra virgolette singole come in:

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

es

es potrebbe essere visto come un sperimentale shell basata su rc .

Ha alcune differenze però. Quello di interesse per questa domanda/risposta è è anche un operatore di virgolette (che virgolette tutti i caratteri speciali eccetto newline) e può essere utilizzato anche per introdurre sequenze di escape come n per nuova riga, b per barra rovesciata...

pesce

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

caratteri speciali

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

Operatori di quotazione

  • cita un singolo carattere speciale tranne newline, ma attenzione, funge anche da sequenza di escape C (n , b …) presentatore. IOW, n non è un n tra virgolette ma una nuova riga.
  • "..." cita tutto tranne se stesso, $ e backslash e backslash possono essere usati per sfuggire a quelli. <newline> è una continuazione di riga (rimossa) all'interno di "..." .
  • '...' cita tutto tranne se stesso e e puoi usare la barra rovesciata per sfuggire a quelli.

Linux
  1. Come usare BusyBox su Linux

  2. Come uso cron in Linux

  3. UNIX / Linux:come utilizzare Sticky Bit su directory e file

  4. Come usare dos2unix?

  5. Come verificare se una stringa contiene un carattere speciale ([email protected]#$%^&*()_+)

Come usare il comando grep in Linux/UNIX

Come utilizzare Instagram nel terminale

Come usare il comando PS

Come usare il comando TOP

Come utilizzare lookahead per escludere caratteri speciali in un'espressione regolare

Come si identifica la distribuzione Linux in uso?