You need to join this project to post message / question. See Help for details.
What is pipe in Linux ?
vẫn còn nhu cầu tuyển người đi uống cafe.
»
Votes:
1/1
Tôi viết một đoạn script thế này
1 #!/bin/bash
2
3 max=-1
4
5 ls -lo | awk '{print $4}' |
6 while read size
7 do
8 if [ "$size" -gt "$max" ]
9 then
10 max=$size
11 fi
12 done
13
14 echo "max size of file in current directory $max"
Mục đích rất rõ ràng, tôi muốn in ra dung lượng của file lớn nhất trong thư mục hiện hành. Kết quả đoạn script trên cho $max bằng -1. Đây không phải là kết quả tôi mong đợi.
Lỗi lầm đã mắc ở đâu? (hướng dẫn: xem định nghĩa pipe)
Đưa ra giải pháp của bạn (chỉ cần 1 giải pháp)
Trả lời đúng 2 câu trên, tôi mời bạn cuối tuần một chầu cafe. Còn chờ gì nữa!
Comments
Bài này hay quá. Mình không đạt giải cà phê được rồi :)
1. Cái này trả lời bên FB rồi giờ vào trả lời lại :) Với định nghĩa của pipelines trong ngữ cảnh Shell Command Language trong Posix standard thì đoạn code chẳng có cái gì sai cả :)), (bash cũng định nghĩa pipeline giống vậy!) và đoạn code trên chạy ngon lành với zsh, ksh, ... nhưng không chạy với bash, lý do là bash chạy từng command của pileline trong một subshell riêng biệt và từ root env thì không thể truy cập vào cái biến của subshell.
2. Giải pháp thì đơn giản là đem cái echo vào trong subshell. Chỉ cần nhóm while và echo vào chung một compound command bằng cách sử dụng { }:
Giải pháp 2: Đem while ra ngoài root env, gắn stdin của while với stdout của pipe thông qua redirection:
Giải pháp 3: dùng zsh, ksh :))
Bác CT lại ... mất một chầu cà phê rất là đắt nữa đây hehe :)
Một vé đi cafe dành cho tuanndh, hy vọng sáng thứ 7 hoặc sáng chủ nhật tuanndh sắp xếp được thời gian. tuanndh cứ liên lạc ở đây ( có thể liên lạc cá nhân, xem Cách che nội dung bài viết).
Trường hợp dùng zsh, ksh shell làm tôi bất ngờ, vì nằm ngoài đáp án mà tôi biết. Nói về bash script thì có thể giải thích thế này:
Mỗi lần dùng 1 pipe, một process con được tạo ra để nhận output của statement bên trái pipe, đem về làm input cho mình (statement bên phải pipe). Cụ thể ở đây, sẽ có 2 processes. Để tiện theo dõi, ta chèn trong vòng lặp while ở statement 3
sleep 2. Giả sử script của ta tên whatpipe.sh, chạy nó ở 1 tab, mở 1 tab khác chạyps -af. Ta thấy có 2 processes tên whatpipe.sh và 1 process tên sleep. Xem process ID và parent process ID, thấy rõ chúng có quan hệ "ông-cha-con".Quay lại script bị lỗi, ta có
maxtrong process ông, vàmaxtrong process cháu. Khi inmaxlà in cái của process ông, rõ ràng nó vẫn là -1.Contents protectedCái pipe bạn nói là hiểu theo lập trình C về hệ thống Unix. Còn trong ngữ cảnh của Shell Command Language thì không phải thế. Posix, Bash đều định nghĩa các thành phần của pipe là một command (max = $size cũng là một command và phải chạy đúng), không có quy định nào về implemention nó thành một subshell cả. Đây là một trường hợp bash không đạt chuẩn Posix! Tuy nhiên theo mình thì việc bash implement thành các subshell cũng chấp nhận được vì khi làm việc với pipe thường dựa trên nguyên tắc blackbox, mà dùng subshell thì còn không bị side-effect đúng style đang hot nữa chứ ;-)
Cafe thì để khi khác :-)
Khi làm việc với Linux thì đập ngay vào mặt là
Bash. Giờ mình mới thấy tiếc :))Cám ơn vanchutr đã cung cấp thêm 1 giải pháp. Mình dời comment của vanchutr ngoài mục Tin tức vào đây: