Tek tırnak içinde değişkenler nasıl kullanılır?


11

Tek tırnak gömülü çift tırnak giriş öznitelikleri olarak alır bir uygulama var. Örneğin şu doğru komutu ele alalım:

command -p 'cluster="cl1"'

Otomatikleştirmek için $CLUSTERdeğişken olarak bir bash dosyası oluşturdum . Benim emrim nasıl olmalı? Başka bir deyişle, cl1 yerine ne koymalıyım?

Yukarıdaki komutu değiştirirsem, kabul edilmeyeceğini lütfen unutmayın. Örneğin: command -p "cluster=cl1"kabul edilmiyor


2
CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"
mikeserv

Başka bir olasılık ( değişken cliiçinde tırnak işaretleri olmadan saklamak isterseniz CLUSTER):CLUSTER='cl1'; command -p 'cluster="'"$CLUSTER"'"'
jimmij

Sonunda doğru cevabı buldum. Teşekkürler @jimmij.
Mohamad-Jaafar NEHME

Yanıtlar:


8

Komutunuz belki de ortam değişkenlerini komut satırında verilen argümanlara göre ayarlıyor gibi görünüyor. Yapabileceğiniz olabilir:

CLUSTER=cl1; cluster=$CLUSTER command

... ve ortamını çağrılmada ayarladı.

Aksi takdirde, kabuk tırnakları genellikle bağımsız değişkenleri sınırlar veya kabuk yorumlamasından diğer özel kabuk karakterlerinden kaçar. Çeşitli kurallara dayanarak diğer türlerde farklı türlerde kabuk tırnakları içerebilir (ve bu nedenle kaçabilirsiniz) :

  • "''''" - yumuşak tırnaklı bir dize herhangi bir sayıda sert tırnak içerebilir.
  • "\""- \ters eğik çizgi, yumuşak tırnaklı bir dize "içindeki yumuşak tırnaktan kaçabilir ".
    • Bu bağlamda, bir \\ters eğik çizgi de kendini, \$genişleme belirtecini ve \naşağıda belirtildiği gibi ewlines'lardan kaçar , ancak tam anlamıyla tedavi edilir.
  • "${expand} and then some"- yumuşak tırnaklı bir dize yorumlanmış bir kabuk $genişletmesi içerebilir .
  • '"\'- 'sert tırnak içine alınmış bir dize, sert tırnak dışında herhangi bir karakter içerebilir '.
  • \- \nalıntılanmamış bir ters eğik çizgi, gerçek yorumlama için herhangi bir karakterden kaçar - hatta başka bir ters eğik çizgi - bir ewline hariç .
    • Bir \\newline durumunda, hem \ters eğik çizgi hem de \newline, elde edilen yorumlanmış komuttan tamamen kaldırılır.
  • ${parameter+expand "$parameter"}- Bir kabuk genişlemesinden kaynaklanan alıntılar, neredeyse hiçbir zaman birkaç özel durum haricinde sınırlayıcı işaretleyici işlevi görmez. Bunları burada daha fazla açıklamak için girişimde bulunmayacağım.

Ben herhangi bir uygulamanın kendi komut satırı argümanlarında tırnak yorumlamak tuhaf olduğunu düşünüyorum. Böyle bir uygulama, en azından mermiler için, bir teklifin birincil amacının genellikle bir argümanı sınırlamak olduğu için çok anlamlı değildir. Çağırma anda, ancak, argümanlar her zaman vardır zaten ayrılmış olan \0NULkarakterler ve bir alıntı çok amaca hizmet edemez.

Bir kabuk bile, yalnızca bir -canahtarla çağrıldığında çağırma argümanlarından birinde tırnakları yorumlamakla uğraşacaktır - bu, ilk işleneninin aslında çağırma üzerine çalıştırması gereken bir kabuk komut dosyası olduğunu gösterir. Bu, iki kez değerlendirilen girdi örneğidir .

Tüm bunlar, komut satırındaki bağımsız değişkenler aracılığıyla gerçek tırnak işaretleri geçirmek için birkaç şey yapabilirsiniz. Örneğin:

