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.