Điều hướng IO trong Unix/Linux

Hầu hết các lệnh hệ thống Unix nhận dữ liệu input từ terminal của bạn và gửi output lại cho terminal của bạn. Một lệnh thường đọc input của nó từ một địa điểm gọi là input tiêu chuẩn (standard input), mà xảy ra với terminal của bạn theo mặc định. Theo cách tương tự, một lệnh thường ghi output tới đầu ra tiêu chuẩn (standard output), mà cũng xảy ra với terminal của bạn theo mặc định.

Điều hướng lại output trong Unix/Linux

output từ một lệnh thường có khuynh hướng chờ cho standard output có thể dễ dàng định hướng tới một file. Khả năng này được biết đến như là sự điều hướng lại đầu ra.

Nếu các ký hiệu > file được gán tới bất kỳ lệnh nào thì nó thường ghi đầu ra của nó tới standard output, đầu ra của lệnh đó sẽ được ghi vào file thay vì terminal của bạn.

Chúng ta cùng kiểm tra lệnh who mà sẽ điều hướng lại toàn bộ đầu ra của lệnh trong tệp users:

$ who > users

Chú ý rằng, không đầu ra nào xuất hiện trên terminal. Đó là bởi vì đầu ra đã được điều hướng lại từ thiết bị đầu ra tiêu chuẩn mặc định (terminal) vào trong một file cụ thể. Nếu bạn kiểm tra tệp users thì khi đó file đó sẽ có nội dung đầy đủ:

$ cat users
oko         tty01   Sep 12 07:30
ai          tty15   Sep 12 13:32
ruth        tty21   Sep 12 10:10
pat         tty24   Sep 12 13:07
steve       tty25   Sep 12 13:03
$

Nếu một lệnh có đầu ra được điều hướng lại tới một file và file đó đã chứa một vài dữ liệu, thì dữ liệu đó sẽ bị thất lạc. Xem xét ví dụ sau:

$ echo line 1 > users
$ cat users
line 1
$

Bạn có thể sử dụng toán tử >> để gán đầu ra vào một file đang tồn tại như sau:

$ echo line 2 >> users
$ cat users
line 1
line 2
$

Sự điều hướng lại input trong Unix/Linux

Tương tự như đầu ra của lệnh, input của lệnh cũng có thể điều hướng lại từ một file. Khi ký tự lớn hơn > được sử dụng cho điều hướng input, thì ký tự nhỏ hơn < được sử dụng để điều hướng lại input của lệnh.

Các lệnh mà thường nhận input của nó từ input tiêu chuẩn có thể có input từ một file theo thao tác của người sử dụng. Ví dụ, để tính toán số lượng dòng trong một tệp users trên, bạn có thể chạy lệnh như sau:

$ wc -l users
2 users
$

Ở đây nó sẽ tạo ra kết quả là 2 dòng. Bạn có thể tính toán số dòng trong file bởi điều hướng lại input tiêu chuẩn của lệnh wc từ tệp users.

$ wc -l < users
2
$

Ghi nhớ rằng, có một sự khác nhau trong output bởi 2 mẫu của lệnh wc. Trong trường hợp đầu tiên, tên của tệp users được liệt kê với số dòng, còn trong trường hợp thứ hai thì không.

Trong trường hợp đầu, wc biết rằng nó đang đọc input của nó từ tệp users. Trong trường hợp thứ hai, nó chỉ biết rằng nó đang input của nó từ input tiêu chuẩn vì thế nó không hiển thị tên file.

Here document trong Unix/Linux

Một here document được sử dụng để điều hướng lại input vào trong một shell script hoặc chương trình tương tác.

Chúng ta có thể chạy một chương trình tương tác trong một shell script mà không cần thao tác của người sử dụng cung cấp input yêu cầu cho chương trình hoặc shell script tương tác.

Mẫu chung cho một here document là:

command << delimiter
document
delimiter

Ở đây, shell phiên dịch toán tử << như là một chỉ lệnh để đọc input tới khi nó tìm thấy một dòng chứa giới hạn đã xác định. Tất cả input mà ở trên dòng chứa giới hạn sau đó được cho trở thành input tiêu chuẩn của lệnh.

Giới hạn này nói cho shell rằng here document đã thực hiện xong. Không có nó, shell tiếp tục đọc input mãi mãi. Giới hạn phải là một từ đơn mà không chứa các dấu cách hoặc tab.

Dưới đây là input của lệnh wc -l để tính toán tổng số dòng.

$wc -l << EOF
    This is a simple lookup program 
    for good (and bad) restaurants
    in Cape Town.
EOF
3
$

Bạn có thể sử dụng here document để in nhiều dòng mà sử dụng script của bạn như sau:

#!/bin/sh
cat << EOF
This is a simple lookup program 
for good (and bad) restaurants
in Cape Town.
EOF 

Code này sẽ tạo ra kết quả sau:

This is a simple lookup program
for good (and bad) restaurants
in Cape Town.

Script sau chạy một khu vực với Bộ soạn văn bản vi và lưu giữ input vào trong tệp test.txt.

#!/bin/sh
filename=test.txt
vi $filename <<EndOfCommands
i
This file was created automatically from
a shell script
^[
ZZ
EndOfCommands

Nếu bạn chạy script này với vim mà hoạt động tương tự vi, thì sau đó bạn sẽ thấy output giống như sau:

$ sh test.sh
Vim: Warning: Input is not from a terminal
$

Sau khi chạy script, bạn sẽ thấy đầu ra sau được thêm vào file test.txt.

$ cat test.txt
This file was created automatically from
a shell script
$

Loại bỏ output trong Unix/Linux

Đôi khi bạn sẽ cần chạy một lệnh, nhưng bạn không muốn output hiển thị trên màn hình. Trong những trường hợp như vậy, bạn có thể loại bỏ đầu ra bằng điều hướng lại nó vào trong tệp /dev/null:

$ command > /dev/null

Ở đây, command là tên của lệnh bạn muốn chạy. Tệp /dev/null là một file đặc biệt mà tự động loại bỏ tất cả input của nó.

Để loại bỏ cả đầu ra của một lệnh và đầu ra bị lỗi của lệnh, bạn sử dụng sự điều hướng lại tiêu chuẩn để điều hướng lại STDERR tới STDOUT.

$ command > /dev/null 2>&1

Ở đây 2 đại diện cho STDERR và 1 đại diện cho STDOUT. Bạn có thể hiển thị một thông báo trên STDERR bằng điều hướng lại STDIN thành STDERR như sau:

$ echo message 1>&2

Các lệnh điều hướng lại trong Unix/Linux

Dưới đây là danh sách đầy đủ các lệnh mà bạn có thể sử dụng cho điều hướng lại:

 

LệnhMiêu tả
pgm > fileĐầu ra của pgm được điều hướng tới file.
pgm < fileChương trình pgm đọc input từ file.
pgm >> fileĐầu ra của pgm được gán tới file.
n > fileĐầu ra từ stream với dấu hiệu n được điều hướng tới file.
n >> fileĐầu ra từ stream với dấu hiệu n được gán tới file.
n >& mSáp nhập đầu ra từ stream n với stream m.
n <& mSáp nhập input từ stream n với stream m.
<< taginput tiêu chuẩn xuất phát từ đây qua thẻ tiếp theo tại phần đầu của dòng.
|Nhận đầu ra từ một chương trình hoặc một tiến trình và gửi nó cho chương trình khác..


Ghi chú rằng dấu hiệu file 0 thường là input tiêu chuẩn (STDIN), 1 thường là đầu ra tiêu chuẩn (STDOUT), và 2 thường là đầu ra lỗi tiêu chuẩn (STAERR).

Bình luận