CLUSTER='"cl1"'; command -p "cluster=$CLUSTER"

Daha önce bir yorumda belirttiğim gibi, "tırnak işaretlerini kendi içinde belirtilen bir genişletme içinde içerebilir ".

CLUSTER=cl1; command -p "cluster=\"$CLUSTER\""

Alıntılanan dize içinde ters eğik çizgi "ile kaçabilirsiniz .\"

CLUSTER=cl1; command -p cluster='"'"$CLUSTER"'"'

Yukarıdaki @jimmij notları olarak istediğiniz son sonuca ulaşmak için alıntı stillerini değiştirebilir ve birleştirebilirsiniz .

CLUSTER=cl1; ( set -f; IFS=; command -p cluster=\"$CLUSTER\" )

Her iki devre dışı bırakabilir dosya adı oluşturulması ve $IFSbu suretle alıntı yapmak ihtiyacını kaçınarak - bölme $expansionhiç - ve böylece sadece tırnak alıntı. Muhtemelen aşırıya kaçmış.

Son olarak, kullanılabilecek başka bir kabuk-alıntı türü vardır. Daha önce de belirttiğim gibi sh -c "$scriptlet", kabuk çağırma biçimi genellikle komut satırında bir kabuk komut dosyası sağlamak için kullanılır. Ancak $scriptlet, tırnak işaretleri başka tırnaklar içermesi gerektiği gibi karmaşıklaştığında, burada bir belgenin kullanılması genellikle avantajlı olabilir ve sh -sbunun yerine, kabuğa aşağıdaki tüm işlenenleri bir -cdurumda olduğu gibi konum parametrelerine ataması talimatı verilir. henüz senaryosunu da almamış stdin.

Komutunuz tırnakları bu şekilde yorumlamalıysa, o zaman bir dosya girişinde yapabilirse daha iyi düşünürdüm. Örneğin:

CLUSTER=cl1
command --stdin <<-SCRIPT
    cluster="$CLUSTER"
SCRIPT

Eğer a sınırlayıcı alıntı yoksa <<here-documentonlar gibi içeriği neredeyse tam davranılır tüm o "- yumuşak alıntılanan haricinde o "kendilerini özel olarak ele edilmez çift tırnak. Ve catbunun yerine yukarıdaki ile çalışırsak :

CLUSTER=cl1
cat <<-SCRIPT
        cluster="$CLUSTER"
SCRIPT

... yazdırıyor ...

cluster="cl1"

1

Gibi mikeserv yazdı:

 CLUSTER='"cl1"'; command -p "cluster=$CLUSTER" 

"Çift tırnak" boşluk / meta karakterler ve içeren her değişmezi her genişleme: "$var", "$(command "$var")", "${array[@]}", "a & b". Kullanın 'single quotes'kodu veya literal için $'s: 'Costs $5 US', ssh host 'echo "$HOSTNAME"'. Bkz.
Http://mywiki.wooledge.org/Quotes
http://mywiki.wooledge.org/Arguments
http://wiki.bash-hackers.org/syntax/words


Haklısın, teşekkürler. Peki otomasyon ne olacak? CLUSTER okumak istediğimi varsayalım? Aynı sorunla tekrar sıkışıp kalacağım: tek tırnak içinde değişken
Mohamad-Jaafar NEHME

@Moi - otomasyon çok önemli değil, ancak "karakter değişkenini sterilize etmeniz gerekecek - sadece ilk ve sonuncusu yeterli olmalı. Buradaki asıl sorun, uygulamanızın bir argümandaki alıntıları yorumlamasıdır. Bir argümanda bir alıntıyı yorumlamak neredeyse hiçbir zaman iyi bir fikir değildir, çünkü bir alıntı sadece bir argümanı sınırlama aracı olmalıdır - ve çağrıldığında sınırlandırmanın \0NULher durumda s tarafından ele alındığı . Muhtemelen istediğiniz bilgiyi uygulamaya iletmenin daha iyi bir yolu var mı? Bir command --'script=/path/to/some/file'şey gibi mi?
mikeserv
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.