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 doposet -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) inbash
,zsh
,mksh
e FreeBSD e busyboxsh
. 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 à larc
(vedi sotto).
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 usareentro
"..."
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 inyash
)) all'interno dei backtick, quindi è necessario uno dei duevar=`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 usareper sfuggire a
$
e`
dentro"..."
, ma puoi usareper 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.
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 è unn
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 ee puoi usare la barra rovesciata per sfuggire a quelli.