Neden bash değişkeni genişlemesi tırnak içinde kalıyor?


12
> echo "hi"
hi
> VAR='echo "hi"'
> $VAR
"hi"

Yukarıdaki komutların çıktısı neden farklı?

Benzer bir şey tek tırnak işaretleri için de geçerlidir:

> VAR="echo 'hi'"
> $VAR
> 'hi'

6
Lütfen yürütülebilir kod snippet'lerini değişkenlere gömme alışkanlığı edinmeyin. Bu en iyi şekilde zor olma eğilimindedir ve evalçok dikkatli bir şekilde
basmanız

@ jw013 İyi nokta ve harika makaleler. Ben teklif "Değişkenler veri tutun, fonksiyonlar kodu tutun." İlk bağlantısından ama benim kullanım için, (bu durumda bir işleve verilir veri at) olduğu kodu. Verilecek kodu düzenlemek / toplamak için daha güvenli bir yol var atmı?
Cory Klein

atshsözdizimini girdi olarak alır . Bu nedenle , önemsiz olmayan gelişigüzel girişten atgeçerli, uygun şekilde alıntılanmış shsözdizimi üretme araçları için girdi oluşturma , bu yüzden mümkünse bundan kaçınmaya çalışacağım. Yapmaya çalıştığınız şey hakkında biraz daha ayrıntılı bilgi vermeniz gerçekten yararlı olacaktır.
jw013

Maalesef, çok fazla ayrıntıya dikkat çekmek istemedim, ancak yaptığım şey gerçekten karmaşık değil, IMO. "Zaman" ve "mesaj" alan bir komut dosyası oluşturuyorum. Daha sonra atverilen "süre" atiçin çalışır ve komutu çalıştırmasını söyler dzen2. dzen2stdin'den "message" alır ve diğer bazı statik parametreleri kullanır. Zorluk şu ki, "message" parametresini kullanıcıdan dzen2komuta eklemeliyim, ama aslında dzen2kendimi çalıştırmıyorum , bunu atyapmayı söylüyorum .
Cory Klein

Yanıtlar:


16

Fazladan alıntılar sadece fazladan bir değerlendirme adımı ile tüketilir. Örneğin eval:

bash-4.2$ VAR='echo "hi"'

bash-4.2$ $VAR
"hi"

bash-4.2$ eval $VAR
hi

Ancak genellikle parametrelerle komutları bir dizeye koymak kötü bir fikirdir. Bunun yerine bir dizi kullanın:

bash-4.2$ VAR=(echo "hi")

bash-4.2$ "${VAR[@]}"
hi

1
Fiyat tekliflerinin farklı değerlendirildiğine dikkat etmek de önemlidir; çift ​​tırnak (") ekteki dizginin değerlendirilmesine izin verir, tek tırnak (') dizgiyi değişmez olarak yazdırır Örnek: "$(ls)"ve '$(ls)'. Özgün soru örneklerinde tırnakların bu yüzden görünmesinin nedeni budur
Joseph Kern

Dizi aynı zamanda bir sorun kaynağıdır. Kod fonksiyonlara, veriler değişkenlere aittir. Sunduğunuz örnek yalnızca tırnak işaretleri dizinin bölünmesinde kaldırıldığı için çalışır. Bir printf '<%s> ' "${VAR[@]}"tekliflerin zaten kaldırıldığını gösterecektir. Gibi VAR ayarlarsanız VAR=(echo \"hi\")aslında tırnak sahip olmak, aynı sorun yeniden görünür $ ${VAR[@]}yazdırır"hi"

9

Fiyat teklifi kaldırma , genişletmelerin sonucu olarak değil , yalnızca orijinal giriş sözcüklerinde gerçekleşir . Genişletilmiş değişkenlerin bir parçası olan tırnaklara dokunulmaz.


2

Biraz geri adım atarsanız, değişken ikamesinin neden tırnakları saklaması gerektiğini görebilirsiniz.

Unix / Linux / BSD kabuğundaki tırnak işareti, bir dizenin parçalarını bir arada tutmaktır, aksi takdirde birden çok dize olarak ayrıştırılır. Bir kabuk varsayılan olarak bir boşluk ayırıcısı olarak boşluk kullandığından, bir şekilde alıntı yapılmazsa veya bir şekilde kaçmazsa boşluklu bir dize 3 dize olarak ayrıştırılır: "bir", "iki" ve "üç".

Bir programlayıcı enterpolasyonlu bazı değişkenlerin değeri olan bir dize istiyorsa:

VAR=two
STRING="one $VAR three"

kabuk kesinlikle tırnak işaretlerini kaldırmamalıdır: boşluk içeren dize 3 küçük dizge olarak ayrıştırılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.