readarray (vagy pipe) kérdés

A readarray parancs furcsa viselkedése miatt ragaszkodtam.

A man bash állapot:

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

de ezek a szkriptek nem működnek (a tömb üres):

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

És ezek működnek:

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

Mi a baj a csővel?

Válasz

Talán próbáld ki:

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

Arra számítok, hogy működni fog , de abban a pillanatban, amikor kilép az utolsó { shell ; } kontextusból a | pipeline ott elveszíti a változó értékét. Ennek az az oka, hogy a | különálló | folyamatokat egy | csővezetéken belül futtatják a ( alhéj ). Tehát a dolgod nem ugyanazon oknál fogva működik:

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

… nem “t – a változó értékét egy másik shell folyamat, mint amelyikben hívod.

Válasz

A parancs az aktuális héjban hajt végre, vagy a folyamat helyettesítését használja a folyamat helyett:

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

vagy (ha bash 4.2 vagy újabb) használja a lastpipe shell opciót:

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

Megjegyzések

  • Hűvös. Ez működik, de mi is pontosan a folyamat helyettesítése? És mit jelent az, hogy < < 2 nyil van?
  • Lásd a bash man oldalt. Röviden: ' a szintaxisa, amely egy folyamatot fájlleíróként kezel. A < <(...) azt jelenti, hogy a bemenetet (az első <) átirányítja a parancs kimenetéből a <(...). Hasonló módon a > >(...) szabványos kimenetet továbbít a csővezeték szabványos bemenetére a >(...) belül. Nem szükséges, hogy ' szükségszerűen használjon átirányítást a folyamat helyettesítésével. A cat <( echo a b c ) is működik.
  • Mindkét lehetőség nemkívánatos eredményt ad számomra, ahol minden tömb elem megtartja az egyes karakterláncok végén lévő sorvégeket. Míg a smac89 válasza nem okozza ezt a problémát.
  • A sorvégeket a readarray -t arr segítségével lehet lecsupaszítani. man bash -ből: -t Remove a trailing newline from each line read.
  • I ' m a bash 5.0.17, és ez nem működik ' nálam. Én ' még ellenőriztem a következőt: BASHOPTS és lastpipe -t tartalmaz, mégis üres arr -t ad, de a readarray -t arr < <(cat myfile.txt) megfelelően működik.

Válasz

readarray a stdin-ből is olvasható, így:

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

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük