Bước tới nội dung

Chuyển hướng (điện toán)

Bách khoa toàn thư mở Wikipedia
Các luồng tiêu chuẩn cho đầu vào, đầu ra và lỗi

Trong điện toán, chuyển hướng là một hình thức giao tiếp giữa các tiến trình và là một chức năng phổ biến đối với hầu hết các trình thông dịch dòng lệnh, bao gồm các shell Unix khác nhau có thể chuyển hướng các luồng tiêu chuẩn đến các vị trí do người dùng chỉ định.

Trong các hệ điều hành giống Unix, các chương trình thực hiện chuyển hướng với lệnh gọi hệ thống dup2 (2) hoặc kém linh hoạt hơn nhưng mức độ cao hơn tương tự stdio là, freopen (3)popen (3).

Chuyển hướng đầu vào tiêu chuẩn và đầu ra tiêu chuẩn

[sửa | sửa mã nguồn]

Chuyển hướng thường được thực hiện bằng cách đặt các ký tự nhất định giữa các lệnh.

Căn bản

[sửa | sửa mã nguồn]

Thông thường, cú pháp như sau, sử dụng < để chuyển hướng đầu vào và > để chuyển hướng đầu ra. command1 > file1 thực thi command1, đặt đầu ra trong file1. Điều này sẽ ghi đè bất kỳ dữ liệu hiện có trong tệp1.

Sử dụng command1 < file1 thực thi command1, với file1 là nguồn đầu vào.

command1 < infile > outfile kết hợp hai khả năng: command1 đọc từ infile và ghi vào outfile

Biến thể

[sửa | sửa mã nguồn]

Để thêm vào cuối của tập tin, chứ không phải là ghi đè nó,>> được sử dụng: command1 >> file1.

Để đọc từ một chuỗi các dòng (một tập tin nhiều dòng, truyền từng dòng tới các đầu vào tiêu chuẩn), người ta có thể sử dụng một here document, sử dụng<<:

1 tr a-z A-Z << END_TEXT
2 one two three
3 uno dos tres
4 END_TEXT

Để đọc từ một chuỗi, người ta có thể sử dụng một here string, sử dụng<<<: tr a-z A-Z <<< "one two three", hoặc là:

NUMBERS="one two three"
tr a-z A-Z <<< "$NUMBERS"

Đường ống

[sửa | sửa mã nguồn]

thumb| Một đường dẫn gồm ba chương trình chạy trên text terminal. Các chương trình có thể được chạy cùng nhau sao cho một chương trình đọc đầu ra từ một chương trình khác mà không cần tệp trung gian rõ ràng. command1 | command2 thực thi command1, sử dụng đầu ra của nó làm đầu vào cho command2 (thường được gọi là đường ống, với ký tự "|" được gọi là "pipe").

Hai chương trình thực hiện các lệnh có thể chạy song song với không gian lưu trữ duy nhất là bộ đệm làm việc (Linux cho phép tối đa 64K cho mỗi bộ đệm) cộng với bất kỳ không gian làm việc nào mà mỗi lệnh xử lý yêu cầu. Ví dụ, lệnh "sort" không thể tạo ra bất kỳ đầu ra nào cho đến khi tất cả các bản ghi đầu vào đã được đọc, vì bản ghi cuối cùng nhận được có thể trở thành đầu tiên theo thứ tự được sắp xếp. Hệ điều hành thử nghiệm của Tiến sĩ Alexia Massalin, Synthesis, sẽ điều chỉnh mức độ ưu tiên của từng tác vụ khi chúng chạy theo mức độ đầy đủ của bộ đệm đầu vào và đầu ra.

Điều này tạo ra kết quả cuối cùng giống như sử dụng hai chuyển hướng và một tệp tạm thời, như cặp lệnh dưới đây:

1 command1 > tempfile
2 command2 < tempfile
3 rm tempfile

Nhưng ở đây, command2 không bắt đầu thực thi cho đến khi command1 kết thúc và một tệp tạm thời đủ lớn được yêu cầu để giữ kết quả trung gian cũng như bất kỳ không gian làm việc nào mà mỗi tác vụ yêu cầu. Ví dụ, mặc dù DOS cho phép cú pháp "pipe", nhưng nó sử dụng cách tiếp cận thứ hai này. Do đó, giả sử một số chương trình chạy trong thời gian dài, "Worker" tạo ra các thông báo khác nhau khi nó hoạt động và chương trình thứ hai, TimeStamp sao chép từng bản ghi từ stdin sang stdout, thêm vào phía trước ngày và giờ của hệ thống khi nhận được bản ghi. Một chuỗi như Worker | TimeStamp > LogFile.txt sẽ chỉ điền thời gian khi Worker đã hoàn thành vào dòng đầu tiên, và ghi thời gian đọc và ghi tệp đầu ra của nó ở các dòng tiếp theo.

Một ví dụ điển hình cho đường ống lệnh là kết hợp echo với một lệnh khác để đạt được thứ gì đó tương tác trong một shell không tương tác, ví dụ echo -e 'user\npass'| ftp localhost. Điều này chạy ứng dụng khách ftp với user đầu vào, nhấn return, sau đó pass.

Trong sử dụng thông thường, bước đầu tiên của một đường ống thường là cat hoặc echo, đọc từ tệp hoặc chuỗi. Điều này thường có thể được thay thế bằng chỉ định đầu vào hoặc here string và sử dụng cat và đường ống thay vì chuyển hướng đầu vào được gọi là sử dụng cat vô dụng. Ví dụ: các lệnh sau:

1 cat infile | cmd
2 echo $string | cmd
3 echo -e 'user\npass' | ftp localhost

có thể được thay thế bởi:

1 cmd < infile
2 cmd <<< $string
3 ftp localhost <<< $'user\npass'

echo thường là một lệnh shell nội bộ, nên việc sử dụng nó không bị chỉ trích như cat, là một lệnh bên ngoài.

Chuyển hướng đến và đi từ xử lí tệp tiêu chuẩn

[sửa | sửa mã nguồn]

Trong các shell Unix có nguồn gốc từ shell Bourne ban đầu, hai hành động đầu tiên có thể được sửa đổi thêm bằng cách đặt một số (bộ mô tả tệp) ngay trước ký tự; điều này sẽ ảnh hưởng đến luồng nào được sử dụng để chuyển hướng. Các luồng I / O tiêu chuẩn Unix là:

Xử lý Tên Sự miêu tả
0 stdin Đầu vào tiêu chuẩn
1 stdout Đầu ra tiêu chuẩn
2 stderr Lỗi tiêu chuẩn

Ví dụ: command1 2> file1 thực thi command1, hướng luồng lỗi tiêu chuẩn đến file1.

Trong các shell có nguồn gốc từ csh (shell C), cú pháp thay vào đó sẽ thêm ký tự & (ampersand) vào các ký tự chuyển hướng, do đó đạt được kết quả tương tự. Lý do cho điều này là để phân biệt giữa một tệp có tên '1' và stdout, tức là 'cat file 2> 1' so với 'cat file 2> &1'. Trong trường hợp đầu tiên, stderr được chuyển hướng đến một tệp có tên '1' và trong trường hợp thứ hai, stderr được chuyển hướng đến stdout.

Một khả năng hữu ích khác là chuyển hướng một xử lý tệp tiêu chuẩn sang một tệp khác. Biến thể phổ biến nhất là hợp nhất lỗi tiêu chuẩn thành đầu ra tiêu chuẩn để thông báo lỗi có thể được xử lý cùng với (hoặc thay thế cho) đầu ra thông thường. Ví dụ: find / -name.profile > results 2>&1 sẽ cố gắng tìm tất cả các tệp có tên .profile. Nếu thực hiện mà không chuyển hướng, nó sẽ xuất các lần tìm được vào stdout và lỗi (ví dụ như thiếu đặc quyền đối với các thư mục được bảo vệ) vào stderr. Nếu đầu ra tiêu chuẩn được hướng đến tập tin results, thông báo lỗi xuất hiện trên console. Để xem cả lượt truy cập và thông báo lỗi trong tệp results, cần hợp nhất stderr (xử lý 2) vào stdout (xử lý 1) bằng cách sử dụng 2> & 1.

Nếu đầu ra được hợp nhất vào đường ống để chuyển sang chương trình khác, chuỗi hợp nhất tệp 2> & 1 phải đặt trước ký hiệu ống, do đó, find / -name.profile2>&1 | less

Một hình thức tuân thủ đơn giản nhưng không phải POSIX của lệnh, command > file 2>&1 là (không có sẵn trong Bourne Shell trước phiên bản 4, bản phát hành cuối cùng hoặc trong vỏ shell Debian Almquist tiêu chuẩn được sử dụng trong Debian / Ubuntu): command &>file hoặc command >&file.

Có thể sử dụng 2>&1 trước " > " nhưng kết quả thường bị hiểu sai. Quy tắc là bất kỳ chuyển hướng nào đều đặt tay cầm vào luồng đầu ra một cách độc lập. Vì vậy, " 2>&1 " đặt xử lý 2 thành bất cứ điều gì xử lý điểm1, mà tại thời điểm đó thường là stdout. Sau đó, " > " chuyển hướng xử lý 1 sang một thứ khác, ví dụ như một tệp, nhưng nó không thay đổi xử lý 2, mà vẫn trỏ đến stdout.

Trong ví dụ sau, đầu ra tiêu chuẩn được ghi vào file, nhưng lỗi được chuyển hướng từ stderr sang stdout, tức là được gửi đến màn hình: command 2>&1 > file.

Để ghi cả lỗi và đầu ra tiêu chuẩn vào tập file, thứ tự phải được đảo ngược. Đầu ra tiêu chuẩn trước tiên sẽ được chuyển hướng đến tệp, sau đó stderr cũng sẽ được chuyển hướng đến stdout đã được thay đổi để trỏ đến tệp: command > file 2>&1. Windows PowerShell 5 định nghĩa sáu luồng khác nhau.

Chuỗi đường ống

[sửa | sửa mã nguồn]

Các mã thông báo chuyển hướng và đường ống có thể được nối lại với nhau để tạo ra các lệnh phức tạp. Ví dụ: sort infile | uniq -c | sort -n > outfile sắp xếp các dòng của infile theo thứ tự từ điển, viết các dòng duy nhất với tiền tố là số lần xuất hiện, sắp xếp các dòng theo số lần xuất hiện và ghi vào outfile. Kiểu xây dựng này được sử dụng rất phổ biến trong các tập lệnh shell và tập tin bó.

Chuyển hướng đến nhiều đầu ra

[sửa | sửa mã nguồn]

Lệnh chuẩn tee có thể chuyển hướng đầu ra từ một lệnh đến một số địa điểm: ls -lrt | tee xyz. Điều này chỉ đạo đầu ra danh sách tập tin cho cả đầu ra tiêu chuẩn và tập tin xyz.

Tham khảo

[sửa | sửa mã nguồn]