ปัญหา readarray (หรือ pipe)


19

ฉันติดอยู่กับพฤติกรรมแปลก ๆ ของการreadarrayออกคำสั่ง

man bashฯ :

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

แต่สคริปต์เหล่านี้ไม่ทำงาน (อาร์เรย์ว่างเปล่า):

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

และงานเหล่านี้:

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

มีอะไรผิดปกติกับท่อ?

คำตอบ:


15

อาจลอง:

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

ฉันคาดหวังว่ามันจะใช้งานได้ แต่เมื่อคุณก้าวออกจากบริบท{เชลล์สุดท้าย; }ในตอนท้ายของ|ไพพ์ไลน์ที่นั่นคุณจะสูญเสียค่าตัวแปรของคุณ นี้เป็นเพราะแต่ละ|แยกต่างหาก|กระบวนการภายใน|ท่อจะถูกดำเนินการในsubshell( )ดังนั้นสิ่งที่คุณไม่ทำงานด้วยเหตุผลเดียวกัน:

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

... ไม่ - ค่าตัวแปรถูกตั้งค่าในกระบวนการเชลล์ที่แตกต่างจากที่คุณเรียกใช้


23

เพื่อให้แน่ใจว่าreadarrayคำสั่งดำเนินการในเชลล์ปัจจุบันให้ใช้การทดแทนกระบวนการแทนไพพ์ไลน์:

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

หรือ (ถ้าbash4.2 หรือใหม่กว่า) ใช้lastpipeตัวเลือกเชลล์:

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

1
เย็น. ใช้งานได้ แต่การทดแทนกระบวนการคืออะไร และมี< <ลูกศร 2 อันหมายความว่าอะไร
CMCDragonkai

1
ดูbashหน้าคน ในระยะสั้นมันเป็นไวยากรณ์สำหรับการปฏิบัติไปป์ไลน์เป็นตัวให้คำอธิบายไฟล์ < <(...)วิธีการป้อนข้อมูลการเปลี่ยนเส้นทาง (ครั้งแรก<) <(...)จากการส่งออกของภายในคำสั่ง Similary, จะผ่านออกมาตรฐานเพื่อเข้ามาตรฐานภายในท่อ> >(...) >(...)คุณไม่จำเป็นต้องใช้การเปลี่ยนเส้นทางด้วยการทดแทนกระบวนการ cat <( echo a b c )ทำงานได้เช่นกัน
chepner

ตัวเลือกทั้งสองนี้สร้างผลลัพธ์ที่ไม่พึงประสงค์สำหรับฉันโดยที่แต่ละรายการของอาเรย์ยังคงรักษาจุดสิ้นสุดของบรรทัดไว้ที่ส่วนท้ายของแต่ละสตริง ในขณะที่คำตอบโดย smac89 ไม่มีปัญหานี้
thnee

3

readarray ยังสามารถอ่านจาก stdin ดังนั้น:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.