Come riecheggiare `virgoletta singola` quando si usa virgoletta singola per avvolgere caratteri speciali nella shell?


26

Sto leggendo il tutorial della shell oggi da http://www.tutorialspoint.com/unix/unix-quoting-mechanisms.htm

In cui menziona:

Se una singola virgoletta appare all'interno di una stringa da produrre, non dovresti inserire l'intera stringa tra virgolette singole, ma devi precedere quella usando una barra rovesciata () come segue:

echo 'It\'s Shell Programming'

Ho provato questo sul mio server centos, non funziona, mi viene >richiesto di suggerirmi di scrivere di più.

Mi chiedevo, poiché due virgolette singole trasformano ogni carattere speciale in caratteri normali, che includono il simbolo di escape \, ma si escludono ',
come , come dovrei rappresentare una singola virgoletta singola 'in una frase a virgoletta singola?


1
Perché non usare echo It\'s Shell Programmingo echo "It's Shell Programming"?
cuonglm

@cuonglm, perché posso usare una frase del tipoecho Wow, I'm going to have lots of $$$$$$ now
Zen

2
Quindi dovresti usare le virgolette doppie e anche scappare $. Qualcosa di simile echo Wow, I\'m going to have lots of \$\$\$\$\$\$ nowo soloecho Wow, I\'m going to have lots of '$$$$$$' now
cuonglm

@cuonglm, sì, posso farcela e so come posso farcela. Ma il tutorial che sto leggendo sembra essere sicuro che ci sia un modo per sfuggire alla virgoletta singola all'interno di frasi a virgoletta singola, ma l'esempio fornito del tutorial non funziona. Quindi mi chiedo che qualcuno possa conoscere la soluzione.
Zen

1
Cosa ne pensi di questo? echo 'It'"'"'s Shell Programming'. Lo divido solo in 3 stringhe, la prima e l'ultima racchiuse tra virgolette singole, ma quella centrale ha una virgoletta singola racchiusa tra virgolette doppie.
jcbermu,

Risposte:


49

Il tutorial è sbagliato.

POSIX dice:

Una virgoletta singola non può essere presente tra virgolette singole.

Ecco alcune alternative:

echo $'It\'s Shell Programming'  # ksh, bash, and zsh only, does not expand variables
echo "It's Shell Programming"   # all shells, expands variables
echo 'It'\''s Shell Programming' # all shells, single quote is outside the quotes
echo 'It'"'"'s Shell Programming' # all shells, single quote is inside double quotes

Ulteriori letture: Citazioni - Greg's Wiki


4
Ancora una: echo 'It''s Shell Programming'- zsh con rc_quotesset di opzioni (e anche la shell rc) - una coppia di virgolette singole all'interno di virgolette singole rappresenta una singola virgoletta singola.
Michał Politowski

5
A volte uso q="'"e qq='"'per rendere questo più pulito. Ciò quindi consente echo "It${q}s ${qq}Shell Programming${qq}"(sono necessarie parentesi graffe date le lettere finali). POSIX-safe. Lo strato esterno deve essere tra virgolette doppie.
Adam Katz,

1

Puoi usare:

sed "s/'"'/&\\&&/g
     s/.*/'"'&'"'/
' <<IN
$arbitrary_value
IN

Per eseguire la shell in modo sicuro, citare una riga di valore per riga.

Shell a seconda, potresti anche avere la possibilità di fare:

printf %q\\n "$arbitrary_value"

Anche se di solito preferisco fare:

a=$(alias "a=$arbitrary_value" a); a=${a#*=}

Un approccio più manuale potrebbe apparire come:

sq(){ set \' "$1"
      while case $2 in (*\'*) :;;
      (*) ! RETURN="$1$2'"     ;;esac
      do  set "$1${2%%\'*}'\''" "${2#*\'}"
      done
}

... che è, almeno, senza forcella.


1
Non ho assolutamente idea di cosa tu stia parlando, tranne la frase printf %q\\n "$arbitrary_value", gli altri sono troppo complicati.
Zen

1

Nel caso in cui venga qualcun altro a mettere un mix di virgolette singole e doppie in un file, anche questo funziona:

cat > its-shell-programing.txt << __EOF__
echo $'It\'s Shell Programming'
echo "It's Shell Programming"
echo 'It'\''s Shell Programming'
echo 'It'"'"'s Shell Programming'
__EOF__

Tutto ciò che la shell potrebbe vedere come una variabile deve essere sfuggito a una barra rovesciata:

cat >> its-shell-programing.txt << __EOF__
echo \$It\'s Shell Programming
__EOF__
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.