readarray (veya pipe) sorunu


19

Garip bir readarraykomuta davranışı ile sıkıştım .

man bashdevletler:

readarray
     Read lines from the standard input into the indexed array variable array

ancak bu komut dosyaları çalışmıyor (dizi boş):

unset arr; (echo a; echo b; echo c) | readarray arr; echo ${#arr[@]}
unset arr; cat /etc/passwd | readarray arr;  echo ${#arr[@]}

Ve bunlar işe yarıyor:

unset arr; readarray arr < /etc/passwd ;  echo ${#arr[@]}
unset arr; mkfifo /tmp/fifo; (echo a; echo b; echo c) > /tmp/fifo & mapfile arr < /tmp/fifo ; echo ${#arr[@]}

Boru ile ilgili sorun ne?

Yanıtlar:


15

Belki deneyin:

unset arr
printf %s\\n a b c | {
    readarray arr
    echo ${#arr[@]}
}

Çalışmasını bekliyorum, ancak boru hattının sonundaki son {kabuk ; }bağlamından çıktığınızda |, değişken değerinizi kaybedeceksiniz. Bunun nedeni, bir boru hattı içindeki |ayrı |işlemlerin her birinin |bir (alt kabukta yürütmesidir ). Yani işiniz aynı nedenden dolayı çalışmıyor:

( arr=( a b c ) ) ; echo ${arr[@]}

... değil - değişken değeri, üzerinde çağırdığınız değerden farklı bir kabuk işleminde ayarlandı .


23

readarrayKomutun geçerli kabukta çalıştığından emin olmak için , ya boru hattı yerine işlem ikamesi kullanın:

readarray arr < <( echo a; echo b; echo c )

veya ( bash4.2 veya üzeri ise) lastpipekabuk seçeneğini kullanın:

shopt -s lastpipe
( echo a; echo b; echo c ) | readarray arr

1
Güzel. Bu işe yarar, ama süreç ikamesi tam olarak nedir? Peki < <2 ok olması ne anlama geliyor ?
CMCDragonkai

1
bashKılavuz sayfasına bakınız . Kısacası, bir boru hattını dosya tanımlayıcı olarak ele almak için sözdizimidir. < <(...)girişi (ilk <) içindeki komutun çıkışından yönlendirmek anlamına gelir <(...). Benzer şekilde, > >(...)standart çıkışı içerideki boru hattının standart girişine geçirir >(...). Proses ikamesi ile yeniden yönlendirme kullanmanız gerekmez. cat <( echo a b c )çalışır.
chepner

Bu seçeneklerin her ikisi de benim için istenmeyen bir sonuç verir, burada her dizi öğesi her dizenin sonunda satır sonlarını tutar. Oysa smac89'un cevabı bu soruna sahip değil.
thnee

3

readarray stdin'den de okuyabilir, bu yüzden:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
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.