Chuyển hướng các luồng I/O c. Kênh và luồng chương trình, chuyển hướng

1403

Chuyển hướng "2>&1", ">/dev/null" hoặc luồng đầu ra trên Unix (bash/sh)

Đánh giá của bạn: kiệt tác tuyệt vời rất tốt tốt bình thường Chưa đọc có thể chấp nhận được tầm thường tệ rất tệ không đọc

Luồng đầu ra

Thông báo tập lệnh được xuất ra các luồng được xác định rõ - luồng đầu ra. Vì vậy những gì chúng tôi xuất ra thông qua

echo "Xin chào thế giới!"

Không chỉ hiển thị trên màn hình, mà từ quan điểm của hệ thống, và cụ thể là trình thông dịch lệnh sh và bash, nó được xuất ra thông qua một luồng đầu ra cụ thể. Trong trường hợp tiếng vang, luồng số 1 (thiết bị xuất chuẩn) mà màn hình được liên kết.

Một số chương trình và tập lệnh cũng sử dụng luồng đầu ra khác - số 2 (stderr). Họ hiển thị thông báo lỗi ở đó. Điều này giúp có thể tách thông tin thông thường và thông báo lỗi khỏi luồng và định tuyến cũng như xử lý chúng một cách riêng biệt.

Ví dụ: bạn có thể chặn đầu ra tin nhắn thông tin, chỉ để lại thông báo lỗi. Hoặc gửi thông báo lỗi tới tập tin riêng biệtđể đăng nhập.

">somefile" là gì

Một mục như vậy trong Unix (trong thông dịch viên bash và sh) chỉ định chuyển hướng các luồng đầu ra.

Trong ví dụ sau, chúng tôi sẽ chuyển hướng tất cả các thông báo thông tin (thông thường) của lệnh ls đến tệp myfile.txt, do đó chỉ có một danh sách ls trong tệp này:

$ ls > myfile.txt


Trong trường hợp này, sau khi nhấn Enter, bạn sẽ không thấy bất cứ thứ gì trên màn hình, nhưng tệp myfile.txt sẽ chứa mọi thứ lẽ ra phải được hiển thị trên màn hình.

Tuy nhiên, hãy thực hiện một thao tác cố ý sai:

$ ls /masdfasdf > myfile.txt


Vậy điều gì sẽ xảy ra? Bởi vì thư mục masdfasdf không tồn tại trong thư mục gốc của hệ thống tập tin (tôi cho là vậy - nếu bạn làm vậy thì sao?), thì lệnh ls sẽ phát sinh lỗi. Tuy nhiên, nó sẽ đưa ra lỗi này không phải thông qua luồng stdout thông thường (1), mà thông qua luồng lỗi stderr (2). Và chuyển hướng chỉ được đặt cho thiết bị xuất chuẩn ("> myfile.txt").

Bởi vì chúng tôi đã không chuyển hướng luồng stderr(2) đi bất cứ đâu - thông báo lỗi sẽ xuất hiện trên màn hình và KHÔNG xuất hiện trong tệp myfile.txt

Bây giờ hãy chạy lệnh ls để dữ liệu thông tin được ghi vào tệp myfile.txt và các thông báo lỗi được ghi vào tệp myfile.err, không có gì xuất hiện trên màn hình trong khi thực thi:

$ ls >myfile.txt 2>myfile.err


Ở đây, lần đầu tiên chúng tôi gặp phải dấu hiệu của số luồng dưới dạng chuyển hướng. Mục "2>myfile.err" chỉ ra rằng luồng số 2 (stderr) phải được chuyển hướng đến tệp myfile.err.

Tất nhiên, chúng ta có thể hướng cả hai luồng đến cùng một tệp hoặc tới cùng một thiết bị.

2>&1

Bạn thường có thể tìm thấy một mục như vậy trong các tập lệnh. Nó có nghĩa là: "Chuyển hướng luồng số 2 sang luồng số 1" hoặc "Stream stderr - chuyển hướng qua thiết bị xuất chuẩn luồng". Những thứ kia. Chúng tôi định tuyến tất cả các thông báo lỗi thông qua chuỗi mà thông báo bình thường, không có lỗi thường được in.

$ ls /asfasdf 2>&1


Đây là một ví dụ khác trong đó tất cả thư được chuyển hướng đến tệp myfile.txt:

$ ls /asfasdf >myfile.txt 2>&1


Trong trường hợp này, tất cả các tin nhắn, cả lỗi và bình thường, sẽ được ghi vào myfile.txt, bởi vì Trước tiên, chúng tôi đã chuyển hướng luồng thiết bị xuất chuẩn sang một tệp, sau đó chỉ ra rằng các lỗi sẽ được chuyển vào thiết bị xuất chuẩn - theo đó, vào tệp myfile.txt

/dev/null

Tuy nhiên, đôi khi chúng ta chỉ cần ẩn toàn bộ tin nhắn – mà không cần lưu lại. Những thứ kia. chỉ cần chặn đầu ra. Với mục đích này nó được sử dụng thiết bị ảo/dev/null. Trong ví dụ sau, chúng tôi sẽ chuyển tất cả đầu ra của các tin nhắn thông thường từ lệnh ls tới /dev/null:

$ ls > /dev/null


Không có gì ngoài thông báo lỗi sẽ được hiển thị trên màn hình. Và trong ví dụ sau, thông báo lỗi sẽ bị chặn:

$ ls > /dev/null 2>&1


Hơn nữa, bản ghi này tương đương với bản ghi có dạng:

$ ls >/dev/null 2>/dev/null


Và trong ví dụ sau, chúng tôi sẽ chỉ chặn các thông báo lỗi:

$ ls 2>/dev/null

Xin lưu ý rằng bạn không thể chỉ định “2>&1” ở đây nữa vì luồng (1) không được chuyển hướng đến bất kỳ đâu và trong trường hợp này, thông báo lỗi sẽ chỉ xuất hiện trên màn hình.

Cái gì có trước - quả trứng hay con gà?

Tôi sẽ cho bạn 2 ví dụ ở đây.

Ví dụ 1)

$ ls >/dev/null 2>&1


Ví dụ 2)

$ ls 2>&1 >/dev/null


Về hình thức, tổng không thay đổi bằng cách sắp xếp lại vị trí của các âm tiết. Nhưng thứ tự của các con trỏ chuyển hướng mới quan trọng!

Vấn đề là người phiên dịch đọc và áp dụng chuyển hướng từ trái sang phải. Và bây giờ chúng ta sẽ xem xét cả hai ví dụ.

ví dụ 1

1) ">/dev/null" - chúng tôi chuyển trực tiếp luồng 1 (thiết bị xuất chuẩn) tới/dev/null. Tất cả tin nhắn vào luồng (1) sẽ được gửi đến /dev/null.

2) "2>&1" - chúng tôi chuyển hướng luồng 2 (stderr) sang luồng 1 (stdout). Nhưng bởi vì luồng 1 đã được liên kết với/dev/null - tất cả thư sẽ vẫn kết thúc bằng/dev/null.

Kết quả: màn hình trống rỗng.

Ví dụ 2

1) "2>&1" - chúng tôi chuyển hướng luồng lỗi stderr (2) sang luồng lỗi stdout (1). Đồng thời, vì luồng 1 được liên kết với thiết bị đầu cuối theo mặc định - chúng ta sẽ thấy thông báo lỗi trên màn hình thành công.

2) ">/dev/null" - và ở đây chúng tôi chuyển hướng luồng 1 sang /dev/null. VÀ tin nhắn thường xuyên chúng ta sẽ không nhìn thấy.

Kết quả: Trên màn hình chúng ta sẽ thấy thông báo lỗi nhưng không thấy thông báo bình thường.

Kết luận: chuyển hướng luồng trước, sau đó liên kết tới luồng đó.

Theo mặc định, trong hệ thống, ba “tệp” luôn mở - (bàn phím), (màn hình) và (hiển thị thông báo lỗi trên màn hình). Những tệp này và bất kỳ tệp đang mở nào khác đều có thể được chuyển hướng. TRONG trong trường hợp này, thuật ngữ "chuyển hướng" có nghĩa là lấy đầu ra từ một tệp, lệnh, chương trình, tập lệnh hoặc thậm chí một khối trong tập lệnh (xem Ví dụ 3-1 và Ví dụ 3-2) và chuyển nó làm đầu vào cho một tệp khác, lệnh, chương trình hoặc tập lệnh.

Mỗi tệp đang mở có một bộ mô tả tệp được liên kết với nó. Các bộ mô tả tệp và lần lượt là 0, 1 và 2. Khi mở Các tệp bổ sung, phần mô tả từ 3 đến 9 vẫn chưa được sử dụng. Đôi khi các bộ mô tả bổ sung có thể thực hiện tốt công việc, lưu trữ tạm thời một liên kết đến hoặc. Điều này giúp dễ dàng đưa các bộ điều khiển về trạng thái bình thường sau các thao tác chuyển hướng và hoán đổi phức tạp (xem Ví dụ 16-1).

LỰA CHỌN_OUTPUT > # Chuyển hướng thiết bị xuất chuẩn(đầu ra) thành một tập tin. # Nếu thiếu file, nó sẽ được tạo, nếu không sẽ bị ghi đè. ls -lR > dir-tree.list # Tạo một tệp chứa danh sách cây thư mục. : > tên tệp # Thao tác > cắt bớt "tên tệp" của tệp về độ dài bằng 0. # Nếu tập tin không tồn tại trước khi thực hiện thao tác, # nó sẽ được tạo tập tin mới Với chiều dài bằng không(lệnh "chạm" có tác dụng tương tự). # Ký hiệu: đóng vai trò giữ chỗ ở đây, không xuất ra bất cứ thứ gì. > tên tệp # Thao tác > cắt bớt "tên tệp" của tệp thành độ dài bằng 0. # Nếu tệp không tồn tại trước thao tác, # thì một tệp mới có độ dài bằng 0 sẽ được tạo (lệnh "touch" có tác dụng tương tự). # (kết quả tương tự như ":>" ở trên, nhưng tùy chọn này không hoạt động # trong một số shell.) COMMAND_OUTPUT >> # Chuyển hướng thiết bị xuất chuẩn (đầu ra) sang một tệp. # Tạo một tệp mới nếu nó bị thiếu, nếu không thì sẽ thêm nó vào cuối tệp. # Các lệnh chuyển hướng một dòng # (chỉ ảnh hưởng đến dòng mà chúng xuất hiện): # ————————————————————————— 1>tên tệp # Đầu ra chuyển hướng (thiết bị xuất chuẩn) ) để gửi "tên tệp". 1>>tên tệp # Chuyển hướng đầu ra (stdout) sang tệp "tên tệp", tệp được mở ở chế độ chắp thêm. 2>tên tệp # Chuyển hướng stderr sang tệp "tên tệp". 2>>tên tệp # Chuyển hướng stderr sang tệp "tên tệp", tệp được mở ở chế độ chắp thêm. &>tên tệp # Chuyển hướng thiết bị xuất chuẩn và thiết bị xuất chuẩn vào tệp "tên tệp". #===================================================== == ================================ # Chuyển hướng thiết bị xuất chuẩn, chỉ cho một dòng. LOGFILE=script.log echo "Dòng này sẽ được ghi vào tập tin \"$LOGFILE\"." 1>$LOGFILE echo "Dòng này sẽ được thêm vào cuối tập tin \"$LOGFILE\"." 1>>$LOGFILE echo "Dòng này cũng sẽ được thêm vào cuối tập tin \"$LOGFILE\"." 1>>$LOGFILE echo "Dòng này sẽ được in ra màn hình và sẽ không xuất hiện trong tập tin \"$LOGFILE\"." # Sau mỗi dòng, việc chuyển hướng được thực hiện sẽ tự động được đặt lại. # Chuyển hướng stderr, chỉ cho một dòng. ERRORFILE=script.errors bad_command1 2>$ERRORFILE # Thông báo lỗi sẽ được ghi vào $ERRORFILE. bad_command2 2>>$ERRORFILE # Một thông báo lỗi sẽ được thêm vào cuối $ERRORFILE. bad_command3 # Thông báo lỗi sẽ được in ra stderr, #+ và sẽ không chuyển tới $ERRORFILE. # Sau mỗi dòng, việc chuyển hướng được thực hiện cũng tự động được đặt lại. #===================================================== == =============================== 2>&1 # Chuyển hướng stderr sang stdout. # Thông báo lỗi được gửi đến cùng nơi với đầu ra tiêu chuẩn. tôi> Tôi V. j. # Xuất ra file có mô tả Tôiđược chuyển vào tập tin với bộ mô tả j. >&j # Bộ mô tả tập tin được chuyển hướng 1 (stdout) vào một tệp có bộ mô tả j. # Đầu ra của thiết bị xuất chuẩn được gửi đến bộ mô tả tệp j. 0< FILENAME < FILENAME # Ввод из файла. # Парная команде ">", thường được kết hợp với nó. # # grep search-word tên tệp # Tệp "tên tệp" được mở để đọc và ghi và được liên kết với thẻ điều khiển "j". # Nếu thiếu "tên tệp", nó sẽ được tạo. # Nếu bộ mô tả "j" không được chỉ định thì bộ mô tả 0, stdin, sẽ được lấy theo mặc định. # # Một cách sử dụng cho việc này là ghi vào một vị trí cụ thể trong một tập tin. echo 1234567890 > Tệp # Viết một chuỗi vào tệp "Tệp". thực hiện 3<>Tệp # Mở "Tệp" và liên kết với phần xử lý 3. read -n 4<&3 # Прочитать 4 символа. echo -n . >&3 # Viết ký tự dấu chấm. exec 3>&- # Đóng xử lý 3. cat File # ==> 1234.67890 # Truy cập ngẫu nhiên, thế thôi! | # Băng tải (kênh). # Phương thuốc phổ quátđể kết hợp các lệnh thành một chuỗi. # Trông giống như ">", nhưng thực ra rộng hơn. # Được sử dụng để kết hợp các lệnh, tập lệnh, tệp và chương trình thành một chuỗi (đường ống). mèo *.txt | sắp xếp | uniq > result-file # Nội dung của tất cả các tệp .txt được sắp xếp, các dòng trùng lặp được loại bỏ, # kết quả được lưu trong tệp "tệp kết quả".

Các hoạt động chuyển hướng và/hoặc đường dẫn có thể được kết hợp trên cùng một dòng lệnh.

yêu cầu< input-file >lệnh tập tin đầu ra1 | lệnh2 | command3 > tệp đầu ra Xem Ví dụ 12-23 và Ví dụ A-17.

Có thể chuyển hướng nhiều luồng đến một tệp.

ls -yz >> command.log 2>&1 # Một thông báo về tùy chọn "yz" không hợp lệ trong lệnh "ls" sẽ được ghi vào tệp "command.log". # Bởi vì stderr được chuyển hướng đến một tập tin.

Đóng các thẻ xử lý tập tin

Đóng bộ mô tả tập tin đầu vào.

0<&-, <&-

Đóng bộ mô tả tập tin đầu ra.

1>&-, >&-

Các tiến trình con kế thừa các thẻ điều khiển mở tập tin. Đây là lý do tại sao băng tải hoạt động. Để ngăn việc kế thừa các tay cầm, hãy đóng chúng trước khi bắt đầu tiến trình con.

# Chỉ có stderr được chuyển vào đường ống. exec 3>&1 # Lưu "trạng thái" hiện tại vào thiết bị xuất chuẩn. ls -l 2>&1 >&3 3>&- | grep bad 3>&- # Đóng desc. 3 cho "grep" (nhưng không phải cho "ls"). # ^^ ^^ ^^ ^^ exec 3>&- # Bây giờ hãy đóng nó lại để xem phần còn lại của tập lệnh. # Cảm ơn S.C.

Để biết thêm thông tin về chuyển hướng I/O, hãy xem Phụ lục D.

16.1. Sử dụng lệnh người điều hành

Đội người điều hành chuyển hướng đầu vào từ một tập tin. Từ giờ trở đi, tất cả đầu vào, thay vì (thường là bàn phím), sẽ được tạo từ tệp này. Điều này cho phép đọc nội dung của tệp, từng dòng và phân tích từng dòng được nhập bằng sed và/hoặc awk.

Ví dụ 16-1. Chuyển hướng với exec

#!/bin/bash # Chuyển hướng stdin bằng "exec". thực hiện 6<&0 # Связать дескр. #6 со стандартным вводом (stdin). # Сохраняя stdin. exec < data-file # stdin заменяется файлом "data-file" read a1 # Читается первая строка из "data-file". read a2 # Читается вторая строка из "data-file." echo echo "Следующие строки были прочитаны из файла." echo "——————————————" echo $a1 echo $a2 echo; echo; echo exec 0<&6 6<&- # Восстанавливается stdin из дескр. #6, где он был предварительно сохранен, #+ и дескр. #6 закрывается (6<&-) освобождая его для других процессов. # # <&6 6<&- дает тот же результат. echo -n "Введите строку " read b1 # Теперь функция "read", как и следовало ожидать, принимает данные с обычного stdin. echo "Строка, принятая со stdin." echo "—————————" echo "b1 = $b1" echo exit 0

Tương tự như vậy, việc thiết kế thực thi >tên tệp chuyển hướng đầu ra đến tập tin được chỉ định. Sau đó, tất cả đầu ra từ các lệnh thường được chuyển hướng đến giờ sẽ được xuất ra tệp này.

Ví dụ 16-2. Chuyển hướng với exec

#!/bin/bash # resign-stdout.sh LOGFILE=logfile.txt exec 6>&1 # Liên kết desc. # 6 với thiết bị xuất chuẩn. # Lưu trữ thiết bị xuất chuẩn. exec > $LOGFILE # stdout được thay thế bằng tệp "logfile.txt". # ————————————————————— # # Tất cả đầu ra từ các lệnh trong khối này được ghi vào tệp $LOGFILE. echo -n "Logfile: " date echo "—————————————-" echo echo "Đầu ra của \"ls -al\"" echo ls -al echo; echo echo "Đầu ra của lệnh \"df\"" echo df # ———————————————————— # exec 1>&6 6>&- # Khôi phục thiết bị xuất chuẩn và đóng tập tin. #6. echo echo "== stdout được khôi phục về mặc định == " echo ls -al echo exit 0

Ví dụ 16-3. Chuyển hướng đồng thời các thiết bị và sử dụng lệnh exec

#!/bin/bash # Upperconv.sh # Chuyển đổi các ký tự trong tệp đầu vào thành chữ hoa. E_FILE_ACCESS=70 E_WRONG_ARGS=71 nếu [ ! -r "$1" ] # Tập tin có đọc được không? sau đó lặp lại "Không thể đọc do của tập tin này!" echo "Cách sử dụng: $0 tệp đầu vào tệp đầu ra" exit $E_FILE_ACCESS fi # Trong trường hợp tệp đầu vào ($1) không được chỉ định #+ mã thoát sẽ giống nhau. nếu [ -z "$2" ] thì echo " Một tập tin đầu ra phải được chỉ định." echo "Cách sử dụng: $0 tập tin đầu vào tập tin đầu ra" exit $E_WRONG_ARGS fi exec 4<&0 exec < $1 # Назначить ввод из входного файла. exec 7>&1 exec > $2 # Gán đầu ra cho một tệp đầu ra. # Giả sử tập tin đầu ra có thể ghi được # (thêm kiểm tra?). # ————————————————— mèo — | tr a-z A-Z # Chuyển sang chữ hoa # ^^^^ # Đọc từ stdin. # ^^ ^^ ^^ ^^ ^^ # Viết vào thiết bị xuất chuẩn. # Tuy nhiên, cả stdin và stdout đều được chuyển hướng. # ———————————————— exec 1>&7 7>&- # Khôi phục thiết bị xuất chuẩn. thực thi 0<&4 4<&- # Восстановить stdin. # После восстановления, следующая строка выводится на stdout, чего и следовало ожидать. echo "Символы из \"$1\" преобразованы в верхний регистр, результат записан в \"$2\"." exit 0

Kế tiếp: Chuyển hướng lỗi sang một tập tin Hướng lên: Chuyển hướng I/O Trước: Chuyển hướng đầu vào từ một tập tin Nội dung Mục lục

Chuyển hướng đầu ra sang một tập tin

Để chuyển hướng đầu ra tiêu chuẩn tới một tập tin, hãy dùng toán tử `>'.

Chuyển hướng I/O trong Linux

Thực hiện theo tên lệnh với toán tử >, theo sau là tên của tệp sẽ đóng vai trò là đích cho đầu ra. Ví dụ: để ghi đầu ra của chương trình vào một tệp, hãy nhập:

Nếu bạn chuyển hướng đầu ra tiêu chuẩn sang một tệp đã có sẵn, nó sẽ bị ghi đè ngay từ đầu. Để nối thêm đầu ra tiêu chuẩn vào nội dung của một tập tin hiện có, bạn phải sử dụng toán tử `"'. Ví dụ, để thêm kết quả công việc khi chạy lại chương trình vào một file, hãy nhập:

Alex Otwagin 2002-12-16

Một chương trình thường có giá trị vì nó có thể xử lý dữ liệu: nhận thứ này, tạo ra thứ khác làm đầu ra và hầu hết mọi thứ đều có thể đóng vai trò là dữ liệu: văn bản, số, âm thanh, video... Luồng dữ liệu đầu vào và đầu ra của một lệnh được gọi là đầu vàoPhần kết luận. Mỗi chương trình có thể có nhiều luồng đầu vào và đầu ra. Trong mỗi tiến trình, khi được tạo trong bắt buộc nhận được cái gọi là đầu vào tiêu chuẩn(đầu vào tiêu chuẩn, stdin) và đầu ra tiêu chuẩn(đầu ra tiêu chuẩn, thiết bị xuất chuẩn) và đầu ra lỗi tiêu chuẩn(lỗi tiêu chuẩn, stderr).

Các luồng đầu vào/đầu ra tiêu chuẩn chủ yếu nhằm mục đích trao đổi thông tin văn bản. Ai giao tiếp qua văn bản thậm chí không quan trọng: một người có chương trình hoặc các chương trình giữa họ - điều chính là họ có kênh truyền dữ liệu và họ nói “cùng một ngôn ngữ”.

