vấn đề readarray (hoặc ống)


19

Tôi mắc kẹt với một hành vi kỳ lạ của readarraymệnh lệnh.

Các man bashtiểu bang:

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

nhưng các tập lệnh này không hoạt động (mảng trống):

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

Và những công việc này:

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

Có gì sai với đường ống?

Câu trả lời:


15

Có thể thử:

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

Tôi hy vọng nó sẽ hoạt động, nhưng thời điểm bạn bước ra khỏi bối cảnh {vỏ cuối cùng đó ; }ở cuối |đường ống, bạn sẽ mất giá trị biến của mình. Điều này là do mỗi quy trình |riêng biệt |trong một |đường ống được thực thi trong một (lớp con ). Vì vậy, điều của bạn không hoạt động vì cùng một lý do:

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

... không - giá trị biến được đặt trong một quy trình shell khác với giá trị mà bạn gọi trên đó.


23

Để đảm bảo readarraylệnh thực thi trong trình bao hiện tại, hãy sử dụng thay thế quy trình thay cho đường ống:

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

hoặc (nếu bash4.2 trở lên) sử dụng lastpipetùy chọn shell:

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

1
Mát mẻ. Điều này hoạt động, nhưng chính xác những gì là quá trình thay thế? Và có < <2 mũi tên nghĩa là gì?
CMCDragonkai

1
Xem bashtrang người đàn ông. Nói tóm lại, đó là cú pháp để xử lý một đường ống như một mô tả tệp. < <(...)có nghĩa là chuyển hướng đầu vào (đầu tiên <) từ đầu ra của lệnh bên trong <(...). Similary, > >(...)sẽ chuyển đầu ra tiêu chuẩn đến đầu vào tiêu chuẩn của đường ống bên trong >(...). Bạn không nhất thiết phải sử dụng chuyển hướng với thay thế quá trình. cat <( echo a b c )làm việc tốt
chepner

Cả hai tùy chọn này đều tạo ra một kết quả không mong muốn đối với tôi, trong đó mỗi mục mảng giữ lại các kết thúc dòng ở cuối mỗi chuỗi. Trong khi đó, câu trả lời của smac89 không có vấn đề này.
thnee

3

readarray cũng có thể đọc từ stdin, vì vậy:

readarray arr <<< "$(echo a; echo b; echo c)"; echo ${#arr[@]}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.