masalah readarray (atau pipa)


19

Saya terjebak dengan perilaku readarrayperintah yang aneh .

Amerika man bashSerikat:

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

tetapi skrip ini tidak berfungsi (array kosong):

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

Dan ini bekerja:

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[@]}

Ada apa dengan pipa?

Jawaban:


15

Mungkin mencoba:

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

Saya berharap ini akan berhasil, tetapi saat Anda melangkah keluar dari konteks {shell terakhir ; }di akhir |pipa di sana Anda akan kehilangan nilai variabel Anda. Ini karena masing- |masing |proses terpisah dalam suatu |pipa dijalankan dalam sebuah (subkulit ). Jadi barang Anda tidak berfungsi karena alasan yang sama:

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

... tidak - nilai variabel diatur dalam proses shell yang berbeda dari yang Anda panggil.


23

Untuk memastikan readarrayperintah dieksekusi di shell saat ini, gunakan subtitusi proses sebagai pengganti pipa:

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

atau (jika bash4.2 atau lebih baru) menggunakan lastpipeopsi shell:

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

1
Keren. Ini bekerja, tetapi apa sebenarnya proses substitusi? Dan apa artinya memiliki < <2 panah?
CMCDragonkai

1
Lihat bashhalaman manual. Singkatnya, ini sintaksis untuk memperlakukan pipa sebagai deskriptor file. < <(...)artinya mengarahkan redirect (yang pertama <) dari output perintah di dalamnya <(...). Serupa, > >(...)akan melewati output standar ke input standar dari pipa di dalam >(...). Anda tidak perlu menggunakan pengalihan dengan substitusi proses. cat <( echo a b c )berfungsi juga.
chepner

Kedua opsi ini menghasilkan hasil yang tidak diinginkan bagi saya, di mana setiap item array mempertahankan akhir baris di akhir setiap string. Sedangkan jawaban oleh smac89 tidak memiliki masalah ini.
Lutut

3

readarray dapat juga membaca dari stdin, jadi:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.