readarray (tai pipe) -asia

Pysyin oudossa käyttäytymisessä readarray -komennossa.

man bash -tila:

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

mutta nämä komentosarjat eivät toimi (taulukko on tyhjä):

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

Ja nämä toimivat:

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

Mitä vikaa putkella on?

vastaus

Ehkä yritä:

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

Odotan, että se toimii , mutta tällä hetkellä kun astut ulos viimeisestä { -kuoren ; } kontekstista | pipeline siellä menetät muuttujasi arvon. Tämä johtuu siitä, että kukin | erillisestä | prosessista | -putkessa suoritetaan a ( alikuori ). Joten sinun juttusi ei toimi samasta syystä:

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

… ei ”t – muuttujan arvo asetettiin eri shell-prosessi kuin se, johon sitä kutsutaan.

Vastaa

Varmistaaksesi, että readarray -komento suoritetaan nykyisessä kuoressa joko käyttämällä prosessikorvausta putkilinjan sijasta:

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

tai (jos bash 4.2 tai uudempi) käytä lastpipe -vaihtoehtoa:

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

kommentit

  • Siistiä. Tämä toimii, mutta mikä on prosessin korvaaminen? Ja mitä tarkoittaa < < 2 nuolta?
  • Katso bash -sivua. Lyhyesti sanottuna se ' n syntaksia putkilinjan käsittelemiseksi tiedostokuvaajana. < <(...) tarkoittaa tulon uudelleenohjaamista (ensimmäinen <) komennon lähdöstä <(...). Samoin > >(...) välittäisi vakiolähdön putkiston vakiotuloon >(...) sisällä. Sinun ' ei välttämättä tarvitse käyttää uudelleenohjausta prosessin korvaamisen kanssa. cat <( echo a b c ) toimii myös.
  • Molemmat näistä vaihtoehdoista tuottavat minulle ei-toivotun tuloksen, jossa kukin matriisikohta säilyttää rivinpäätteet kunkin merkkijonon lopussa. Smac89: n vastauksella ei ole tätä ongelmaa.
  • Rivinpäätteet voidaan poistaa käyttämällä readarray -t arr. Alkaen man bash: -t Remove a trailing newline from each line read.
  • I ' m käyttämällä bash 5.0.17 ja tämä ei toimi '. Olen ' jopa tarkistanut BASHOPTS ja se sisältää lastpipe, mutta cat myfile.txt | readarray -t arr antaa tyhjän arr, mutta readarray -t arr < <(cat myfile.txt) toimii oikein.

Vastaus

readarray voi lukea myös stdinistä, joten:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]} 

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *