Dizede Bash komutu, dizeyi oluşturduğumda çalıştırıyor, daha sonra kullandığımda değil


10

Kabuk komut dosyası oluşturma konusunda nispeten yeniyim, ancak lftp programını kullanan bir komut dosyasını neredeyse tamamladım . Ben sorun yaşıyorum komut dosyası parçası (ile ayrılmış ;) uzun bir komut dizisi oluşturmak olduğunu .

for var in something
do
    ...
    commands_to_run+="echo Result is `tail -n 1 $somefile`;"
done

Ne fark ediyorum tail- program geri çivilere sarılmış - for döngüsü yinelenen zaman çalıştırılıyor, ama komut dizimi daha sonra komut dizesini çağırdığınızda değil.

Ne yazık ki, $ somefile içeriği bu aşamada incelenmeye hazır değil. Dizeyi oluştururken değil, gerektiğinde yürütme komutunu nasıl alabilirim?

Yanıtlar:


8

Bu biraz zor. Hauke'nin sağladığı bilgiler doğrudur, sadece kullanım durumunuz için ayrıştırılması meselesidir.

En kolay yol, $()sözdizimini kaçış sırasında kullanmaktır, $öyle ki değişken tanım, tanım sırasında ekteki komutu yürütmez $(). Uyarı, sonuçta evaliçiçe yerleştirilmiş komutun yürütülmesi için gerçek sonuç sırasında son sonucun kabuk tarafından yeniden değerlendirilmesi gerektiğidir .

Bir örneğe bakmak çok daha kolay, bu yüzden sizi doğru yola sokması gereken bir tane alın:

for((i=0;i<10;i++)); do 
  date +%s.%N  # Print a timestamp (in format seconds.nanoseconds)
  test="echo \$(date +%s.%N)" # Save a command to do the same
  sleep 1      # Sleep for a second
  eval "$test" # Evaluate the command saved in variable 'test'
  echo         # Print a new line before the next iteration
done

Yukarıdaki örnekten örnek çıktı (bir yinelemeye kesilmiş):

1398832186.133661344
1398832187.139076728

Her döngü için ikinci zaman damgasının, ilk döngüden yaklaşık bir saniye sonra olduğunu fark edeceksiniz. Çıkış yöntemini olmadan aynı testi Tersine, $içinde testtanım ve kaldırma eval, iki damgaları neredeyse eşleşir.

evalÇoğu durumda kullanma alışkanlığına girmeyin , ancak bu, bundan kaçınmanın iyi bir yolunu bilmediğim şeylerden biridir. Umarım bu yardımcı olur. İyi şanslar!


Çok teşekkürler, $(...)Hauke'nin önerdiği gibi kullanmayı denedim ama ters eğik çizgi anahtar.
Ricky

Memnun oldum - hatırlayın, ancak, burada anahtar gerçekten evalaynı şey yapabilirsiniz çünkü komutunuzu çevrelemek için çift ​​tırnak ( ) yerine $tek tırnak ( ') kaçarak ve kullanarak aynı şeyi yapabilirsiniz ".
daBeamer

Şimdi sadece Huake'in önerilerinde olduğu gibi, bunu lftp programında kullanmayı denediğimde yankı sadece komutu yazdırıyor, aslında çalıştırmayacak. Daha spesifik yardım için posta listelerini denemek gerekebilir.
Ricky

Hangi komutu yürütmeye çalışıyorsunuz? echoGecikmeli yürütme iç içe komutun çıkışı da dahil olmak üzere içeriği ile bir dize istediğiniz izlenim altında idi .
daBeamer

1
@Ricky @HaukeLaging tüm noktaları kabul etmek gerekir. As-as kodu echoişe yaramayacak, çünkü komut yok eval, daha çok bir dize var. Bizim için daha uygun bir örneğiniz varsa, yardım etmeye çalışabiliriz.
daBeamer

6

Birkaç alıntı seviyesi vardır. Çift tırnak ( "...") koruma boşluk ve birkaç özel karakter ( ~, &, |, ;, ...) ama parametre genişleme ve komut ikamesi engellemez.

"Tek" tırnak işaretleri ( ') veya "tehlikeli" karakterlerin önünde ters eğik çizgi kullanmanız gerekir .

Genel olarak: Geri $(tail ...)tıklamalar yerine kullanmayı düşünmelisiniz . Backticks eski standart ama biz $()çoğu insan için sorun yaratmayacak kadar eski bahsediyoruz . Yeni sürümün okunması daha kolaydır ve yuvalanabilir. Bırakın biçimlendirme sorunları burada sx ...


Hızlı cevap için teşekkürler Hauke. Maalesef backticks'i önerilen ile değiştirmek $(...)hala aynı sonucu veriyor - kabuk benim dizem tanımlandığında bunu yürütüyor.
Ricky

@Ricky Bu alternatif öneriler değildi. Kullanacaksınız $()ama yine de tek tırnaklara ihtiyacınız var.
Hauke ​​Laging

Peki bu karakterlerin hiçbir kombinasyonu peşimde olanı elde edemez mi?
Ricky

@Ricky "Tek tırnaklara ihtiyacınız var" hakkında anlaşılması zor olan nedir? Açıkçası denemiyorsunuz bile.
Hauke ​​Laging

Aslında yaptım, ama tek tırnak kullandığımda yankı sadece bu satırdaki her şeyi normal bir dize olarak basacak. Belki bir örnek vermede bu kadar zor olan ne?
Ricky
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.