Üst kabuktan bir değişkenin üst kabukta kullanılabilir hale getirilmesi


11

Bir web hizmetinden bazı raporları zamanlamak için hızlı ve kirli bir komut dosyası yazdım:

BASE_URL='http://example.com/json/webservice/'
FIRST=1
FINAL=10000

for report_code in $(seq 1 $FINAL); do
  (time -p response=$(curl --write-out %{http_code} --silent -O ${BASE_URL}/${report_code}) ) 2> ${report_code}.time

  echo $response  # <------- this is out of scope!  How do I fix that?
  if [[ $response = '404' ]]; then
    echo "Deleting report # ${report_code}!"
    rm ${report_code}
  else
    echo "${report_code} seems to be good!"
  fi
done

Ben timeçıkışını yönlendirebilirsiniz, ancak bir alt kabukta komut sarmak gerekir , ancak bu $responseüst kabuk için kullanılamaz değerini yapar . Bu sorunu nasıl çözerim?

Yanıtlar:


11

Bir hataya yatkın marshalling ve hantal iletişim olmadan bir değişkenin alt kabuktan ebeveynine değerini getiremezsiniz.

Neyse ki, burada bir alt kabuğa ihtiyacınız yok. Yeniden yönlendirme , alt kabuk yerine yalnızca ile komut gruplandırmayı gerektirir { … }.

{ time -p response=$(curl --write-out '%{http_code}' --silent -O "${BASE_URL}/${report_code}"); } 2> "${report_code}.time"

( Değişken ikameler etrafında çift tırnak unutmayın .)


her programlama dilinin bunu yapabilmesi komik. zaten kabuk olası bir çözüm ile 1 saat googling geçirdi. im disapointed.
Kra

1
Hiçbir programlama dili bunu yapamaz. (Neredeyse) herhangi bir programlama dili, bir değişkenin değerini bir alt programdan veya komut bloğundan üst öğesine getirebilir ve cevabımda tam olarak açıkladığım şey: { … }bir alt kabuk yerine komut gruplamasını kullanın ( … ).
Gilles 'SO- kötü olmayı bırak'

4

Diğer U&L kullanıcıları: C-stilini main()işlevle kullanma konusundaki cevabımı küçümsemeden önce lütfen şu bağlantıyı ziyaret edin: https://unix.stackexchange.com/a/313561/85039 Komut dosyalarında ana işlevleri kullanmak, birçok profesyonel tarafından kullanılan yaygın bir uygulamadır alan içerisinde.


Gilles'in işaret ettiği gibi, alt kabuklar değişkenleri ortamlarının dışına çıkaramaz. Ancak bu soruna başka bir açıdan yaklaşalım - senaryonuzu fonksiyonlara yazarsanız, değişken olarak ilan edilebilir localve bu düzenlenebilir.

Bash 4.3 el kitabından localaçıklama:

Bir işlev içinde yerel kullanıldığında, değişken adının o işleve ve alt işlevleriyle sınırlı görünür bir kapsama sahip olmasına neden olur ...

Misal:

#!/bin/bash

outter()
{
    for i in $(seq 1 3)
    do
        var=$i
    done
}

main()
{
    local var=0
    outter
    echo $var
}
main "$@"
$ ./testscript.sh                                                                                                        
3

Döngü işlevinin 3 yinelemesinden sonra görebileceğiniz gibi, değişken değiştirilir.


Hmm, C programcıları için sezgisel olmayan davranış. Normalde outterbir global örneğine başvurmayı beklerdim var.
Ruslan

Bu cevabın bazı kusurları var. "$var"çağrıda gerekli değildir outter. Hiçbir şey yapmaz. Ve ayrıca local var=0hiçbir şey yapmaz; belirttiğiniz gibi ouf çağrısı outterüzerine yazılır var.
Golar Ramblar

@ GolarRamblar Ben "$var"konumsal argüman olarak kaldırdım outter; Adil olmak gerekirse, bu bir alışkanlık dışında. Ayrılmak için ayrıntıya girebilir misiniz local var=0 ?
Sergiy Kolodyazhnyy
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.