Nguyên tắc văn bản khi làm việc với máy cho phép bạn thoát khỏi các phần cụ thể của máy tính, chẳng hạn như bàn phím hệ thống và card màn hình với một màn hình, xem xét một thiết bị đầu cuối, qua đó người dùng nhập văn bản (lệnh) và truyền nó đến hệ thống, và hệ thống sẽ xuất ra cần thiết cho người dùng dữ liệu và thông báo (chẩn đoán và lỗi). Một thiết bị như vậy được gọi là phần cuối. TRONG trường hợp chung thiết bị đầu cuối là điểm truy cập của người dùng vào hệ thống và có khả năng truyền thông tin văn bản. Thiết bị đầu cuối có thể là một thiết bị riêng biệt thiết bị bên ngoài, được kết nối với máy tính thông qua cổng dữ liệu nối tiếp (trong máy tính cá nhân nó được gọi là "cổng COM"). Một chương trình (ví dụ: xterm hoặc ssh) cũng có thể hoạt động như một thiết bị đầu cuối (với một số hỗ trợ từ hệ thống). Cuối cùng, bảng điều khiển ảo- cũng là thiết bị đầu cuối, chỉ được tổ chức theo chương trình bằng cách sử dụng thiết bị phù hợp máy tính hiện đại.

Khi làm việc ở dòng lệnh, đầu vào tiêu chuẩn của shell được liên kết với bàn phím, còn đầu ra tiêu chuẩn và đầu ra lỗi được liên kết với màn hình điều khiển (hoặc cửa sổ trình mô phỏng thiết bị đầu cuối). Hãy hiển thị với một ví dụ lệnh đơn giản nhất-con mèo. Thông thường đội con mèođọc dữ liệu từ tất cả các tệp được chỉ định làm tham số của nó và gửi dữ liệu đọc trực tiếp đến đầu ra tiêu chuẩn (thiết bị xuất chuẩn). Vì vậy lệnh

/home/larry/papers# luận án thạc sĩ cuối cùng về lịch sử mèo

sẽ hiển thị nội dung của tệp trước, sau đó là tệp.

Tuy nhiên, nếu tên tệp không được chỉ định, chương trình sẽ con mèođọc đầu vào từ stdin và ngay lập tức trả nó về thiết bị xuất chuẩn (mà không sửa đổi nó theo bất kỳ cách nào). Dữ liệu đi qua con mèo như xuyên qua một đường ống. Hãy đưa ra một ví dụ:

/home/larry/papers# cat Xin chào bạn. Xin chào. Tạm biệt. Tạm biệt. Điều khiểnD/home/larry/papers#

Mỗi dòng được nhập từ bàn phím sẽ ngay lập tức được chương trình con mèo đưa trở lại màn hình. Khi nhập thông tin từ đầu vào tiêu chuẩn, phần cuối của văn bản được báo hiệu bằng cách nhập sự kết hợp đặc biệt phím, thường Điều khiểnD.

Hãy đưa ra một ví dụ khác. Đội loạiđọc các dòng văn bản đầu vào (cũng từ stdin nếu không có tên tệp nào được chỉ định) và xuất ra một tập hợp các dòng này ở dạng có thứ tự trên thiết bị xuất chuẩn. Hãy kiểm tra hành động của nó.

/home/larry/papers# sắp xếp chuối cà rốt táo Ctrl+D táo chuối cà rốt /home/larry/papers#

Như bạn có thể thấy, sau khi nhấn Điều khiểnD, loại xuất ra các dòng được sắp xếp trong thứ tự ABC.

Đầu vào tiêu chuẩn và đầu ra tiêu chuẩn

Giả sử bạn muốn định tuyến đầu ra lệnh sắp xếp vào một số tập tin để lưu danh sách được sắp xếp theo thứ tự bảng chữ cái trên đĩa. Shell lệnh cho phép bạn chuyển hướng đầu ra tiêu chuẩn của lệnh sang tệp bằng ký hiệu. Hãy đưa ra một ví dụ:

/home/larry/papers#sort > danh sách mua sắm chuối cà rốt táo Điều khiểnD/home/larry/papers#

Bạn có thể thấy rằng đầu ra của lệnh sắp xếp không được in trên màn hình mà được lưu trong một tệp có tên. Hãy hiển thị nội dung của tập tin này:

/home/larry/papers# danh sách mua sắm mèo táo chuối cà rốt /home/larry/papers#

Bây giờ hãy để danh sách không có thứ tự ban đầu ở trong một tệp. Danh sách này có thể được sắp xếp bằng lệnh loại, bằng cách yêu cầu nó đọc từ một tệp nhất định thay vì từ đầu vào tiêu chuẩn của nó, đồng thời chuyển hướng đầu ra tiêu chuẩn sang một tệp, như đã thực hiện ở trên. Ví dụ:

/home/larry/papers# sắp xếp các mục trong danh sách mua sắm /home/larry/papers# danh sách mua sắm của mèo táo chuối cà rốt /home/larry/papers#

Tuy nhiên, bạn có thể làm điều đó theo cách khác bằng cách chuyển hướng không chỉ đầu ra tiêu chuẩn mà còn đầu vào tiêu chuẩn tiện ích từ tệp bằng ký hiệu:

/home/larry/papers# sắp xếp< items apples bananas carrots /home/larry/papers#

Kết quả lệnh loại< items tương đương với lệnh sắp xếp các mục, tuy nhiên phần đầu tiên thể hiện điều sau: khi ban hành lệnh loại< items hệ thống hoạt động như thể dữ liệu chứa trong tệp được nhập từ đầu vào tiêu chuẩn. Việc chuyển hướng được thực hiện bởi lệnh shell. Đội loại tên tệp không được báo cáo: lệnh này đọc dữ liệu từ đầu vào tiêu chuẩn của nó như thể chúng ta đã nhập nó từ bàn phím.

Hãy giới thiệu khái niệm lọc. Bộ lọc là một chương trình đọc dữ liệu từ đầu vào tiêu chuẩn, xử lý dữ liệu theo cách nào đó và gửi kết quả đến đầu ra tiêu chuẩn. Khi áp dụng chuyển hướng, các tệp có thể được sử dụng làm đầu vào và đầu ra tiêu chuẩn. Như đã nêu ở trên, theo mặc định, stdin và stdout lần lượt đề cập đến bàn phím và màn hình. Chương trình sắp xếp là một bộ lọc đơn giản - nó sắp xếp dữ liệu đầu vào và gửi kết quả đến đầu ra tiêu chuẩn. Một bộ lọc rất đơn giản là chương trình con mèo- nó không làm gì với dữ liệu đầu vào mà chỉ gửi nó đến đầu ra.

Chúng tôi đã trình bày cách sử dụng chương trình sắp xếp làm bộ lọc ở trên. Những ví dụ này giả định rằng dữ liệu nguồn nằm trong một số tệp hoặc dữ liệu nguồn sẽ được nhập từ bàn phím (đầu vào tiêu chuẩn). Tuy nhiên, điều gì sẽ xảy ra nếu bạn muốn sắp xếp dữ liệu là kết quả của một số lệnh khác, ví dụ: ls?

Chúng tôi sẽ sắp xếp dữ liệu theo thứ tự bảng chữ cái ngược lại; việc này được thực hiện bằng tùy chọn lệnh loại. Nếu bạn muốn liệt kê các tập tin trong thư mục hiện tại theo thứ tự bảng chữ cái đảo ngược, một cách để làm điều đó là như sau.

Chuyển hướng I/O

Đầu tiên chúng ta hãy sử dụng lệnh ls:

/home/larry/papers# ls tiếng anh-danh sách lịch sử-cuối cùng ghi chú luận án thạc sĩ/home/larry/papers#

Bây giờ chúng tôi chuyển hướng đầu ra lệnh ls vào một tập tin có tên file-list

/home/larry/papers# ls > file-list /home/larry/papers#sort -r file-list ghi chú masters-the history-final English-list /home/larry/papers#

Đây là đầu ra lệnh lsđược lưu trong một tệp và sau đó tệp này được xử lý bằng lệnh loại. Tuy nhiên, con đường này không phù hợp và đòi hỏi phải sử dụng tập tin tạm thờiđể lưu trữ đầu ra chương trình ls.

Giải pháp cho tình trạng này có thể là tạo ra lệnh neo(đường ống). Việc gắn kết được thực hiện bởi shell lệnh, lệnh này hướng thiết bị xuất chuẩn của lệnh đầu tiên đến stdin của lệnh thứ hai. Trong trường hợp này, chúng tôi muốn gửi lệnh tới thiết bị xuất chuẩn ls tới các lệnh stdin loại. Một biểu tượng được sử dụng để gắn đế, như trong ví dụ sau:

/home/larry/papers# ls | sắp xếp -r ghi chú thạc sĩ-luận văn lịch sử-cuối cùng danh sách tiếng anh /home/larry/papers#

Lệnh này ngắn hơn một tập hợp các lệnh và dễ gõ hơn.

Hãy xem xét một cái khác ví dụ hữu ích. Đội

/home/larry/papers# ls /usr/bin

trả về một danh sách dài các tập tin. Hầu hết danh sách này lướt qua màn hình quá nhanh để có thể đọc được nội dung của danh sách này. Hãy thử sử dụng lệnh more để hiển thị danh sách này theo từng phần:

/home/larry/papers# ls /usr/bin | hơn

Bây giờ bạn có thể “lướt qua” danh sách này.

Bạn có thể đi xa hơn và cập bến nhiều hơn hai đội. Hãy xem xét đội cái đầu, là một bộ lọc có thuộc tính sau: nó xuất ra những dòng đầu tiên từ luồng đầu vào (trong trường hợp của chúng tôi, đầu vào sẽ là đầu ra từ một số lệnh được nối). Nếu chúng ta muốn hiển thị tên tệp theo thứ tự bảng chữ cái cuối cùng trong thư mục hiện tại, chúng ta có thể sử dụng lệnh dài sau:

/home/larry/papers# ls | sắp xếp -r | đầu -1 ghi chú /home/larry/papers\#

đội ở đâu cái đầu hiển thị dòng đầu tiên của luồng đầu vào của các dòng mà nó nhận được (trong trường hợp của chúng tôi, luồng bao gồm dữ liệu từ lệnh ls), được sắp xếp theo thứ tự bảng chữ cái đảo ngược.

Sử dụng các lệnh xếp chồng (đường ống)

Tác dụng của việc sử dụng biểu tượng để chuyển hướng đầu ra tệp là có hại; nói cách khác, đội

/home/larry/papers# ls > danh sách tập tin

sẽ hủy nội dung của tệp nếu tệp đã tồn tại trước đó và tạo một tệp mới vào vị trí của nó.

Thay vào đó, nếu việc chuyển hướng được thực hiện bằng cách sử dụng các ký hiệu thì đầu ra sẽ được thêm vào cuối tệp được chỉ định mà không phá hủy nội dung gốc của tệp. Ví dụ, lệnh

/home/larry/papers# ls >> danh sách tập tin

thuộc tính đầu ra của lệnh lsđến cuối tập tin.

Xin lưu ý rằng việc chuyển hướng đầu vào và đầu ra cũng như nối lệnh được thực hiện vỏ lệnh, hỗ trợ việc sử dụng các ký hiệu và. Bản thân các đội không thể nhận thức và giải thích những biểu tượng này.

Chuyển hướng đầu ra không phá hủy

Một cái gì đó như thế này sẽ làm những gì bạn cần?

Kiểm tra nó ra: wintee

Không cần Cygwin.

Tuy nhiên, tôi đã gặp phải và báo cáo một số vấn đề.

