Bash'de beklenmeyen davranışlar


7

itibaren man bash:

A simple command is a sequence of optional variable assignments
followed by blank-separated words and redirections, and
terminated by a control operator. The first word specifies the
command to be executed, and is passed as argument zero. The
remaining words are passed as arguments to the invoked command.

Bu yüzden yazmak tamamen yasal.

foo=bar echo $foo

ama beklediğim gibi çalışmıyor (sadece yeni bir satır basar). O zamandan beri bana çok garip geldi:

$ foo=bar printenv
foo=bar
TERM=rxvt-unicode
[...]

Birisi lütfen nerede yanlış yaptığımı açıklayabilir mi?

Yanıtlar:


6

Bunun nedeni değişken genişlemesinin komut çalıştırılmadan önce yapılmasıdır. Değişken genleşme gerçekleştiğinde, foo ayarlanmadığı için boş dizgeye genişler. Komut sonra çalışır, ayar foo.


1
Ayrıca, foo'nun echo komutuna önek olarak ayarlandığından, yalnızca bu komut için ayarlandığını (sonraki komutlar için olmadığını) unutmayın. İle karşılaştırmak foo=bar eval 'echo eval sees $foo'; echo echo sees $foo (burada, beri $foo içinde genişletilir eval komut, değer irade orda ikame edilebilir, ancak bir sonraki yankı komutu için değil).
Gordon Davisson

1
Bu çocuğun ortamındaki bir ödevdir (ör. echo Orijinal soruda veya eval Gordon'un örneğinde). Çocuğun ortamındaki değişken atamaları ebeveynin değişken değerlerini etkilemez. foo=bar eval 'foo=$foo'; echo $foo sadece yeni bir satır çıkarır.
Dennis Williamson

itibaren man bash: "Komut adı sonuç vermezse, değişken atamaları mevcut kabuk ortamını etkiler. Aksi halde, değişkenler yürütülen komutun ortamına eklenir ve geçerli kabuk ortamını etkilemez. salt okunur bir değişken, bir hata oluşur ve komut sıfır olmayan bir durumla çıkar. "
Dennis Williamson

1

Eğer yapıyorsan foo=bar ve echo $foo bir satırda işe yaramaz. Üç şeyden birini yapmanız gerekecek.

  1. Bunları ayrı komutlar halinde çalıştırın. yani: foo=bar Girmek echo $foo

  2. Onları bir satırda çalıştırın, ancak ikisi arasında noktalı virgül kullanın. yani: foo=bar; echo $foo

  3. # 2 ile aynı, ancak çift ve işareti ile. yani: foo=bar && echo $foo

2 ile 3 arasındaki fark, 3’ün yalnızca echo $foo Eğer foo=bar başarılı oldu.


Teşekkürler, ama sorunla nasıl başa çıkacağımı biliyorum. Sadece verdiğim örnekle ilgileniyordum.
cYrus

+1: Yine de güzel alternatifler. Bu biri için kullanışlı olabilir.
cYrus

0

Deneyin:

foo=bar; echo $foo
       ^

Dikkat et ; çünkü iki ayrı komutu tek bir satıra sığdırmaya çalışıyorsun. Varsayılan olarak birlikte çalışmıyorlar.



0

Bunu yapmanın uygun bir yolu:

foo=bar sh -c 'echo $foo'
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.