Ve işareti “değişkenleştirin” (arka planı bir işlem)


9

Ve işareti değişkene koymanın bir yolu olup olmadığını bilmek ve hala arka plana bir işlem göndermek için kullanmak istiyorum.

Bu çalışıyor:

BCKGRND=yes
if [ "$BCKGRND" = "yes" ]; then
    sleep 5 &
else
    sleep 5
fi

Ama bu beş çizgiyi sadece biriyle başarmak hoş olmaz mıydı? Şöyle ki:

BCKGRND='&'
sleep 5 ${BCKGRND}

Ama bu işe yaramıyor. BCKGRND ayarlanmamışsa çalışır - ancak ayarlandığında bunu bir '&' harfi ile yorumlanır ve hatalar çıkarır.


izleme ve işareti kullandıktan sonra echo $!PID döndürür
noobninja

Yanıtlar:


9

Çağrıyı arka plan yapmak için bir değişken kullanmak mümkün değildir, çünkü komut satırı kontrol işleçleri ( &&ve gibi &) için ayrıştırıldıktan sonra değişken genişletme gerçekleşir .

Yine başka bir seçenek de çağrıları bir fonksiyona sarmak olabilir:

mayberunbg() {
  if [ "$BCKGRND" = "yes" ]; then
    "$@" &
  else
    "$@"
  fi
}

... ve değişkeni gerektiği gibi ayarlayın:

$ BCKGRND=yes mayberunbg sleep 3
[1] 14137
$
[1]+  Done                    "$@"
# or
$ BCKGRND=yes
$ mayberunbg sleep 3
[1] 14203
$
[1]+  Done                    "$@"
$ BCKGRND=no mayberunbg sleep 3
# 3 seconds later
$

Ne, hayır ed? Yine de +1, bu en temiz çözüm.
Stephen Kitt

LOLStephenKitt; şimdi dişliler dönüyor
Jeff Schaller

Basitliği nedeniyle eval cevabını beğendim ama arka plan yapmak istediğim gerçek gerçek dünya komutum, eval kullanarak rahat olmak için çok fazla değişkenle çok karmaşıktı. @ jeff-schaller gittiğim yöne işaret eden cevabı verdi. Bir fonksiyon yerine, tüm komutu bir değişkene koydum ve sonra komutunu & ile veya olmadan yürütmek için if if stilini kullandım.
BrowncoatOkie

11

Bir şeyleri çevirebilir ve "ön plana alma" özelliğini değiştirebilirsiniz:

FOREGROUND=fg
sleep 5 & ${FOREGROUND}

İşlemi arka planda çalıştırmak FOREGROUNDiçin trueveya olarak ayarlayın . (Ayar FOREGROUNDiçin truearka planda çalışmasına kuşkusuz kafa karıştırıcı! Uygun değişken isimleri okuyucuya alıştırma olarak kalır.)


4
bu güzel ama iş kontrolü olmayan bir kabukta çalışmaz ( set -mkullanılmadığı sürece herhangi bir komut dosyası ).
mosvy

9

Muhtemelen şunları kullanmanız gerekir eval:

eval "sleep 5" "$BCKGRND"

evalkabuğun verilen argümanları yeniden değerlendirmesine neden olur. &Dolayısıyla bir değişmez değer &, komutu arka plana koyarak, komutun bir argümanı olarak değil, bir komutun sonunda olarak yorumlanır .


2
İçeren bir cevap eval, dikkatle ele alınması gerektiği konusunda bir uyarı içermelidir. Örneğin bu cevaba bakınız .
Ralf

"$BCKGRND"Boş bir tartışmayı değerlendirirken sorunun ne olduğunu anlamıyorum .
mosvy

2
@Ralf bu durumda kesinlikle alakasız . Eval hakkında özel bir şey yoktur - örneğin, aritmetik genişletmeler yoluyla komutları yürütebilirsiniz. Belki de bash (veya herhangi bir kabuk) kullanmaya karşı böyle bir uyarı olmalı ;-)
mosvy

1
@Kusalananda evalasıl değerlendirmeden önce argümanlarını boşluklarla birleştirecek. Sadece deneyin: eval printf "'{%s}\n'" foo "" "" "". ne olursa olsun eval foo "" "" "" "", tamamen benzerdir . eval fooIFS
mosvy

1
Değerlendirilen komut herhangi bir özel karakter içeriyorsa çift tırnak içinde olmalıdır, örn eval 'sleep $TIMEOUT' "$BACKGROUND". Aksi takdirde, değişken başka bir değişkene genişlerse veya özel karakterler içeriyorsa çift genişletme alabilirsiniz. Ayrıca, iç içe geçmiş alıntı yapmak zor olabilir.
Barmar
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.