Ngoài ra, bạn có thể muốn xem http://unxutils.sourceforge.net/ vì nó chứa tee (và không cần cygwin), nhưng hãy cẩn thận rằng đầu ra EOL giống UNIX.

Cuối cùng nhưng không kém phần quan trọng, nếu có PowerShell, bạn có thể dùng thử Tee-Object. Nhập vào bảng điều khiển PowerShell để biết thêm thông tin.

Điều này hoạt động, mặc dù nó hơi xấu:

Nó linh hoạt hơn một số giải pháp khác một chút ở chỗ nó hoạt động theo cách riêng nên bạn có thể sử dụng để bổ sung.

Tôi sử dụng điều này khá nhiều trong các tệp bó để ghi nhật ký và hiển thị thông báo:

Có, bạn có thể chỉ cần lặp lại câu lệnh ECHO (một lần cho màn hình và lần thứ hai chuyển hướng đến tệp nhật ký), nhưng điều đó trông cũng tệ như vậy và là một vấn đề bảo trì.

Chuyển hướng đầu vào và đầu ra

Ít nhất bằng cách này, bạn không phải thực hiện thay đổi đối với tin nhắn ở hai nơi.

Lưu ý rằng _ chỉ là tên ngắn tệp, vì vậy bạn sẽ cần xóa nó ở cuối tệp bó của mình (nếu bạn đang sử dụng tập tin hàng loạt).

Điều này sẽ tạo một tệp nhật ký với thời điểm hiện tại và thời gian, đồng thời bạn có thể sử dụng các dòng console trong quá trình

Nếu bạn có Cygwin trên đường đi của bạn Môi trường Windows, bạn có thể dùng:

Đơn giản ứng dụng giao diện điều khiển C# sẽ thực hiện thủ thuật:

Để sử dụng điều này, bạn chỉ cần chuyển lệnh nguồn tới chương trình và chỉ định đường dẫn đến bất kỳ tệp nào mà bạn muốn sao chép đầu ra. Ví dụ:

Sẽ hiển thị kết quả tìm kiếm và cũng lưu kết quả trong files1.txt và files2.txt.

Lưu ý rằng không có nhiều cách xử lý lỗi (không có gì!) và việc hỗ trợ nhiều tệp có thể không cần thiết.

Tôi cũng đang tìm giải pháp tương tự, sau một chút thử tôi đã có thể thực hiện thành công việc này trên dòng lệnh. Đây là giải pháp của tôi:

Nó thậm chí còn chiếm quyền điều khiển bất kỳ lệnh PAUSE nào.

Một cách khác là chuyển thiết bị xuất chuẩn sang thiết bị xuất chuẩn trong chương trình của bạn:

Sau đó, trong tệp bó dos của bạn:

Stdout sẽ đi tới tệp nhật ký và stderr (cùng dữ liệu) sẽ được hiển thị trên bảng điều khiển.

Cách hiển thị và chuyển hướng đầu ra sang một tập tin. Giả sử nếu tôi sử dụng lệnh dos, dir> test.txt, lệnh này chuyển hướng đầu ra sang file test.txt mà không hiển thị kết quả. cách viết lệnh in đầu ra và chuyển hướng đầu ra sang một tệp có sử dụng DOS, tức là lệnh Chuỗi Windows, không phải UNIX/LINUX.

