GNU/Linux >> Linux Esercitazione >  >> Linux

La differenza tra le citazioni "...", '...', $'...' e $"..." In The Shell?

A volte vedo che gli script della shell usano tutti questi modi diversi per citare del testo:"..." , '...' , $'...' e $"..." . Perché vengono utilizzati così tanti tipi diversi di citazione?

Si comportano diversamente o influiscono su ciò che posso fare al loro interno?

Risposta accettata:

Tutti questi significano qualcosa di diverso e puoi scrivere cose diverse al loro interno (o le stesse cose, con un significato diverso). Diversi tipi di virgolette interpretano diverse sequenze di escape al loro interno (something ), oppure consentono o meno le interpolazioni variabili ($something ) e altri tipi di espansione al loro interno.

In breve:

  • '...' è del tutto letterale.
  • "..." consente sia variabili che caratteri di virgolette incorporati.
  • $'...' esegue l'escape dei caratteri come n , ma non espande le variabili.
  • $"..." è per le traduzioni in lingua umana in Bash e ksh.

"Virgolette singole"

Qualunque cosa tu scriva tra virgolette singole viene trattata alla lettera e non elaborata affatto. Le barre rovesciate e i segni del dollaro non hanno un significato speciale lì. Ciò significa che non puoi eseguire l'escape della barra rovesciata di un carattere (incluse altre virgolette singole!), interpolare una variabile o utilizzare qualsiasi altra funzione della shell.

Tutti questi esempi risultano letteralmente in ciò che è scritto tra le virgolette:

Codice Risultato
'hello world' ciao mondo
'/pkg/bin:$PATH' /pkg/bin:$PERCORSO
'hellonworld' il mondo dell'inferno
'`echo abc`' `echo abc`
'I'dn't've' Non avrei

