Soru Linux bash: Çoklu değişken ataması


Linux'ta aşağıdaki kodla benzer bir linux bash var:

list($var1, $var2, $var3) = function_that_returns_a_three_element_array() ;

Yani, bir cümleye 3 farklı değişkene karşılık gelen bir değer atarsınız.

Diyelim ki bash fonksiyonum var myBashFuntion "qwert asdfg zxcvb" dizesini yazmak için yazıyor. Gibi bir şey yapmak mümkün mü:

(var1 var2 var3) = ( `myBashFuntion param1 param2` )

Eşit işaretin solundaki kısım, geçerli bir sözdizimi değildir. Sadece ne istediğimi açıklamaya çalışıyorum.

Bununla birlikte, iş ne işe yarar?

array = ( `myBashFuntion param1 param2` )
echo ${array[0]} ${array[1]} ${array[2]}

Ancak dizinlenmiş bir dizi düz değişken isimleri gibi açıklayıcı değildir.
Ancak, sadece yapabilirim:

var1 = ${array[0]} ; var2 = ${array[1]} ; var3 = ${array[2]}

Ama bunlar kaçınmayı tercih ettiğim 3 ifadedir.

Sadece bir kısayol sözdizimi arıyorum. Mümkün mü?


86
2017-12-23 12:03


Menşei




Cevaplar:


Aklıma gelen ilk şey:

read -r a b c <<<$(echo 1 2 3) ; echo "$a|$b|$c"

çıktı, şaşırtıcı değil

1|2|3

165
2017-12-23 12:16



İlk değişken bir boşluk içeriyorsa bunu işe almak için zaten var mı? - Rucent88
@Michael Kullanma read -d "\n" v1 v2 <<<$(cmd) Mükemmel çalışıyor. Teşekkür ederim! - Rucent88
Alternatif olarak, read a b c < <(echo 1 2 3) - idfah
@LeeNetherton, iyi bir nokta, ben bir eko komutunun dönüş durumuna ihtiyacı olup olmadığından emin değilim :-) Ben bu sözdizimini destekleyen cevap bash yazma zamanında düşünüyorum (varsayılan olarak yüklü olarak), daha az yaygın olsa da, ben % 100 emin değilim. - Michael Krelin - hacker
@ MichaelKrelin-hacker emin, dönüş durumu echo anlamsız, ancak bu tekniği, geri dönüş durumuyla ilgilendiğim bir komut dosyasından birden çok değer döndürmek için kullanıyordum. Bulgularımı paylaşacağımı düşündüm. - Lee Netherton


Değerleri bir diziye atamak istedim. Yani, uzatma Michael Krelin'ın yaklaşımı, Yaptım:

read a[{1..3}] <<< $(echo 2 4 6); echo "${a[1]}|${a[2]}|${a[3]}"

hangi verir:

2|4|6 

beklenildiği gibi.


14
2018-02-07 10:19



Değerleri bir diziye yerleştirmek için şu soruya değindiğim basit bir çözüm zaten var: a=( $(echo 2 4 6) ) ; echo ${a[0]} ${a[1]} ${a[2]} - GetFree
Evet, bunu gözden kaçırmıştım. Yine de, önerim daha büyük diziler atamak için daha uygun olduğunu iddia ediyorum. - soundray
@soundray Çözümünüz genişleme ve bir çalıntı kullanır, ne olduğu benimdir, bu senaryoda iyi performans göstereceğinden şüphe duyuyorum (ama kontrol etmedim). - Camilo Martin
Güvenlik için şunları kullanmalısınız: read -r: do not allow backslashes to escape any characters - Tom Hale


Sanırım bu yardımcı olabilir ...

Komut dosyalarında kullanıcı giriş tarihlerini (mm / gg / yyyy) ayırmak için gün, ay ve yılı bir diziye kaydediyorum ve sonra değerleri aşağıdaki gibi ayrı değişkenlere koyarım:

DATE_ARRAY=(`echo $2 | sed -e 's/\// /g'`)
MONTH=(`echo ${DATE_ARRAY[0]}`)
DAY=(`echo ${DATE_ARRAY[1]}`)
YEAR=(`echo ${DATE_ARRAY[2]}`)

4
2017-12-29 23:55





Bazen korkak bir şey yapmalısın. Diyelim ki bir komuttan (örneğin SDGuero tarafından tarih örneği) okumak istediğinizi, ancak birden fazla çataldan kaçınmak istediğinizi varsayalım.

read month day year << DATE_COMMAND
 $(date "+%m %d %Y")
DATE_COMMAND
echo $month $day $year

Ayrıca, read komutunu da okuyabilirsiniz, ancak değişkenleri bir subshell içinde kullanmanız gerekir:

day=n/a; month=n/a; year=n/a
date "+%d %m %Y" | { read day month year ; echo $day $month $year; }
echo $day $month $year

sonuç ...

13 08 2013
n/a n/a n/a

3
2017-08-13 20:39



read komutlar nedeniyle bir alt kabukta gerçekleşmez, çünkü borunun sağ tarafındaki okuma komutuna sahip olursunuz. Koşmalısın read yapabileceğiniz mevcut kabukta komut read day month year <<< `date "+%d %m %Y"` - pneumatics
Hayır - read  olur Ancak, boru hattının alt kabuğu sona erdiğinde, okuduğu değişkenlerin kapsamı kapsam dışıdır. - Otheus
Yorumum sebebi hakkındaydı niye ya okuma bir alt kabuğun içinde gerçekleşir ve şimdi yazdığın şeyi yanlış anladığımı anladım. Subshell'in yaratıldığını kastettiğini sanmıştım çünkü bileşik kaşifin etrafında kaşlı ayraçları kullandın. Fakat! Bu örneği vermenizin sebebi, forkinglemekten kaçınmaktı, ama subshell fork da değil mi? - pneumatics
İlk örnek tam olarak bir çatal gerektirir: böylece bash tarih komutunu başlatabilir. İkinci örnekte, tarih ile alt-kabuk arasında bir boru hattı kurdunuz. Sanırım bugünlerde buhşet, gerçekten de alt kabuğun içine girmemek için yeterince zeki, ama bundan emin değilim. Herhangi bir oranda, o görünüyor gibi olurdu :) - Otheus


Bölüm 5 Bash Yemek Tarifleri O'Reilly tarafından, değişken bir ödevdeki gerekliliğin gerekçelerini (bazı uzunluklarda) '=' işareti etrafında boşluk olmadığını tartışır.

MYVAR="something"

Açıklama, bir komutun adı ile bir değişken arasında ayrım yapmakla ilgili bir şey vardır ('=' geçerli bir argüman olabilir).

Bu, olaydan sonra haklı çıkmaya benzer gibi görünüyor, ancak her durumda, değişkenler listesine atanma yönteminden bahsedilmiyor.


0
2017-12-23 12:25



Evet biliyorum. Okunabilirlik uğruna ekstra boşluklar ekledim. - GetFree
Evet, bu doğru: Readbiity, bash betiklerinde gerçekten acı çekiyor. - pavium