Bạn có thể thấy các lệnh này trong biterscripting (http://www.biterscripting.com) hữu ích.

Đây là một biến thể của câu trả lời trước của MTS, tuy nhiên nó bổ sung một số tính năng có thể hữu ích cho những tính năng khác. Đây là phương pháp tôi đã sử dụng:

  • Lệnh được đặt làm biến có thể được sử dụng sau này trong mã để xuất ra cửa sổ lệnh và được thêm vào tệp nhật ký bằng cách sử dụng
    • lệnh tránh chuyển hướng bằng biểu tượng củ cà rốt để ban đầu các lệnh không được đánh giá
  • Một tệp tạm thời được tạo với tên tệp tương tự như tệp bó có tên sử dụng cú pháp mở rộng tham số dòng lệnhđể lấy tên của tập tin batch.
  • Kết quả được thêm vào một tệp nhật ký riêng

Đây là chuỗi lệnh:

  1. Thông báo đầu ra và lỗi được gửi đến một tệp tạm thời
  2. Nội dung của tệp tạm thời là:
    • đã thêm vào tệp nhật ký
    • xuất ra cửa sổ lệnh
  3. Tệp tạm thời có tin nhắn bị xóa

Đây là một ví dụ:

Bằng cách này, lệnh có thể được thêm vào sau các lệnh sau trong một tệp bó, trông gọn gàng hơn nhiều:

Điều này cũng có thể được thêm vào cuối các lệnh khác. Theo như tôi có thể nói thì điều này sẽ hoạt động khi tin nhắn có nhiều dòng. Ví dụ, lệnh tiếp theo in hai dòng nếu có thông báo lỗi:

Tôi đồng ý với Brian Rasmussen, cổng unxutils là cách dễ nhất để thực hiện việc này. Trong phần Tệp hàng loạt trên các trang Tập lệnh của mình, Rob van der Woude cung cấp rất nhiều thông tin về cách sử dụng các lệnh MS-DOS và CMD. Tôi nghĩ anh ấy có thể có giải pháp riêng vấn đề của bạn, và sau khi tìm hiểu kỹ về TEE.BAT, tôi đã tìm thấy TEE.BAT, có vẻ như chỉ có vậy, một đợt gói ngôn ngữ MS-DOS. Đây là một tệp bó khá phức tạp và tôi có xu hướng sử dụng cổng unxutils.

Tôi cài đặt Perl trên hầu hết các máy của mình, vì vậy câu trả lời là sử dụng Perl: tee.pl

thư mục | perl tee.pl hoặc danh mục | perl tee.pl dir.bat

thô và chưa được kiểm tra.

Một trong những chủ đề thú vị và hữu ích nhất dành cho quản trị viên hệ thống và những người dùng mới mới bắt đầu hiểu cách làm việc với thiết bị đầu cuối - đây là sự chuyển hướng các luồng đầu vào/đầu ra của Linux. Tính năng đầu cuối này cho phép bạn chuyển hướng đầu ra của lệnh sang một tệp hoặc nội dung của tệp thành đầu vào lệnh, để kết hợp các lệnh với nhau và tạo thành các đường dẫn lệnh.

Trong bài viết này, chúng ta sẽ xem xét cách thực hiện chuyển hướng luồng I/O trong Linux, toán tử nào được sử dụng cho việc này và tất cả những điều này có thể được sử dụng ở đâu.

Tất cả các lệnh chúng tôi thực hiện đều trả về cho chúng tôi ba loại dữ liệu:

  • Kết quả của lệnh, thường là dữ liệu văn bản do người dùng yêu cầu;
  • Thông báo lỗi - thông báo về quá trình thực hiện lệnh và các tình huống bất ngờ phát sinh;
  • Mã trả về là một con số cho phép bạn đánh giá xem chương trình có hoạt động chính xác hay không.

Trong Linux, tất cả các chất đều được coi là tệp, bao gồm cả luồng đầu vào đầu ra linux- các tập tin. Mỗi bản phân phối có ba tệp luồng chính mà các chương trình có thể sử dụng, chúng được xác định bởi shell và được xác định bằng số mô tả tệp của chúng:

  • STDIN hoặc 0- tệp này được liên kết với bàn phím và hầu hết các lệnh đều nhận dữ liệu để hoạt động từ đây;
  • STDOUT hoặc 1- đây là đầu ra tiêu chuẩn; chương trình sẽ gửi tất cả kết quả công việc của nó ở đây. Nó được kết nối với màn hình, hay nói chính xác hơn là với thiết bị đầu cuối nơi chương trình đang chạy;
  • STDERR hoặc 2- tất cả các thông báo lỗi đều được xuất ra tệp này.

Chuyển hướng I/O cho phép bạn thay thế một trong các tệp này bằng tệp của riêng bạn. Ví dụ: bạn có thể buộc một chương trình đọc dữ liệu từ một tệp trong hệ thống tập tin, thay vì bàn phím, bạn cũng có thể xuất lỗi ra tệp thay vì ra màn hình, v.v. Tất cả điều này được thực hiện bằng cách sử dụng các ký hiệu "<" ">" .

Chuyển hướng đầu ra sang tập tin

Mọi thứ đều rất đơn giản. Bạn có thể chuyển hướng đầu ra sang một tệp bằng ký hiệu >. Ví dụ: hãy lưu đầu ra của lệnh top:

top -bn 5 > top.log

Tùy chọn -b khiến chương trình chạy ở chế độ hàng loạt không tương tác và n - lặp lại thao tác năm lần để lấy thông tin về tất cả các quy trình. Bây giờ hãy xem điều gì đã xảy ra với con mèo:

Biểu tượng ">" ghi đè thông tin từ một tập tin nếu đã có thông tin gì đó ở đó. Để nối thêm dữ liệu vào mục đích sử dụng cuối cùng ">>" . Ví dụ: chuyển hướng đầu ra sang tập tin linux cũng dành cho hàng đầu:

top -bn 5 >> top.log

Theo mặc định, bộ mô tả tệp đầu ra tiêu chuẩn được sử dụng để chuyển hướng. Nhưng bạn có thể chỉ định điều này một cách rõ ràng. Lệnh này sẽ cho kết quả tương tự:

top -bn 5 1>top.log

Chuyển hướng lỗi sang tập tin

Để chuyển hướng đầu ra lỗi sang một tệp, bạn cần chỉ định rõ ràng bộ mô tả tệp mà bạn sắp chuyển hướng. Đối với lỗi, đây là số 2. Ví dụ: khi cố gắng truy cập vào thư mục superuser, ls sẽ báo lỗi:

Bạn có thể chuyển hướng lỗi tiêu chuẩn sang một tệp như thế này:

ls -l /root/ 2> ls-error.log
$ cat ls-error.log

Để nối dữ liệu vào cuối tệp, hãy sử dụng cùng một ký hiệu:

ls -l /root/ 2>>ls-error.log

Chuyển hướng đầu ra tiêu chuẩn và lỗi sang tập tin

Bạn cũng có thể chuyển hướng tất cả đầu ra, lỗi và đầu ra tiêu chuẩn sang một tệp duy nhất. Có hai cách để làm điều này. Cách đầu tiên, cũ hơn là chuyển cả hai tay cầm:

ls -l /root/ >ls-error.log 2>&1

Đầu tiên, đầu ra của lệnh ls sẽ được gửi đến tệp ls-error.log bằng ký tự chuyển hướng đầu tiên. Sau đó tất cả các lỗi sẽ được gửi đến cùng một tập tin. Phương pháp thứ hai đơn giản hơn:

ls -l /root/ &> ls-error.log

Bạn cũng có thể sử dụng tính năng nối thêm thay vì viết lại:

ls -l /root/ &>> ls-error.log

Đầu vào tiêu chuẩn từ tập tin

Hầu hết các chương trình, ngoại trừ dịch vụ, nhận dữ liệu cho công việc của chúng thông qua đầu vào tiêu chuẩn. Theo mặc định, đầu vào tiêu chuẩn yêu cầu đầu vào từ bàn phím. Nhưng bạn có thể buộc chương trình đọc dữ liệu từ một tệp bằng toán tử "<" :

con mèo

Bạn cũng có thể ngay lập tức chuyển hướng đầu ra sang một tệp. Ví dụ: hãy sắp xếp lại danh sách:

loại sắp xếp.output

Vì vậy, chúng tôi chuyển hướng đầu vào/đầu ra sang linux bằng một lệnh.

Sử dụng đường hầm

Bạn có thể làm việc không chỉ với các tệp mà còn có thể chuyển hướng đầu ra của một lệnh thành đầu vào của lệnh khác. Điều này rất hữu ích để thực hiện các hoạt động phức tạp. Ví dụ: hãy hiển thị năm tệp được sửa đổi gần đây:

ls -lt | đầu -n 5

Với tiện ích xargs, bạn có thể kết hợp các lệnh để đầu vào tiêu chuẩn được truyền dưới dạng tham số. Ví dụ: hãy sao chép một tệp vào một số thư mục:

kiểm tra tiếng vang/tmp/ | xargs -n 1 cp -v testfile.sh

Ở đây, tùy chọn -n 1 chỉ định rằng chỉ nên cung cấp một tham số cho mỗi lệnh và tùy chọn -v cho cp cho phép in thông tin chi tiết về các chuyển động. Một lệnh hữu ích khác trong những trường hợp như vậy là tee. Nó đọc dữ liệu từ đầu vào tiêu chuẩn và ghi vào đầu ra hoặc tập tin tiêu chuẩn. Ví dụ:

echo "Thử nghiệm hoạt động của Tee" | tập tin tee1

Kết hợp với các lệnh khác, chúng có thể được sử dụng để tạo các lệnh đa lệnh phức tạp.

kết luận

Trong bài viết này, chúng tôi đã trình bày các khái niệm cơ bản về chuyển hướng luồng I/O của Linux. Bây giờ bạn đã biết cách chuyển hướng đầu ra sang tệp linux hoặc đầu ra từ một tệp. Nó rất đơn giản và thuận tiện. Nếu bạn có bất kỳ câu hỏi nào, hãy hỏi trong phần bình luận!

Khả năng chuyển hướng tích hợp của Linux cung cấp cho bạn nhiều công cụ đơn giản hóa cho mọi loại tác vụ. Khả năng quản lý các luồng I/O khác nhau sẽ tăng năng suất đáng kể, cả khi phát triển phần mềm phức tạp và khi quản lý tệp bằng dòng lệnh.

Chủ đề I/O

Đầu vào và đầu ra trong môi trường Linux được phân phối giữa ba luồng:

  • Đầu vào tiêu chuẩn (đầu vào tiêu chuẩn, stdin, số luồng 0)
  • Đầu ra tiêu chuẩn (thiết bị xuất chuẩn, số 1)
  • Lỗi tiêu chuẩn hoặc luồng chẩn đoán (lỗi tiêu chuẩn, stderr, số 2)

Khi người dùng tương tác với thiết bị đầu cuối, đầu vào tiêu chuẩn sẽ được truyền qua bàn phím của người dùng. Đầu ra tiêu chuẩn và lỗi tiêu chuẩn được hiển thị dưới dạng văn bản trên thiết bị đầu cuối của người dùng. Tất cả ba luồng này được gọi là luồng tiêu chuẩn.

Đầu vào tiêu chuẩn

Luồng đầu vào tiêu chuẩn thường truyền dữ liệu từ người dùng đến chương trình. Các chương trình yêu cầu đầu vào tiêu chuẩn thường nhận đầu vào từ một thiết bị (chẳng hạn như bàn phím). Đầu vào tiêu chuẩn dừng khi đạt đến EOF (cuối tập tin). EOF chỉ ra rằng không còn dữ liệu để đọc.

Để xem cách nhập tiêu chuẩn hoạt động như thế nào, hãy chạy chương trình cat. Tên của công cụ này có nghĩa là “nối” (để kết nối hoặc kết hợp một cái gì đó). Thông thường công cụ này được sử dụng để kết hợp nội dung của hai tệp. Khi chạy không có đối số, cat sẽ mở dấu nhắc lệnh và chấp nhận nội dung của đầu vào tiêu chuẩn.

Bây giờ hãy nhập một số số:

1
2
3
ctrl-d

Bằng cách nhập một số và nhấn enter, bạn gửi đầu vào tiêu chuẩn tới chương trình mèo đang chạy để chấp nhận dữ liệu. Ngược lại, chương trình cat hiển thị đầu vào nhận được trên đầu ra tiêu chuẩn.

Người dùng có thể đặt EOF bằng cách nhấn ctrl-d, thao tác này sẽ khiến chương trình cat dừng lại.

Đầu ra tiêu chuẩn

Đầu ra tiêu chuẩn ghi lại dữ liệu do chương trình tạo ra. Nếu đầu ra tiêu chuẩn chưa được chuyển hướng, nó sẽ xuất văn bản tới thiết bị đầu cuối. Hãy thử chạy lệnh sau làm ví dụ:

echo Gửi đến thiết bị đầu cuối thông qua đầu ra tiêu chuẩn

Lệnh echo, không có bất kỳ tùy chọn bổ sung nào, hiển thị trên màn hình tất cả các đối số được truyền cho nó trên dòng lệnh.

Bây giờ hãy chạy echo mà không có bất kỳ đối số nào:

Lệnh sẽ trả về một chuỗi trống.

Lỗi tiêu chuẩn

Luồng tiêu chuẩn này ghi lại các lỗi do một chương trình bị lỗi tạo ra. Giống như đầu ra tiêu chuẩn, luồng này gửi dữ liệu đến thiết bị đầu cuối.

Hãy xem một ví dụ về luồng lỗi lệnh ls. Lệnh ls hiển thị nội dung của các thư mục.

Không có đối số, lệnh này trả về nội dung của thư mục hiện tại. Nếu bạn cung cấp tên thư mục làm đối số cho ls, lệnh sẽ trả về nội dung của nó.

Vì thư mục % không tồn tại nên lệnh sẽ trả về lỗi tiêu chuẩn:

ls: không thể truy cập %: Không có tập tin hoặc thư mục như vậy

Chuyển hướng luồng

Linux cung cấp các lệnh đặc biệt để chuyển hướng từng luồng. Các lệnh này ghi đầu ra tiêu chuẩn vào một tập tin. Nếu đầu ra được chuyển hướng đến một tệp không tồn tại, lệnh sẽ tạo một tệp mới có tên đó và lưu đầu ra được chuyển hướng vào đó.

Các lệnh có một dấu ngoặc nhọn sẽ ghi đè lên nội dung hiện có của tệp đích:

  • > - đầu ra tiêu chuẩn
  • < — стандартный ввод
  • 2> - lỗi tiêu chuẩn

Các lệnh có dấu ngoặc nhọn không ghi đè lên nội dung của tệp đích:

  • >> - đầu ra tiêu chuẩn
  • << — стандартный ввод
  • 2>> - lỗi tiêu chuẩn

Hãy xem xét ví dụ sau:

con mèo > write_to_me.txt
Một
b
c
ctrl-d

Ví dụ này sử dụng lệnh cat để ghi kết quả đầu ra vào một tệp.

Xem lại nội dung của write_to_me.txt:

mèo write_to_me.txt

Lệnh sẽ trả về:

Chuyển hướng cat đến write_to_me.txt một lần nữa và nhập ba số.

con mèo > write_to_me.txt
1
2
3
ctrl-d

Bây giờ hãy kiểm tra nội dung của tập tin.

mèo write_to_me.txt

Lệnh sẽ trả về:

Như bạn có thể thấy, tệp chỉ chứa đầu ra mới nhất vì lệnh chuyển hướng đầu ra đã sử dụng một dấu ngoặc nhọn.

Bây giờ hãy thử chạy lệnh tương tự với hai dấu ngoặc nhọn:

con mèo >> write_to_me.txt
Một
b
c
ctrl-d

Mở write_to_me.txt:

1
2
3
Một
b
c

Các lệnh có dấu ngoặc nhọn không ghi đè lên nội dung hiện có mà chỉ thêm vào nội dung đó.

Băng tải

Các ống chuyển hướng đầu ra của một lệnh này sang đầu vào của lệnh khác. Trong trường hợp này, dữ liệu được truyền sang chương trình thứ hai không được hiển thị trong thiết bị đầu cuối. Dữ liệu sẽ chỉ xuất hiện trên màn hình sau khi được chương trình thứ hai xử lý.

Các đường dẫn trong Linux được biểu thị bằng một thanh dọc.

Ví dụ:

Lệnh này sẽ chuyển đầu ra của ls (nội dung của thư mục hiện tại) sang less, lệnh này sẽ hiển thị dữ liệu được truyền đến nó theo từng dòng. Thông thường, ls hiển thị nội dung của các thư mục một cách liên tục mà không chia chúng thành dòng. Nếu bạn chuyển hướng đầu ra ls sang less, lệnh sau sẽ chia đầu ra thành các dòng.

Như bạn có thể thấy, một đường dẫn có thể chuyển hướng đầu ra của một lệnh sang đầu vào của lệnh khác, không giống như > và >> chỉ chuyển hướng dữ liệu đến các tệp.

Bộ lọc

Bộ lọc là các lệnh có thể thay đổi chuyển hướng và đầu ra của đường ống.

Ghi chú: Bộ lọc cũng là các lệnh Linux tiêu chuẩn có thể được sử dụng mà không cần đường dẫn.

  • find – tìm kiếm một tập tin theo tên.
  • grep – tìm kiếm văn bản bằng một mẫu nhất định.
  • tee – chuyển hướng đầu vào tiêu chuẩn sang đầu ra tiêu chuẩn và một hoặc nhiều tệp.
  • tr – tìm kiếm và thay thế chuỗi.
  • wc – đếm ký tự, dòng và từ.

Ví dụ về chuyển hướng I/O

Bây giờ bạn đã quen với các khái niệm và cơ chế chuyển hướng cơ bản, hãy xem một số ví dụ cơ bản về cách sử dụng chúng.

lệnh> tập tin

Mẫu này chuyển hướng đầu ra tiêu chuẩn của lệnh tới một tệp.

ls ~> root_dir_contents.txt

Lệnh này chuyển nội dung của thư mục gốc của hệ thống dưới dạng đầu ra tiêu chuẩn và ghi đầu ra vào tệp root_dir_contents. Thao tác này sẽ xóa tất cả nội dung trước đó trong tệp vì lệnh sử dụng một dấu ngoặc nhọn.

lệnh>/dev/null

/dev/null là một tệp đặc biệt (được gọi là "thiết bị null") được sử dụng để ngăn chặn đầu ra tiêu chuẩn hoặc chẩn đoán nhằm tránh đầu ra bảng điều khiển không mong muốn. Tất cả dữ liệu kết thúc bằng /dev/null sẽ bị loại bỏ. Chuyển hướng đến /dev/null thường được sử dụng trong các tập lệnh shell.

ls > /dev/null

Lệnh này đặt lại đầu ra tiêu chuẩn được ls trả về thành /dev/null.

lệnh 2> tập tin

Mẫu này chuyển hướng luồng lỗi tiêu chuẩn của lệnh tới một tệp, ghi đè nội dung hiện tại của nó.

mkdir "" 2> mkdir_log.txt

Lệnh này sẽ chuyển hướng lỗi do tên thư mục không hợp lệ gây ra và ghi nó vào log.txt. Xin lưu ý: lỗi vẫn xuất hiện trong terminal.

lệnh >> tập tin

Mẫu này chuyển hướng đầu ra tiêu chuẩn của lệnh sang tệp mà không ghi đè nội dung hiện tại của tệp.

echo Được ghi vào một tệp mới > data.txt
echo Đã thêm vào nội dung của tệp hiện có >> data.txt

Cặp lệnh này trước tiên chuyển hướng đầu vào của người dùng sang một tệp mới, sau đó dán nó vào một tệp hiện có mà không ghi đè lên nội dung của nó.

lệnh 2>>tập tin

Mẫu này chuyển hướng luồng lỗi tiêu chuẩn của lệnh tới một tệp mà không ghi đè lên nội dung hiện có của tệp. Nó phù hợp để tạo nhật ký lỗi chương trình hoặc dịch vụ vì nội dung nhật ký sẽ không được cập nhật liên tục.

tìm "" 2> stderr_log.txt
wc "" 2>> stderr_log.txt

Lệnh trên chuyển hướng thông báo lỗi do đối số find không hợp lệ gây ra vào tệp stderr_log.txt và sau đó nối thêm thông báo lỗi do đối số wc không hợp lệ gây ra vào tệp stderr_log.txt.

đội | đội

Mẫu này chuyển hướng đầu ra tiêu chuẩn của lệnh đầu tiên tới đầu vào tiêu chuẩnđội thứ hai.

tìm /var lib | lỗi grep

Lệnh này tìm kiếm thư mục /var và các thư mục con của nó để tìm tên tệp và phần mở rộng gỡ lỗi, đồng thời trả về đường dẫn tệp, đánh dấu mẫu tìm kiếm bằng màu đỏ.

đội | tập tin tee

Mẫu này chuyển hướng đầu ra tiêu chuẩn của lệnh sang một tệp và ghi đè nội dung của nó, sau đó hiển thị đầu ra được chuyển hướng trong thiết bị đầu cuối. Nếu tệp được chỉ định không tồn tại, nó sẽ tạo một tệp mới.

TRONG mẫu này Lệnh tee thường được sử dụng để xem đầu ra của chương trình và lưu nó vào một tệp cùng một lúc.

wc /etc/magic | tee magic_count.txt

Lệnh này chuyển số lượng ký tự, dòng và từ trong tập tin ma thuật(Linux sử dụng điều này để xác định loại tệp) tới lệnh tee, lệnh này sẽ gửi dữ liệu này đến thiết bị đầu cuối và tới tệp magic_count.txt.

đội | đội | lệnh >> tập tin

Mẫu này chuyển hướng đầu ra tiêu chuẩn của lệnh đầu tiên và lọc nó qua hai lệnh tiếp theo, sau đó nối kết quả cuối cùng vào một tệp.

ls ~ | grep *tar | tr e E >> ls_log.txt

Lệnh này gửi đầu ra của ls cho thư mục gốc tới grep. Đổi lại, grep tìm kiếm dữ liệu nhận được tập tin tar. Sau đó, kết quả của grep được chuyển tới lệnh tr, lệnh này sẽ thay thế tất cả các ký tự e bằng ký tự E. Kết quả thu được sẽ được thêm vào tệp ls_log.txt (nếu tệp đó không tồn tại, lệnh sẽ tạo nó tự động).

Phần kết luận

Lúc đầu, các chức năng chuyển hướng I/O của Linux có vẻ quá phức tạp. Tuy nhiên, làm việc với chuyển hướng là một trong những kỹ năng quan trọng nhất của quản trị viên hệ thống.

Để tìm hiểu thêm về một lệnh cụ thể, hãy sử dụng:

lệnh người đàn ông | ít hơn

Ví dụ:

Lệnh này sẽ trở lại danh sách đầy đủ lệnh cho tee.

thẻ:

Học Linux, 101

Luồng, kênh chương trình và chuyển hướng

Tìm hiểu những điều cơ bản về đường ống Linux

Chuỗi nội dung:

Đánh giá ngắn

Trong bài viết này, bạn sẽ tìm hiểu các kỹ thuật cơ bản để chuyển hướng các luồng I/O tiêu chuẩn trong Linux. Bạn sẽ học:

  • Chuyển hướng các luồng đầu vào/đầu ra tiêu chuẩn: đầu vào tiêu chuẩn, đầu ra tiêu chuẩn và lỗi tiêu chuẩn.
  • Hướng đầu ra của một lệnh tới đầu vào của lệnh khác.
  • Gửi đầu ra đồng thời tới thiết bị tiêu chuẩnđầu ra (thiết bị xuất chuẩn) và vào một tập tin.
  • Sử dụng đầu ra của lệnh làm đối số cho lệnh khác.

Bài viết này sẽ giúp bạn chuẩn bị tham dự kỳ thi LPI 101 Administrator cấp độ đầu vào(LPIC-1) và chứa các tài liệu từ Mục tiêu 103.4 của Chủ đề 103. Mục tiêu có trọng số là 4.

Về loạt bài này

Chuỗi bài viết này sẽ giúp bạn nắm vững các công việc quản trị hệ điều hành Linux. Bạn cũng có thể sử dụng tài liệu trong các bài viết này để chuẩn bị.

Để xem mô tả các bài viết trong loạt bài này và nhận liên kết đến chúng, vui lòng tham khảo trang web của chúng tôi. Danh sách này được cập nhật liên tục với các bài viết mới khi chúng có sẵn và bao gồm các mục tiêu thi chứng chỉ LPIC-1 mới nhất (tính đến tháng 4 năm 2009). Nếu thiếu bài viết nào trong danh sách, bạn có thể tìm thêm phiên bản trước đó, nhất quán với các mục tiêu LPIC-1 trước đây (trước tháng 4 năm 2009), bằng cách tham khảo .

Các điều kiện cần thiết

Để giải nen lợi ích lớn nhất từ các bài viết của chúng tôi, bạn cần có kiến ​​thức cơ bản về Linux và có một máy tính Linux đang hoạt động để bạn có thể thực thi tất cả các lệnh bạn gặp phải. Thỉnh thoảng phiên bản khác nhau Các chương trình tạo ra kết quả khác nhau nên nội dung của danh sách và số liệu có thể khác với những gì bạn thấy trên máy tính.

Chuẩn bị chạy các ví dụ

Làm thế nào để liên hệ với Ian

Ian là một trong những tác giả nổi tiếng và có nhiều tác phẩm nhất của chúng tôi. Kiểm tra (EN) được xuất bản trên devWorks. Bạn có thể tìm thấy thông tin liên hệ tại và kết nối với anh ấy cũng như những cộng tác viên và cộng tác viên DeveloperWorks khác của tôi.

Để chạy các ví dụ trong bài viết này, chúng tôi sẽ sử dụng một số tệp được tạo trước đó trong bài viết " ". Nếu bạn chưa đọc bài viết này hoặc chưa lưu những tập tin này, đừng lo lắng! Hãy bắt đầu bằng cách tạo một thư mục mới lpi103-4 và tất cả tập tin cần thiết. Để thực hiện việc này, hãy mở một cửa sổ văn bản và điều hướng đến thư mục chính của bạn. Sao chép nội dung của Liệt kê 1 vào hộp văn bản; là kết quả của việc thực hiện các lệnh trong thư mục chính Thư mục con lpi103-4 sẽ được tạo và tất cả các tệp cần thiết trong đó mà chúng tôi sẽ sử dụng trong các ví dụ của mình.

Liệt kê 1. Tạo các tệp cần thiết cho các ví dụ của bài viết này
mkdir -p lpi103-4 && cd lpi103-4 && ( echo -e "1 apple\n2 lê\n3 chuối" > text1 echo -e "9\tplum\n3\tbanana\n10\tapple" > text2 echo "Đây là một câu " !#:* !#:1->text3 chia -l 2 text1 chia -b 17 text2 y; )

Cửa sổ của bạn sẽ trông giống như Liệt kê 2 và thư mục làm việc hiện tại của bạn sẽ là thư mục lpi103-4 mới được tạo.

Liệt kê 2. Kết quả của việc tạo các tệp cần thiết
$ mkdir -p lpi103-4 && cd lpi103-4 && ( > echo -e "1 apple\n2 lê\n3 chuối" > text1 > echo -e "9\tplum\n3\tbanana\n10\tapple"> text2 > echo "Đây là một câu." !#:* !#:1->text3echo "Đây là một câu." "Đây là một câu."">text3 > chia -l 2 text1 > chia -b 17 văn bản2 y ) $

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

Một hệ vỏ Linux, chẳng hạn như Bash, nhận đầu vào và gửi đầu ra dưới dạng các chuỗi hoặc dòng nhân vật. Bất kỳ ký tự nào đều độc lập với các ký tự trước hoặc sau. Các ký hiệu không được tổ chức thành các mục có cấu trúc hoặc các khối có kích thước cố định. Các luồng được truy cập bằng cơ chế I/O bất kể luồng ký tự đến từ đâu hoặc được gửi đến (tệp, bàn phím, cửa sổ, màn hình hoặc thiết bị I/O khác). Trình thông dịch lệnh Linux sử dụng ba luồng I/O tiêu chuẩn, mỗi luồng được gán một địa chỉ cụ thể mô tả tập tin.

  1. thiết bị xuất chuẩnđầu ra tiêu chuẩn, hiển thị đầu ra lệnh và có số xử lý 1.
  2. lỗi chuẩnluồng lỗi tiêu chuẩn, hiển thị lỗi lệnh và có mô tả 2.
  3. stdinđầu vào tiêu chuẩn, chuyển đầu vào cho các lệnh và có số xử lý là 0.

Luồng đầu vào cung cấp đầu vào (thường là từ bàn phím) cho các lệnh. Luồng đầu ra cung cấp khả năng in ký tự văn bản, thường là đến thiết bị đầu cuối. Thiết bị đầu cuối ban đầu là thiết bị in ASCII hoặc thiết bị đầu cuối hiển thị, nhưng bây giờ nó thường chỉ là một cửa sổ trên màn hình máy tính.

Nếu bạn đã đọc hướng dẫn "", thì một số tài liệu trong bài viết này sẽ quen thuộc với bạn.

Chuyển hướng đầu ra

Có hai cách để chuyển hướng đầu ra sang một tệp:

N> chuyển hướng đầu ra từ một bộ mô tả tập tin N nộp. Bạn phải có quyền ghi vào tập tin. Nếu tập tin không tồn tại, nó sẽ được tạo. Nếu tệp tồn tại thì tất cả nội dung của nó thường bị hủy mà không có bất kỳ cảnh báo nào. N>> cũng chuyển hướng đầu ra từ bộ mô tả tập tin N nộp. Bạn cũng phải có quyền ghi vào tập tin. Nếu tập tin không tồn tại, nó sẽ được tạo. Nếu tệp tồn tại, đầu ra sẽ được thêm vào nội dung của nó.

Biểu tượng N trong toán tử n> hoặc n>> là mô tả tập tin. Nếu nó không được chỉ định thì thiết bị đầu ra tiêu chuẩn được coi là được sử dụng. Liệt kê 3 thể hiện hoạt động chuyển hướng để phân tách đầu ra tiêu chuẩn và lỗi tiêu chuẩn của lệnh ls, sử dụng các tệp đã được tạo trước đó trong thư mục lpi103-4. Cũng được chứng minh là thêm đầu ra lệnh vào các tệp hiện có.

Liệt kê 3. Chuyển hướng đầu ra
$ ls x* z* ls: không thể truy cập z*: Không có tệp hoặc thư mục như vậy xaa xab $ ls x* z* >stdout.txt 2>stderr.txt $ ls w* y* ls: không thể truy cập w*: Không như vậy tập tin hoặc thư mục yaa yab $ ls w* y* >>stdout.txt 2>>stderr.txt $ cat stdout.txt xaa xab yaa yab $ cat stderr.txt ls: không thể truy cập z*: Không có tập tin hoặc thư mục như vậy ls: không thể truy cập w*: Không có tập tin hoặc thư mục như vậy

Chúng tôi đã nói rằng việc chuyển hướng đầu ra bằng toán tử n> thường dẫn đến việc ghi đè tập tin hiện có. Bạn có thể kiểm soát thuộc tính này bằng cách sử dụng tùy chọn noclobber của lệnh tích hợp sẵn. Nếu tùy chọn này được xác định, bạn có thể ghi đè nó bằng toán tử n>|, như trong Liệt kê 4.

Liệt kê 4. Chuyển hướng đầu ra bằng tùy chọn noclobber
$ set -o noclobber $ ls x* z* >stdout.txt 2>stderr.txt -bash: stdout.txt: không thể ghi đè lên tập tin hiện có $ ls x* z* >|stdout.txt 2>|stderr.txt $ cat stdout.txt xaa xab $ cat stderr.txt ls: không thể truy cập z*: Không có tệp hoặc thư mục như vậy $ set +o noclobber #restore cài đặt noclobber gốc

Đôi khi bạn có thể muốn chuyển hướng cả đầu ra tiêu chuẩn và lỗi tiêu chuẩn sang một tệp. Điều này thường được sử dụng trong các quy trình tự động hoặc công việc nềnđể bạn có thể xem kết quả công việc của mình sau này. Để chuyển hướng đầu ra tiêu chuẩn và lỗi tiêu chuẩn đến cùng một vị trí, hãy sử dụng toán tử &> hoặc &>>. Lựa chọn thay thế– mô tả tập tin chuyển hướng N và sau đó là bộ mô tả tập tin tôiđến cùng một nơi bằng cách sử dụng cấu trúc m>&n hoặc m>>&n. Trong trường hợp này, thứ tự chuyển hướng các luồng là quan trọng. Ví dụ, lệnh
lệnh 2>&1 >output.txt
nó không giống như một mệnh lệnh
lệnh >output.txt 2>&1
Trong trường hợp đầu tiên, luồng lỗi stderr được chuyển hướng đến vị trí hiện tại của luồng stdout và sau đó luồng stdout được chuyển hướng đến tệp đầu ra.txt; tuy nhiên, chuyển hướng thứ hai chỉ ảnh hưởng đến thiết bị xuất chuẩn chứ không ảnh hưởng đến thiết bị xuất chuẩn. Trong trường hợp thứ hai, luồng stderr được chuyển hướng đến vị trí hiện tại của luồng stdout, tức là tới tệp đầu ra.txt. Những chuyển hướng này được minh họa trong Liệt kê 5. Lưu ý trong lệnh cuối cùng rằng đầu ra tiêu chuẩn đã được chuyển hướng sau luồng lỗi tiêu chuẩn và kết quả là luồng lỗi tiếp tục được xuất ra cửa sổ đầu cuối.

Liệt kê 5. Chuyển hướng hai luồng sang một tệp
$ ls x* z* &>output.txt $ cat output.txt ls: không thể truy cập z*: Không có tệp hoặc thư mục như vậy xaa xab $ ls x* z* >output.txt 2>&1 $ cat out.txt ls: không thể truy cập z*: Không có tập tin hoặc thư mục như vậy xaa xab $ ls x* z* 2>&1 >output.txt # stderr không đi đến đầu ra.txt ls: không thể truy cập z*: Không có tập tin hoặc thư mục như vậy $ cat đầu ra. txt xaa xab

Trong các tình huống khác, bạn có thể muốn bỏ qua hoàn toàn đầu ra tiêu chuẩn hoặc lỗi tiêu chuẩn. Để thực hiện việc này, hãy chuyển hướng chuỗi tương ứng tới tệp tin rỗng/dev/null. Liệt kê 6 cho thấy cách bỏ qua luồng lỗi lệnh ls và cách sử dụng lệnh mèođảm bảo rằng tệp /dev/null thực sự trống.

Liệt kê 6. Bỏ qua lỗi tiêu chuẩn bằng cách sử dụng /dev/null
$ ls x* z* 2>/dev/null xaa xab $ cat /dev/null

Chuyển hướng đầu vào

Giống như chúng ta có thể chuyển hướng stdout và stderr, chúng ta có thể chuyển hướng stdin từ một tệp bằng toán tử<. Если вы прочли руководство " ", то должны помнить, что в разделе была использована команда tr для замены пробелов в файле text1 на символы табуляции. В том примере мы использовали вывод команды cat чтобы создать стандартный поток ввода для команды tr . Теперь для преобразования пробелов в символы табуляции вместо бесполезного вызова команды cat мы можем использовать перенаправление ввода, как показано в листинге 7.

Liệt kê 7. Chuyển hướng đầu vào
$ tr " " "\t"

Trình thông dịch lệnh, bao gồm cả bash, triển khai khái niệm này tài liệu ở đây, đây là một trong những cách để chuyển hướng đầu vào. Nó sử dụng thiết kế<< и какое-либо слово, например END, являющееся маркером, или сигнальной меткой, означающей конец ввода. Эта концепция продемонстрирована в листинге 8.

Liệt kê 8. Chuyển hướng đầu vào bằng cách sử dụng khái niệm here-document
$sắp xếp -k2<1 quả táo > 2 quả lê > 3 quả chuối > KẾT THÚC 1 quả táo 3 quả chuối 2 quả lê

Nhưng tại sao bạn không thể gõ lệnh Sort -k2, nhập dữ liệu và nhấn tổ hợp Ctrl-d, cho biết sự kết thúc của đầu vào? Tất nhiên, bạn có thể chạy lệnh này, nhưng khi đó bạn sẽ không biết về khái niệm tài liệu ở đây, rất phổ biến trong các tập lệnh shell (trong đó không có cách nào khác để chỉ định dòng nào sẽ được chấp nhận làm đầu vào). Vì các tab được sử dụng rộng rãi trong các tập lệnh để căn chỉnh văn bản và làm cho chúng dễ đọc hơn nên có một kỹ thuật khác để sử dụng khái niệm tài liệu ở đây. Khi sử dụng toán tử<<- вместо оператора << начальные символы табуляции удаляются.

Trong Liệt kê 9, chúng tôi đã sử dụng tính năng thay thế lệnh để tạo một ký tự tab và sau đó tạo một tập lệnh shell nhỏ chứa hai lệnh cat, mỗi lệnh đọc dữ liệu từ khối tài liệu ở đây. Lưu ý rằng chúng tôi đã sử dụng từ END để báo hiệu khối tài liệu ở đây mà chúng tôi đang đọc từ thiết bị đầu cuối. Nếu chúng tôi sử dụng cùng từ này trong tập lệnh của mình, dữ liệu nhập của chúng tôi sẽ kết thúc sớm. Do đó, thay vì từ END, chúng tôi sử dụng từ EOF trong tập lệnh. Khi tập lệnh của chúng tôi được tạo, chúng tôi sử dụng lệnh. (dấu chấm) để chạy nó trong ngữ cảnh của shell hiện tại.

Liệt kê 9. Chuyển hướng đầu vào bằng cách sử dụng khái niệm here-document
$ ht=$(echo -en "\t") $ cat<ex-here.sh > con mèo<<-EOF >apple > EOF > $(ht)cat<<-EOF >$(ht)pear > $(ht)EOF > END $ cat ex-here.sh cat<<-EOF apple EOF cat <<-EOF pear EOF $ . ex-here.sh apple pear

Trong các bài viết tiếp theo của loạt bài này, bạn sẽ tìm hiểu thêm về thay thế lệnh và viết kịch bản. Liên kết tới tất cả các bài viết trong loạt bài này có thể được tìm thấy trong.

Tạo đường ống

Sử dụng lệnh xargs

Lệnh xargs đọc dữ liệu từ thiết bị đầu vào tiêu chuẩn, sau đó xây dựng và thực thi các lệnh lấy đầu vào nhận được làm tham số. Nếu không có lệnh nào được chỉ định thì lệnh echo sẽ được sử dụng. Liệt kê 12 cho thấy một ví dụ đơn giản về cách sử dụng tệp text1 của chúng tôi, tệp này chứa ba dòng, mỗi dòng có hai từ.

Liệt kê 12. Cách sử dụng lệnh xargs
$ cat text1 1 quả táo 2 quả lê 3 quả chuối $ xargs

Tại sao đầu ra xargs chỉ chứa một dòng? Theo mặc định, xargs sẽ phân chia đầu vào nếu nó gặp các ký tự phân cách và mỗi đoạn kết quả sẽ trở thành một tham số riêng. Tuy nhiên, khi xargs xây dựng một lệnh, nó sẽ được truyền nhiều tham số nhất có thể cùng một lúc. Hành vi này có thể được thay đổi bằng cách sử dụng tùy chọn –n hoặc --max-args. Liệt kê 13 cho thấy một ví dụ về cả hai tùy chọn; một lệnh gọi rõ ràng tới lệnh echo cũng được thực hiện để sử dụng với xargs.

Liệt kê 13. Sử dụng lệnh xargs và echo
$xargs " args > 1 quả táo 2 quả lê 3 quả chuối $ xargs --max-args 3 " args > 1 quả táo 2 args > quả lê 3 quả chuối $ xargs -n 1 " args > 1 args > apple args > 2 args > lê args > 3 args > chuối

Nếu dữ liệu đầu vào chứa khoảng trắng nhưng chúng được đặt trong một hoặc dấu ngoặc kép(hoặc khoảng trắng được biểu diễn dưới dạng chuỗi thoát bằng dấu gạch chéo ngược), khi đó xargs sẽ không chia chúng thành các phần riêng biệt. Điều này được thể hiện trong Liệt kê 14.

Liệt kê 14. Sử dụng lệnh xargs và dấu ngoặc kép
$ echo ""4 mận"" | cat text1 - 1 quả táo 2 quả lê 3 quả chuối "4 quả mận" $ echo ""4 quả mận"" | văn bản mèo1 - | xargs -n 1 1 quả táo 2 quả lê 3 quả chuối 4 quả mận

Cho đến bây giờ, tất cả các đối số đã được thêm vào cuối lệnh. Nếu bạn cần thêm các đối số tùy chọn khác vào sau chúng, hãy sử dụng tùy chọn -I để chỉ định chuỗi thay thế. Tại thời điểm trong lệnh được gọi thông qua xargs nơi chuỗi thay thế được sử dụng, thay vào đó, một đối số sẽ được thay thế. Với cách tiếp cận này, chỉ có một đối số được truyền cho mỗi lệnh. Tuy nhiên, đối số sẽ được tạo từ toàn bộ chuỗi đầu vào chứ không phải từ một đoạn riêng biệt của chuỗi đó. Bạn cũng có thể sử dụng tùy chọn -L của lệnh xargs, điều này sẽ khiến toàn bộ chuỗi được sử dụng làm đối số thay vì các phần riêng lẻ được phân tách bằng dấu cách. Việc sử dụng tùy chọn -I ngầm khiến tùy chọn -L 1 được sử dụng. Liệt kê 15 cho thấy các ví dụ về cách sử dụng các tùy chọn -I và –L.

Liệt kê 15. Sử dụng lệnh xargs và các dòng đầu vào
$ xargs -I XYZ echo "BẮT ĐẦU XYZ LẶP LẠI XYZ KẾT THÚC" " <9 plum> <3 banana><3 banana> <10 apple><10 apple>$ văn bản mèo1 văn bản2 | xargs -L2 1 quả táo 2 quả lê 3 quả chuối 9 quả mận 3 quả chuối 10 quả táo

Mặc dù các ví dụ của chúng tôi sử dụng các tệp văn bản đơn giản nhưng bạn sẽ không thường xuyên sử dụng lệnh xargs cho những trường hợp như vậy. Thông thường, bạn sẽ xử lý một danh sách lớn các tệp được tạo ra từ các lệnh như ls , find hoặc grep . Liệt kê 16 cho thấy một cách để chuyển xargs danh sách nội dung của một thư mục tới một lệnh như grep.

Liệt kê 16. Sử dụng lệnh xargs và danh sách tệp
$ ls |xargs grep "1" text1:1 apple text2:10 apple xaa:1 apple yaa:1

Trong ví dụ trước, điều gì xảy ra nếu một hoặc nhiều tên tệp chứa dấu cách? Nếu bạn cố gắng sử dụng lệnh như trong Liệt kê 16, bạn sẽ gặp lỗi. Trong tình huống thực tế, danh sách các tệp có thể không được lấy từ lệnh ls, nhưng, ví dụ, do thực thi tập lệnh hoặc lệnh của người dùng; hoặc bạn có thể muốn xử lý nó ở các giai đoạn khác trong quy trình để lọc bổ sung. Vì vậy, chúng tôi không tính đến thực tế là bạn có thể chỉ cần sử dụng grep "1" * thay vì cấu trúc logic hiện có.

Trong trường hợp lệnh ls, bạn có thể sử dụng tùy chọn --quoting-style để buộc tên tệp chứa khoảng trắng được đặt trong dấu ngoặc đơn (hoặc thoát). Giải pháp tốt hơn (khi có thể) là sử dụng tùy chọn -0 của lệnh xargs, tùy chọn này khiến các ký tự trống (\0) được sử dụng để phân tách các đối số đầu vào. Mặc dù lệnh ls không có tùy chọn sử dụng tên tệp kết thúc bằng null làm đầu ra nhưng nhiều lệnh có thể thực hiện việc này.

Trong Liệt kê 17, trước tiên chúng ta sẽ sao chép tệp text1 sang "text 1" và sau đó đưa ra một số ví dụ về cách sử dụng danh sách tên tệp chứa khoảng trắng bằng lệnh xargs. Những ví dụ này giúp bạn hiểu ý tưởng vì có thể không dễ dàng để nắm vững hoàn toàn xargs. Đặc biệt, ví dụ cuối cùng về chuyển đổi dòng mới thành ký tự trống sẽ không hoạt động nếu một số tên tệp đã chứa dòng mới. Trong phần tiếp theo của bài viết này, chúng ta sẽ xem xét một giải pháp mạnh mẽ hơn, sử dụng lệnh find để tạo đầu ra phù hợp sử dụng các ký tự null làm dấu phân cách.

Liệt kê 17. Sử dụng lệnh xargs và các tệp chứa khoảng trắng trong tên của chúng
$ cp text1 "text 1" $ ls *1 |xargs grep "1" # error text1:1 apple grep: text: Không có tập tin hoặc thư mục như vậy grep: 1: Không có tập tin hoặc thư mục như vậy $ ls --quoting-style escape * 1 text1 text\ 1 $ ls -- shell kiểu trích dẫn *1 text1 "text 1" $ ls -- shell kiểu trích dẫn *1 |xargs grep "1" text1:1 apple text 1:1 apple $ # Minh họa -0 tùy chọn xargs $ ls *1 | tr "\n" "\0" |xargs -0 grep "1" text1:1 apple text 1:1 apple

Lệnh xargs không thể xây dựng các lệnh dài tùy ý. Do đó, trong Linux, cho đến phiên bản kernel 2.26.3, độ dài lệnh tối đa bị giới hạn. Nếu bạn cố chạy một lệnh như rm somepath/* và thư mục chứa nhiều tệp có tên dài, lệnh đó có thể không thành công với lỗi cho biết danh sách đối số quá dài. Nếu bạn đang chạy các phiên bản Linux hoặc UNIX cũ hơn có thể có những hạn chế này, thì có thể hữu ích nếu bạn biết cách sử dụng xargs theo cách khắc phục chúng.

Bạn có thể sử dụng tùy chọn --show-limits để xem giới hạn mặc định cho lệnh xargs và tùy chọn -s để đặt độ dài tối đa của đầu ra lệnh. Bạn có thể tìm hiểu về các tùy chọn khác từ trang man.

Sử dụng lệnh find với tùy chọn -exec hoặc kết hợp với lệnh xargs

Trong phần hướng dẫn " ", bạn đã học cách sử dụng lệnh find để tìm các tệp dựa trên tên, thời gian sửa đổi, kích thước và các đặc điểm khác của chúng. Thông thường, một số hành động nhất định phải được thực hiện trên các tệp được tìm thấy - xóa, sao chép, đổi tên chúng, v.v. Bây giờ chúng ta sẽ xem xét tùy chọn -exec của lệnh find, hoạt động tương tự như lệnh find và sau đó chuyển đầu ra sang lệnh xargs.

Liệt kê 18. Sử dụng tùy chọn find với -exec
$ tìm văn bản -exec cat text3()\; Đây la một câu. Đây la một câu. Đây la một câu. 1 quả táo 2 quả lê 3 quả chuối Đây là một câu. Đây la một câu. Đây la một câu. 9 quả mận 3 quả chuối 10 quả táo

So sánh kết quả của Liệt kê 18 với những gì bạn đã biết về xargs sẽ thấy một vài điểm khác biệt.

  1. Bạn phải sử dụng ký hiệu () trong lệnh để chỉ ra vị trí thay thế nơi tên tệp sẽ được thay thế. Những ký tự này không được tự động thêm vào cuối lệnh.
  2. Bạn phải kết thúc lệnh bằng dấu chấm phẩy, dấu chấm này phải được thoát (\;, ";" hoặc ";").
  3. Lệnh được thực thi một lần cho mỗi tệp đầu vào.

Hãy thử chạy find text |xargs cat text3 để thấy sự khác biệt.

Bây giờ chúng ta hãy quay lại trường hợp tên tệp chứa khoảng trắng. Trong Liệt kê 19, chúng tôi đã thử sử dụng lệnh find với tùy chọn -exec thay vì lệnh ls và xargs.

Liệt kê 19. Sử dụng lệnh find với tùy chọn -exec và các tệp chứa khoảng trắng trong tên của chúng
$ tìm. -name "*1" -exec grep "1" () \; 1 quả táo 1 quả táo

Càng xa càng tốt. Tuy nhiên, bạn có nghĩ rằng còn thiếu điều gì đó ở đây không? Những tập tin nào chứa các dòng được tìm thấy bởi grep? Điều còn thiếu ở đây là tên tệp vì find gọi grep một lần cho mỗi tệp và grep, là một lệnh thông minh, biết rằng nếu nó chỉ được đặt tên của một tệp thì nó không cần cho bạn biết đó là gì.

Trong tình huống này, chúng tôi có thể sử dụng lệnh xargs, nhưng chúng tôi đã biết về sự cố với các tệp có tên chứa dấu cách. Chúng tôi cũng đề cập đến thực tế là lệnh find có thể tạo danh sách tên được phân tách bằng null nhờ tùy chọn -print0. Các phiên bản hiện đại của lệnh find có thể được phân tách không phải bằng dấu chấm phẩy mà bằng dấu +, để có thể chuyển số lượng tên tối đa có thể có trong một lệnh gọi tới lệnh find, giống như khi sử dụng xargs . Không cần phải nói, trong trường hợp này bạn chỉ có thể sử dụng cấu trúc () một lần và đó phải là tham số cuối cùng của lệnh. Liệt kê 20 thể hiện cả hai phương pháp này.

Liệt kê 20. Sử dụng find, xargs và các tệp chứa khoảng trắng trong tên của chúng
$ tìm. -name "*1" -print0 |xargs -0 grep "1" ./text 1:1 apple ./text1:1 apple $ find . -name "*1" -exec grep "1" () + ./text 1:1 apple ./text1:1 apple

Cả hai phương pháp này đều hoạt động và việc lựa chọn một trong số chúng thường chỉ được xác định bởi sở thích cá nhân của người dùng. Xin lưu ý rằng bạn có thể gặp sự cố khi sắp xếp các đối tượng có dấu phân cách thô và khoảng trắng; vì vậy nếu bạn chuyển đầu ra cho xargs , hãy sử dụng tùy chọn -print0 của find , cũng như tùy chọn -0 của xargs , tùy chọn này sẽ yêu cầu bạn sử dụng dấu phân cách null trong đầu vào. Các lệnh khác, bao gồm tar, cũng hỗ trợ tùy chọn -0 và hoạt động với đầu vào được phân cách bằng null, vì vậy bạn phải luôn sử dụng tùy chọn này cho các lệnh hỗ trợ nó, trừ khi bạn chắc chắn 100% rằng danh sách đầu vào sẽ không gây ra vấn đề gì cho bạn.

Nhận xét cuối cùng của chúng tôi liên quan đến việc làm việc với danh sách các tệp. Bạn nên luôn kiểm tra danh sách và lệnh của mình một cách cẩn thận trước khi thực hiện các thao tác hàng loạt (chẳng hạn như xóa hoặc đổi tên nhiều tệp). Có một bản sao lưu cập nhật khi cần thiết cũng có thể là vô giá.

Tách đầu ra

Để kết thúc bài viết này, chúng ta sẽ xem nhanh một lệnh nữa. Đôi khi bạn có thể cần xem kết quả đầu ra trên màn hình và lưu nó vào một tệp cùng một lúc. Đối với điều này bạn chúng ta có thể chuyển hướng đầu ra của lệnh đến một tệp trong một cửa sổ, sau đó sử dụng tail -fn1 để theo dõi đầu ra trong một cửa sổ khác, nhưng cách dễ nhất là sử dụng lệnh tee.

Lệnh tee được sử dụng trong một đường ống và đối số của nó là tên của tệp (hoặc tên của một số tệp) mà đầu ra tiêu chuẩn sẽ được dẫn đến. Tùy chọn -a cho phép bạn không thay thế nội dung cũ của tệp bằng nội dung mới mà thêm dữ liệu vào cuối tệp. Như đã thảo luận khi chúng ta thảo luận về đường ống, nếu bạn muốn lưu trữ cả luồng đầu ra tiêu chuẩn và luồng lỗi, bạn phải chuyển hướng stderr sang stdout trước khi chuyển dữ liệu làm đầu vào cho lệnh tee. Liệt kê 21 cho thấy một ví dụ về cách sử dụng lệnh tee để lưu kết quả đầu ra vào hai tệp, f1 và f2.

Liệt kê 21. Tách thiết bị xuất chuẩn bằng lệnh tee
$ ls văn bản|tee f1 f2 text1 text2 text3 $ cat f1 text1 text2 text3 $ cat f2 text1 text2 text3