Jawaban:
Kutipan tunggal tidak akan menginterpolasi apa pun, tetapi tanda kutip ganda akan. Sebagai contoh: variabel, backticks, \
escapes tertentu , dll.
Contoh:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Manual Bash mengatakan ini:
Menutup karakter dalam tanda kutip tunggal (
'
) mempertahankan nilai literal setiap karakter dalam tanda kutip. Kutipan tunggal mungkin tidak terjadi di antara tanda kutip tunggal, bahkan ketika didahului oleh garis miring terbalik.Melampirkan karakter dalam tanda kutip ganda (
"
) mempertahankan nilai literal dari semua karakter dalam tanda kutip, dengan pengecualian$
,`
,\
, dan, ketika ekspansi sejarah diaktifkan,!
. Karakter$
dan`
mempertahankan makna khusus mereka dalam tanda kutip ganda (lihat Shell Expansions ). Backslash mempertahankan arti khusus hanya ketika diikuti oleh salah satu karakter berikut:$
,`
,"
,\
, atau baris baru. Dalam tanda kutip ganda, garis miring terbalik yang diikuti oleh salah satu karakter ini dihapus. Garis miring terbalik karakter sebelumnya tanpa makna khusus dibiarkan tidak dimodifikasi. Kutipan ganda dapat dikutip dalam tanda kutip ganda dengan mendahului dengan garis miring terbalik. Jika diaktifkan, ekspansi riwayat akan dilakukan kecuali!
kemunculan dalam tanda kutip ganda diloloskan menggunakan backslash. Garis miring terbalik sebelum!
tidak dihapus.Parameter khusus
*
dan@
memiliki arti khusus ketika dalam tanda kutip ganda (lihat Ekspansi Parameter Shell ).
git_prompt
git asalkan mereka menyarankan menggunakannya seperti ini PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, git prompt , menurut ini seharusnya tidak berfungsi. Apakah ada sesuatu yang istimewa tentang PS#
variabel? atau mengapa itu bekerja jika tidak melakukan interpolasi.
PS1
. Coba echo $PS1
lihat apa yang saya maksud. Tetapi PS1
dievaluasi sebelum ditampilkan (lihat PROMPTING
bagian dalam bash manpage). Untuk mengujinya, coba PS1='$X'
. Anda tidak akan memiliki prompt. Kemudian jalankan X=foo
dan tiba-tiba prompt Anda "foo" (telah PS1
dievaluasi saat disetel alih-alih ditampilkan, Anda masih tidak memiliki prompt).
The jawaban yang diterima besar. Saya membuat tabel yang membantu dalam memahami topik dengan cepat. Penjelasannya melibatkan variabel sederhana a
dan juga array yang diindeks arr
.
Jika kita atur
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
dan kemudian echo
ekspresi di kolom kedua, kita akan mendapatkan hasil / perilaku yang ditunjukkan pada kolom ketiga. Kolom keempat menjelaskan perilaku.
# | Expression | Result | Comments
---+-------------+-------------+--------------------------------------------------------------------
1 | "$a" | apple | variables are expanded inside ""
2 | '$a' | $a | variables are not expanded inside ''
3 | "'$a'" | 'apple' | '' has no special meaning inside ""
4 | '"$a"' | "$a" | "" is treated literally inside ''
5 | '\'' | **invalid** | can not escape a ' within ''; use "'" or $'\'' (ANSI-C quoting)
6 | "red$arocks"| red | $arocks does not expand $a; use ${a}rocks to preserve $a
7 | "redapple$" | redapple$ | $ followed by no variable name evaluates to $
8 | '\"' | \" | \ has no special meaning inside ''
9 | "\'" | \' | \' is interpreted inside "" but has no significance for '
10 | "\"" | " | \" is interpreted inside ""
11 | "*" | * | glob does not work inside "" or ''
12 | "\t\n" | \t\n | \t and \n have no special meaning inside "" or ''; use ANSI-C quoting
13 | "`echo hi`" | hi | `` and $() are evaluated inside ""
14 | '`echo hi`' | `echo hi` | `` and $() are not evaluated inside ''
15 | '${arr[0]}' | ${arr[0]} | array access not possible inside ''
16 | "${arr[0]}" | apple | array access works inside ""
17 | $'$a\'' | $a' | single quotes can be escaped inside ANSI-C quoting
18 | "$'\t'" | $'\t' | ANSI-C quoting is not interpreted inside ""
19 | '!cmd' | !cmd | history expansion character '!' is ignored inside ''
20 | "!cmd" | cmd args | expands to the most recent command matching "cmd"
21 | $'!cmd' | !cmd | history expansion character '!' is ignored inside ANSI-C quotes
---+-------------+-------------+--------------------------------------------------------------------
Lihat juga:
The special parameters * and @ have special meaning when in double quotes
jadi bagaimana "*"
hasilnya *
?
"$@"
dan "$*"
merupakan ekspansi parameter. "@"
dan "*"
tidak.
echo "\'"
,, mengembalikan saya \'
.
Jika Anda merujuk pada apa yang terjadi ketika Anda menggemakan sesuatu, tanda kutip tunggal akan benar-benar menggemakan apa yang Anda miliki di antara mereka, sedangkan tanda kutip ganda akan mengevaluasi variabel di antara mereka dan menghasilkan nilai variabel.
Sebagai contoh, ini
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
akan memberikan ini:
double quotes gives you sometext
single quotes gives you $MYVAR
Yang lain menjelaskan dengan sangat baik dan hanya ingin memberi dengan contoh sederhana.
Kutipan tunggal dapat digunakan di sekitar teks untuk mencegah shell menafsirkan karakter khusus. Tanda-tanda dolar, spasi, tanda bintang, tanda bintang, dan karakter khusus lainnya diabaikan ketika dimasukkan dalam tanda kutip tunggal.
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Ini akan memberikan ini:
All sorts of things are ignored in single quotes, like $ & * ; |.
Satu-satunya hal yang tidak dapat dimasukkan ke dalam kutipan tunggal adalah kutipan tunggal.
Kutipan ganda bertindak mirip dengan tanda kutip tunggal, kecuali tanda kutip ganda masih memungkinkan shell untuk menafsirkan tanda dolar, tanda kutip kembali dan garis miring terbalik. Sudah diketahui bahwa backslash mencegah satu karakter khusus dari ditafsirkan. Ini bisa berguna dalam tanda kutip ganda jika tanda dolar perlu digunakan sebagai teks, bukan untuk variabel. Ini juga memungkinkan tanda kutip ganda untuk diloloskan sehingga mereka tidak ditafsirkan sebagai akhir dari string yang dikutip.
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
Ini akan memberikan ini:
Here's how we can use single ' and double " quotes within double quotes
Dapat juga diperhatikan bahwa apostrof, yang jika tidak akan ditafsirkan sebagai awal dari string yang dikutip, diabaikan dalam tanda kutip ganda. Namun, variabel ditafsirkan dan diganti dengan nilainya dalam tanda kutip ganda.
$ echo "The current Oracle SID is $ORACLE_SID"
Ini akan memberikan ini:
The current Oracle SID is test
Kutipan kembali sepenuhnya tidak seperti kutipan tunggal atau ganda. Alih-alih digunakan untuk mencegah penafsiran karakter khusus, kutipan balik justru memaksa pelaksanaan perintah yang mereka lampirkan. Setelah perintah terlampir dijalankan, outputnya diganti dengan tanda kutip di baris aslinya. Ini akan lebih jelas dengan sebuah contoh.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Ini akan memberikan ini:
Monday, September 28, 2015
Ada perbedaan yang jelas antara penggunaan ' '
dan " "
.
Ketika ' '
digunakan di sekitar apa pun, tidak ada "transformasi atau terjemahan" yang dilakukan. Dicetak seperti apa adanya.
Dengan " "
, apa pun yang ada di sekitarnya, "diterjemahkan atau diubah" menjadi nilainya.
Yang saya maksudkan dengan terjemahan / transformasi adalah sebagai berikut: Apa pun di dalam tanda kutip tunggal tidak akan "diterjemahkan" ke nilai-nilai mereka. Mereka akan diambil karena mereka berada di dalam kutipan. Contoh:, a=23
maka echo '$a'
akan menghasilkan $a
output standar. Sedangkan echo "$a"
akan menghasilkan 23
pada output standar.
Karena ini adalah jawaban de facto ketika berhadapan dengan tanda kutip bash
, saya akan menambahkan satu poin lagi yang terlewatkan dalam jawaban di atas, ketika berhadapan dengan operator aritmatika di shell.
The bash
shell mendukung dua cara melakukan operasi aritmatika, yang didefinisikan oleh built-in let
perintah dan $((..))
operator. Yang pertama mengevaluasi ekspresi aritmatika sedangkan yang terakhir lebih merupakan pernyataan majemuk.
Penting untuk memahami bahwa ekspresi aritmatika yang digunakan dengan let
mengalami pemekaran kata, perluasan pathname sama seperti perintah shell lainnya. Jadi mengutip dan melarikan diri yang tepat perlu dilakukan.
Lihat contoh ini saat menggunakan let
let 'foo = 2 + 1'
echo $foo
3
Menggunakan tanda kutip tunggal di sini benar-benar baik-baik saja di sini, karena tidak perlu untuk ekspansi variabel di sini, pertimbangkan kasus
bar=1
let 'foo = $bar + 1'
akan gagal total, karena $bar
kutipan tunggal di bawah tidak akan berkembang dan perlu dikutip ganda sebagai
let 'foo = '"$bar"' + 1'
Ini harus menjadi salah satu alasan, yang $((..))
harus selalu dipertimbangkan untuk digunakan let
. Karena di dalamnya, konten tidak tunduk pada pemisahan kata. Contoh sebelumnya menggunakan let
dapat ditulis sebagai
(( bar=1, foo = bar + 1 ))
$((..))
tanpa tanda kutip tunggalMeskipun $((..))
dapat digunakan dengan tanda kutip ganda, tidak ada tujuan untuk itu karena tidak dapat berisi konten yang akan membutuhkan tanda kutip ganda. Pastikan saja tidak dikutip satu pun.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Mungkin dalam beberapa kasus khusus menggunakan $((..))
operator di dalam string yang dikutip tunggal, Anda perlu menginterpolasi tanda kutip sedemikian rupa sehingga operator dibiarkan tanpa tanda kutip atau di bawah tanda kutip ganda. Misalnya mempertimbangkan suatu kasus, ketika Anda ingin menggunakan operator di dalam curl
pernyataan untuk melewati konter setiap kali permintaan dibuat, lakukan
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
Perhatikan penggunaan tanda kutip ganda bersarang di dalam, yang tanpanya string literal $((reqcnt++))
diteruskan ke requestCounter
bidang.
$((...))
juga. Mungkin paranoid "sedikit" dan sangat tidak mungkin IFS=0
untuk misalnya, tetapi tentu saja itu tidak mustahil :)
$[[...]]
sintaks yang lama tetapi mungkin Anda benar melupakannya.