a. Các vào/ra chuẩn của UNIX
UNIX cũng như nhiều hệ điều hành khác có 3 kênh vào/ra chuẩn ở terminal (/dev/tty) đó là nhập chuẩn từ bàn phím, còn xuất chuẩn và lỗi chuẩn thì đưa ra màn hình. Những kênh này là nơi các luồng dữ liệu của một chương trình đang thi hành (ví dụ: shell) sẽ tự động vào/ra khi được coi như mặc định.
Kênh Số Tên Thiết bị
Nhập chuẩn 0 stdin Bàn phím /dev/tty
Xuất chuẩn 1 stdout Màn hình /dev/tty
b. Các luồng dữ liệu của shell
1- Xu t chu n ấ ẩ
Lệnh date đưa luồng dữ liệu ra màn hình về ngày giờ hiện nay: $ date
2- Nh p chu n ậ ẩ
Lệnh tee nhập luồng dữ liệu từ bàn phím và đồng thời đưa ra màn hình: % tee
Luồng dữ liệu vào từ bàn phím sẽ kết thúc bằng cách gõ ký tự: ^D
Trong ví dụ sau các tệp sẽ có cùng nội dung từ một luồng dữ liệu gõ vào: % tee tệp1 tệp2 tệp3 tệpn
3- B l c d li uộ ọ ữ ệ
Một lệnh vừa vào lại vừa ra dữ liệu được gọi là bộ lọc (filter), dù nói chung dữ liệu vào/ra thường khác nhau chứ không giống nhau như trong lệnh tee.
Lệnh cat sẽ hiển thị tệp ra màn hình và cũng là một bộ lọc: % cat tệp
4- L i chu nỗ ẩ
Shell khi cần thiết sẽ phải thông báo lỗi và hiển thị nó lên màn hình, như trong ví dụ sau nếu tệp kiki không tồn tại:
% cat kiki
kiki: No such file or directory Chú ý:
Tệp nhập chuẩn được ký hiệu là dấu gạch nối "-", ví dụ: % cat –
Sau lệnh này ta gõ vào các dữ liệu từ bàn phím và kết thúc cũng bằng ký tự điều khiển: ^D
c. Chỉnh hướng các luồng dữ liệu
Nếu không muốn dùng những tệp vào/ra chuẩn, ta có thể theo ý mình chỉnh hướng các luồng dữ liệu vào/ra với những tệp khác.
1- Ch nh hỉ ướng ra t p m iệ ớ
Ta sử dụng siêu ký tự ">" để tạo ra một tệp mới, ví dụ lệnh sau sẽ ghi danh sách các tệp trong thư mục hiện hành vào tệp1:
% ls > tệp1
Nếu tệp1 đã có sẵn thì nó sẽ bị mất nội dung cũ. Chỉnh hướng như vậy dễ có rủi ro nên C shell cho phép lập một biến để bảo vệ như sau:
% set noclobber
Ví dụ sau tạo ra một tệp mới, có cùng nội dung như prog.c : % cat prog.c > tệp_2
ngoài quyền truy cập được thừa kế khác nhau trên tệp mới, lệnh sau cũng tương đương như trên:
% cp prog.c tệp_2
Lệnh sau sao đơn thể khả thi a.out vào một tệp đĩa result: % a.out > result
2- Ch nh hỉ ướng ra t p cệ ũ
Ta dùng " >>" để ghi ra một tệp mới hoặc nếu nó đã có sẵn thì ghi tiếp vào cuối tệp cũ, ví dụ:
% cat tệp_2 >> tệp_1
Dưới UNIX ta có thể chỉnh hướng ra bất kỳ một thiết bị ngoại vi nào vì nó cũng là một tệp, dù đặc biệt, ví dụ ra máy in:
% ls > /dev/lp
Dưới UNIX ta có thể chỉnh hướng ra /dev/null để huỷ dữ liệu như ném chúng vào một cái giếng vô đáy:
% wc tệp > /dev/null
Ví dụ muốn khỏi nhìn thấy các dòng chữ do lệnh tee gửi ra màn hình: % tee tệp1 tệp2 tệp3 > /dev/null
3- Ch nh hỉ ướng vào t t pừ ệ
Ta gõ "< " để nhập dữ liệu từ tệp thay vì từ bàn phím, ví dụ: % tee < tệp1
Ba ví dụ sau tương đương và đều che các dòng chữ gửi ra màn hình: % tee < tệp1 > tệp2
% tee > tệp2 < tệp1 % cat tệp1 > tệp2 Hai ví dụ sau cũng tương đương:
% cat tệp % cat < tệp
4- Ch nh hỉ ướng vào v i k t thúc t pớ ế ệ
Ta gõ "<< " và một từ bất kỳ từ bàn phím, ví dụ: % cat << END
Hai ví dụ sau tương đương:
% cat < /dev/tty > tệp2 % cat > tệp2
5- Ch nh hỉ ướng thông báo l iỗ
+Trong Bourne shell:
Ta gõ " 2> " để tạo ra một tệp mới hoặc ghi thông báo lỗi lên một tệp cũ cùng tên (2 là kênh lỗi chuẩn): % rm tệp 2> tệp_error
Ta gõ " 2>> " để tạo ra một tệp mới hoặc ghi thông báo lỗi vào cuối một tệp cũ cùng tên: % cat tệp_ strange 2>> tệp_old
Ghi chú:
+Trong C shell:
Trong C shell không có ký hiệu riêng để chỉnh hướng báo lỗi, chỉ có >& và >>& để chỉnh hướng nó cùng với luồng dữ liệu thông thường, ví dụ:
% rm tệp_strange >& tệp_error
Nếu muốn tách thông báo lỗi ra khỏi luồng dữ liệu thông thường ta phải dùng các dấu ngoặc đơn, ví dụ:
% (cat tệp_strange > tệp_data) >& tệp_error
Trong trường hợp sau, nếu "tệp1" tồn tại thì "tệp_data" sẽ nhận nội dung của nó, nếu "tệp1" không tồn tại thì "tệp_data" sẽ nhận thông báo lỗi về lý do đó:
% (cat tệp >> tệp_ data) >>& tệp_error
d. Các ống nối
Các ống nối (pipe) là một kỹ thuật shell dùng để nối các luồng dữ liệu của một số tiến trình (tức một số chương trình đang tiến hành).
Giả sử luồng dữ liệu ra của lệnh ls lớn hơn một trang màn hình và ta muốn quản lý chúng (hiển thị từng đoạn) bằng more hay pg. Trực quan thì phải dùng tệp_annex để làm việc trên trong 2 bước:
% ls > tệp_annex % more tệp_annex
Nhưng ta có thể gộp thành một bước với pipe, hiển thị bằng siêu ký tự "|": % ls | more
Tất nhiên có thể liên lạc nhiều tiến trình với nhau bằng các pipe, ví dụ: command_1 | command_2 | command_3
Trong đó command_1 phải có đầu ra, command_2 là bộ lọc và command_3 phải có đầu vào.
Gọi là ống nối vì mỗi pipe nối hai luồng dữ liệu của 2 lệnh liền kề qua một ống trung gian, thể hiện bằng bộ nhớ đệm BUFER; command_j bắt đầu chạy khi BUFFER vừa đầy, dù rằng command_i chưa kết thúc, cách làm việc này gọi là không đồng bộ:
command_i ==> BUFER ==> command_j