Yanıtlar:
Tek tırnaklar hiçbir şey için enterpolasyon yapmaz, ancak çift tırnak işaretleri olur. Örneğin: değişkenler, ters çentikler, belirli \
kaçışlar, vb.
Misal:
$ echo "$(echo "upg")"
upg
$ echo '$(echo "upg")'
$(echo "upg")
Bash el kitabı şunları söylemektedir:
Karakterleri tek tırnak içine almak (
'
) tırnak içindeki her karakterin gerçek değerini korur. Bir ters eğik çizgiden önce de olsa, tek tırnak işaretleri arasında tek bir tırnak oluşmayabilir.(Çift tırnak karakterleri çevreleyen
"
) hariç olmak üzere, tırnak içindeki tüm karakterlerin değişmez değerini korur$
,`
,\
, ve, geçmiş genişleme etkinken,!
. Karakterler$
ve`
özel anlamlarını çift tırnak içinde tutun (bkz. Kabuk Genişletmeleri ). Aşağıdaki karakterlerden biri tarafından bitirilen ters eğik çizgi sadece özel bir anlam korur:$
,`
,"
,\
veya yeni satır. Çift tırnak içinde, bu karakterlerden birini izleyen ters eğik çizgiler kaldırılır. Özel bir anlamı olmayan karakterlerden önceki ters eğik çizgiler değiştirilmez. Bir çift tırnak, bir ters eğik çizgi ile önüne çift tırnak içine alınabilir. Etkinleştirilirse,!
çift tırnak işareti içinde görünen bir ters eğik çizgi kullanılarak çıkış yapılmadığı sürece geçmiş genişlemesi gerçekleştirilir . Tarihinden önceki ters eğik çizgi!
kaldırılmaz.Özel parametreler
*
ve@
çift tırnak içinde özel bir anlamı vardır (bkz. Kabuk Parametre Genişlemesi ).
git_prompt
git kullandığınızda ne olur, bu şekilde kullanmanızı öneririm PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '
, git istemi , buna göre çalışmamalı. PS#
Değişkenler hakkında özel bir şey var mı ? veya enterpolasyon yapmıyorsa neden çalışır?
PS1
. Deneyin echo $PS1
ne demek istediğimi görmek için. Ancak PS1
görüntülenmeden önce değerlendirilir ( PROMPTING
bash man sayfasındaki bölüme bakın ). Bunu test etmek için deneyin PS1='$X'
. Hiç isteminiz olmayacak. Sonra çalıştırın X=foo
ve aniden isteminiz "foo" ( görüntülenen yerine belirlendiğindePS1
değerlendirilmişti hala hiçbir istemi olurdu).
Kabul edilen cevap harika. Konuyu hızlı bir şekilde anlamaya yardımcı olan bir tablo yapıyorum. Açıklama, basit bir değişkenin a
yanı sıra dizinlenmiş bir diziyi de içerir arr
.
Eğer ayarlarsak
a=apple # a simple variable
arr=(apple) # an indexed array with a single element
ve sonra echo
ikinci sütundaki ifadeyi, üçüncü sütunda gösterilen sonucu / davranışı elde ederiz. Dördüncü sütun davranışı açıklar.
# | 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
---+-------------+-------------+--------------------------------------------------------------------
Ayrıca bakınız:
The special parameters * and @ have special meaning when in double quotes
nasıl oluyor böylece "*"
sonuçları *
?
"$@"
ve "$*"
parametre genişletmeleridir. "@"
ve "*"
değil.
echo "\'"
beni döndürür \'
.
Bir şeyi yankıladığınızda ne olacağına atıfta bulunuyorsanız, tek tırnak işaretleri aralarında ne varsa tam anlamıyla yankılanırken, çift tırnaklar arasındaki değişkenleri değerlendirir ve değişkenin değerini verir.
Örneğin, bu
#!/bin/sh
MYVAR=sometext
echo "double quotes gives you $MYVAR"
echo 'single quotes gives you $MYVAR'
bunu verecek:
double quotes gives you sometext
single quotes gives you $MYVAR
Diğerleri çok iyi açıkladılar ve basit örneklerle vermek istediler.
Kabuğun herhangi bir özel karakteri yorumlamasını önlemek için metin etrafında tek tırnak kullanılabilir. Dolar işaretleri, boşluklar, ve işaretleri, yıldız işaretleri ve diğer özel karakterler tek tırnak içine alındığında yok sayılır.
$ echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
Bunu verecektir:
All sorts of things are ignored in single quotes, like $ & * ; |.
Tek tırnak içine alınamayan tek şey tek tırnaktır.
Çift tırnaklar tek tırnaklara benzer şekilde hareket eder, ancak çift tırnaklar kabuğun dolar işaretlerini, geri tırnak işaretlerini ve ters eğik çizgileri yorumlamasına izin verir. Ters eğik çizgilerin tek bir özel karakterin yorumlanmasını engellediği zaten bilinmektedir. Bir dolar işareti değişken yerine metin olarak kullanılması gerekiyorsa, bu çift tırnak içinde yararlı olabilir. Ayrıca, tırnak içine alınmış bir dizenin sonu olarak yorumlanmamaları için çift tırnak işaretleri kullanılmasına izin verir.
$ echo "Here's how we can use single ' and double \" quotes within double quotes"
Bunu verecektir:
Here's how we can use single ' and double " quotes within double quotes
Ayrıca, alıntılanan bir dizenin başlangıcı olarak yorumlanacak olan kesme işaretinin çift tırnak içinde göz ardı edildiği de görülebilir. Bununla birlikte, değişkenler yorumlanır ve çift tırnak içindeki değerleri ile değiştirilir.
$ echo "The current Oracle SID is $ORACLE_SID"
Bunu verecektir:
The current Oracle SID is test
Geri tırnak işaretleri tamamen tek veya çift tırnaklardan farklıdır. Özel tırnakların yorumlanmasını önlemek için kullanılmaktansa, geri alıntılar aslında içerdikleri komutların yürütülmesini zorlar. Ekteki komutlar yürütüldükten sonra, çıktıları orijinal satırdaki arka tırnakların yerine kullanılır. Bu bir örnekle daha açık olacaktır.
$ today=`date '+%A, %B %d, %Y'`
$ echo $today
Bunu verecektir:
Monday, September 28, 2015
Kullanımı arasında net bir ayrım yoktur ' '
ve " "
.
Herhangi bir ' '
şeyin etrafında kullanıldığında, "dönüştürme veya çeviri" yapılmaz. Olduğu gibi yazdırılır.
İle " "
, bunu çevreleyen neyse, "tercüme veya dönüştürülmüş" olan değeri içine.
Çeviri / dönüşüm ile kastediyorum: Tek tırnak içindeki hiçbir şey değerlerine "çevrilmeyecek". Onlar tırnak içinde olduğu gibi alınacaktır. Örnek: a=23
ardından echo '$a'
üretecek $a
standart çıktıda. Halbuki standart çıktıda echo "$a"
üretilecektir 23
.
Bu alıntılarla uğraşırken fiili cevap olduğundan bash
, kabuktaki aritmetik operatörlerle uğraşırken yukarıdaki cevaplarda kaçırılan bir noktayı daha ekleyeceğim.
bash
Kabuk iki yolu aritmetik işlem yapmak destekler ile tanımlanan bir dahili let
komuta ve $((..))
operatör. Birincisi aritmetik bir ifadeyi değerlendirirken ikincisi daha çok bileşik bir ifadedir.
Diğer aritmetik let
komutlarda olduğu gibi, kullanılan aritmetik ifadenin sözcük bölme, yol adı genişletme işleminden geçtiğini anlamak önemlidir . Bu yüzden uygun alıntı ve kaçış yapılması gerekiyor.
Kullanırken bu örneğe bakın let
let 'foo = 2 + 1'
echo $foo
3
Burada tek tırnak işareti kullanmak kesinlikle iyidir, çünkü burada değişken genişletmelere gerek yoktur,
bar=1
let 'foo = $bar + 1'
olarak, sefil başarısız olur $bar
tek tırnak altında olacağını değil genişletmek ve ihtiyaçları gibi çift tırnaklı edilecek
let 'foo = '"$bar"' + 1'
Bu nedenlerden biri $((..))
olmalı, her zaman kullanımı düşünülmelidir let
. Çünkü onun içindekiler, kelime bölünmesine tabi değildir. Önceki örnek let
kullanımı basitçe şu şekilde yazılabilir:
(( bar=1, foo = bar + 1 ))
$((..))
tek tırnak işareti olmadan kullanmayı unutmayınGerçi $((..))
çift tırnak kullanılabilir, bunun sonucu olarak kendisine amaç yoktur olamaz çift tırnak gereken bir içeriğe sahip. Sadece tek tırnaklı olmadığından emin olun.
printf '%d\n' '$((1+1))'
-bash: printf: $((1+1)): invalid number
printf '%d\n' $((1+1))
2
printf '%d\n' "$((1+1))"
2
Bazı özel durumlarda $((..))
operatörü tek tırnaklı bir dize içinde kullanmak, tırnak işaretleri operatörünü tırnaksız veya çift tırnak altında bırakacak şekilde enterpolasyon yapmanız gerekir. Örneğin, curl
her istek yapıldığında bir sayacı geçmek için bir ifadenin içindeki operatörü kullanmak istediğinizde ,
curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
İçinde çift yönlü dizenin alana $((reqcnt++))
geçirildiği iç içe çift tırnak işareti kullanıldığına dikkat edin requestCounter
.
$((...))
de. "Biraz" paranoyak olabilir ve IFS=0
örneğin olması pek olası değildir , ama kesinlikle imkansız değildir :)
$[[...]]
sözdizimi var ama belki de unutmakta haklıydınız.