Bagaimana gema `kutipan tunggal` saat menggunakan kutipan tunggal untuk membungkus karakter khusus dalam shell?

26

Saya membaca tutorial shell hari ini dari http://www.tutorialspoint.com/unix/unix-quoting-mechanisms.htm

Di mana disebutkan:

Jika kutipan tunggal muncul dalam string untuk menjadi output, Anda tidak harus menempatkan seluruh string dalam kutipan tunggal, Anda harus terlebih dahulu menggunakan backslash () sebagai berikut:

echo 'It\'s Shell Programming'

Saya mencoba ini di server centos saya, itu tidak berhasil, >permintaan untuk mengisyaratkan saya mengetik lebih banyak.

Saya bertanya-tanya, karena dua kutipan tunggal mengubah setiap karakter khusus menjadi karakter normal, yang termasuk simbol pelarian \, tetapi mengecualikan dirinya sendiri ',,
bagaimana saya harus mewakili satu kutipan tunggal 'dalam frasa yang dikutip tunggal?

Zen
sumber
1
Mengapa tidak menggunakan echo It\'s Shell Programmingatau echo "It's Shell Programming"?
cuonglm
@cuonglm, karena saya dapat menggunakan frasa sepertiecho Wow, I'm going to have lots of $$$$$$ now
Zen
2
Jadi, Anda harus menggunakan tanda kutip ganda, dan melarikan diri $juga. Sesuatu seperti echo Wow, I\'m going to have lots of \$\$\$\$\$\$ nowatau hanyaecho Wow, I\'m going to have lots of '$$$$$$' now
cuonglm
@cuonglm, ya, saya bisa melakukannya, dan saya tahu bagaimana saya bisa melakukannya. Tapi tutorial yang saya baca tampaknya percaya diri bahwa ada cara untuk lolos dari kutipan tunggal di dalam frase yang dikutip sendiri, tetapi contoh tutorial yang diberikan tidak bekerja. Jadi saya ingin tahu seseorang mungkin tahu solusinya.
Zen
1
Bagaimana dengan ini? echo 'It'"'"'s Shell Programming'. Saya hanya membaginya menjadi 3 string, yang pertama dan yang terakhir dikelilingi oleh tanda kutip tunggal, tetapi yang di tengah memiliki tanda kutip tunggal yang dikelilingi oleh tanda kutip ganda.
jcbermu

Jawaban:

49

Tutorialnya salah.

POSIX mengatakan:

Kutipan tunggal tidak dapat terjadi dalam tanda kutip tunggal.

Inilah beberapa alternatif:

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

Bacaan lebih lanjut: Kutipan - Wiki Greg

Mikel
sumber
4
Satu lagi: echo 'It''s Shell Programming'- zsh dengan rc_quotesset opsi (dan shell rc juga) - sepasang tanda kutip tunggal di dalam tanda kutip tunggal mewakili tanda kutip tunggal.
Michał Politowski
5
Saya terkadang menggunakan q="'"dan qq='"'membuat pembersih ini. Ini kemudian memungkinkan echo "It${q}s ${qq}Shell Programming${qq}"(kurung keriting diperlukan diberikan huruf tambahan). POSIX-safe. Lapisan luar harus dikutip ganda.
Adam Katz
1

Anda dapat gunakan:

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

Untuk dengan aman mengutip kutipan garis nilai per baris.

Tergantung pada Shell, Anda mungkin juga memiliki opsi untuk melakukan:

printf %q\\n "$arbitrary_value"

Padahal saya biasanya lebih suka melakukan:

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

Pendekatan yang lebih manual bisa terlihat seperti:

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

... yang, setidaknya, bebas garpu.

mikeserv
sumber
1
Saya benar-benar tidak tahu apa yang Anda bicarakan, kecuali frasa printf %q\\n "$arbitrary_value", yang lain terlalu rumit.
Zen
1

Jika ada orang lain datang untuk menempatkan campuran tanda kutip tunggal dan ganda ke dalam file, ini juga berfungsi:

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__

Segala sesuatu yang mungkin dilihat shell sebagai variabel harus diloloskan oleh backslash:

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