L'ultimo è complicato:ce ne sono due stringhe tra virgolette vengono eseguite insieme a del testo senza virgolette. Il primo contiene I . Il testo senza virgolette dn't contiene una singola virgoletta con escape a livello di shell , quindi non inizia una stringa tra virgolette ed è incluso come carattere letterale (quindi, dn't ). La stringa tra virgolette finale è solo ve . Tutti questi vengono riuniti in una singola parola nel solito modo in cui funziona la shell.

Un idioma alquanto comune per combinare testo letterale e variabili è eseguirli insieme in questo modo:

'let x="'$PATH"

risulterà in

let x="/usr/bin:/bin"

come una singola parola (meglio virgolette $PATH anche per ogni evenienza:spazi o caratteri glob nella variabile value potrebbe essere elaborato in altro modo, ma per motivi di esecuzione leggibile non l'ho fatto).

"virgolette doppie"

Tra virgolette doppie, vengono elaborati due tipi di espansione e puoi utilizzare una barra rovesciata per eseguire l'escape dei caratteri per impedire l'elaborazione di espansioni o escape.

Ci sono due categorie di espansione che si verificano tra virgolette doppie:

  • Quelli che iniziano con $ (espansione del parametro $abc e ${abc} , sostituzione del comando $(...) e espansione aritmetica $((...)) );
  • Sostituzione comando con virgolette `abc`;

All'interno delle virgolette, una barra rovesciata può inibire tali espansioni mettendola prima del $ o ` . Può anche sfuggire a una doppia virgoletta di chiusura, quindi " include solo " nella tua stringa o un'altra barra rovesciata. Qualsiasi altra barra rovesciata viene preservata letteralmente:non ci sono escape per produrre altri personaggi e non viene rimossa.

Alcuni di questi esempi si comportano in modo diverso rispetto a prima, altri no:

Codice Risultato
"hello world" ciao mondo
"/pkg/bin:$PATH" /pkg/bin:/bin:/usr/bin
"hellonworld" il mondo dell'inferno
"hello\nworld" il mondo dell'inferno
"`echo abc`" abc
"I'dn't've" Non avrei
"I'dn't've" Non avrei
"I"dn"t've" Non ho
Correlati:Dhcpv6 – stateful VS stateless, qual è la differenza tra esso?

$'Citazione ANSI-C'

Questo tipo di virgolette consente di elaborare gli escape della barra rovesciata in stile C, ma non variabili incorporate o sostituzioni. È l'solo tipo di citazione che supporta i caratteri di escape .

Questa è un'estensione di ksh, ora supportata anche in Bash, zsh e alcune altre shell. Non fa ancora parte dello standard POSIX e quindi gli script portabili al massimo non possono usarlo, ma uno script Bash o ksh è gratuito.

Tutti questi escape possono essere usati con i loro significati in C:a , b , f , n , r , t , v e il valore letterale è \ , ' , " e ? . Supportano anche le estensioni e (carattere di escape) e in Bash e ksh cx (cosa verrebbe inserito da Ctrl-x, ad esempio cM è il ritorno a capo). Le conchiglie hanno una gamma di estensioni minori proprie.

Consente inoltre quattro tipi di escape di caratteri generici:

  • nnn , un singolo byte con valore ottale nnn
  • xHH , un singolo byte con valore esadecimale HH
  • uHHHH , il codepoint Unicode il cui indice esadecimale è HHHH
  • UHHHHHHHH , il codepoint Unicode il cui indice esadecimale è HHHHHHHH

Tutte queste cifre sono facoltative dopo la prima.

$ e ` non hanno significato e vengono mantenuti alla lettera, quindi non puoi includere una variabile lì.

Codice Risultato
$'hello world' ciao mondo
$'/pkg/bin:$PATH' /pkg/bin:$PERCORSO
$'hellonworld' ciao
mondo
$'`echo abc`' `echo abc`
$'I'dn't've' Non avrei
$'U1f574u263A' 🕴☺

Puoi simulare la maggior parte di questi escape usando printf comando, sebbene POSIX richieda solo \ , a , b , f , n , r , t , v e nnn per lavorare lì. Puoi usare la sostituzione del comando per incorporare un printf tra virgolette se necessario:"Path:$(printf 't')$PATH" .

$"Traduzione locale"

Questa è un'estensione specifica per ksh e Bash per la localizzazione di stringhe testuali in linguaggio naturale e cerca la parte all'interno delle virgolette in un catalogo di messaggi. Esegue prima tutte le espansioni delle virgolette doppie. Se la stringa non viene trovata nel database di traduzione, viene utilizzata come propria traduzione. Il presupposto integrato è che le stringhe siano in inglese.

Probabilmente non vorrai usarlo, ma se lo vedi puoi generalmente trattarlo come normali virgolette doppie.

Un punto da notare è che non c'è nessun tipo di citazione che consente sia l'espansione dei parametri incorporati che l'escape dei caratteri incorporati. Nella maggior parte dei casi in cui lo vorresti, staresti meglio (più sicuro) usando printf :

printf 'New path: e[1m%se[0m' "/pkg/bin:$PATH:"

Questo separa chiaramente quali parti sono soggette a caratteri di escape e quali sono valori di dati.

Un altro è che tutti questi stili di citazione creano una singola "parola" nella shell, a meno che [email protected] o un'espansione dell'array ${x[@]} è usato tra virgolette doppie. Entrambe le forme di virgolette singole sono sempre una parola e non sono mai ampliate ulteriormente.


Linux
  1. L'esatta differenza tra un "terminale", un "shell", un "tty" e una "console"?

  2. Differenza tra shell di accesso e shell non di accesso?

  3. La differenza tra un comando integrato e uno che non lo è?

  4. La differenza tra [[ $a ==Z* ]] e [ $a ==Z* ]?

  5. La differenza di utilizzo tra variabili Shell e variabili d'ambiente?

Qual è la differenza tra Linux e Unix?

Qual è la differenza tra Login e Non-Login Shell

Qual è la differenza tra una console, un terminale e una shell?

Differenza tra '{}' e {} nel comando find?

Qual è la differenza tra ls e l?

Qual è la differenza tra unlink e rm?