Các Lược Giảng Chuyên Sâu về Sử Dụng Văn Lệnh BASH trong Linux/Bài 3A

Từ Thư viện Khoa học VLOS
Bước tới: chuyển hướng, tìm kiếm

Loạt bài "Các Lược Giảng Chuyên Sâu về Sử Dụng Văn Lệnh BASH trong Linux" của tác giả Làng Đậu giữ bản quyền 2006. Người đọc chỉ được sử dụng cho mụch đích học tập hay giảng dạy cho cá nhân. Cấm mọi hình thức sao chép, đăng lại, hay in lại nhằm mụch đích mua bán hay trục lợi mà không có sự cho phép chính thức của tác giả. Mọi thông tin về việc phổ biến rộng rãi có tính quảng bá tài liệu này cho mụch đích giáo dục hay các phê bình, đề nghị về nội dung bài giảng xin liên lạc về vo_quang_nhan@yahoo.com

Bài 3A: Một số lệnh cơ bản và kĩ năng dùng lệnh trong BASH

Biểu thức chính quy (Regular Expressions)

Một biểu thức chinh quy là một dạng thức chung của những chuỗi các kí tự khác nhau. Dạng thức này được biểu thị bởi một chuỗi kí tự đặc biệt thường được dùng trong một cuộc tìm kiếm. Mỗi dạng thức như vậy thường được đóng giữa hai kí tự gọi là các kí tự giới hạn (delimited character) thường là kí tự /. (Tuy nhiên, tuỳ theo nhu cầu, kí tự giới hạn có thể được định nghiã lại).

Thí dụ: với biểu thức /Bob/ thì dạng thức Bob sẽ tương hợp với các chuỗi kí tự (string) có chứa chuỗi "Bob" ở bất kì vì trí nào nó (như là các chuỗi kí tự BabyBob, my Boby, Bob, 12Bob, (Bob) đều thoả mãn điều kiện tìm kiếm đối với dạng thức Bob.) Một biểu thức chính quy thường gọi tắt là RE (Regular Expressions). Một chuỗi kí tự S thoả mãn dạng thức của một biểu thức chính quy R thì S được gọi là  tương hợp (với dạng thức của biểu thức R)

Một biểu thức chính quy R có thể là tổ hợp của nhiều biểu thức chính quy thành phần SR. Khi đó, ta bảo SR là biểu thức chính quy con (hay gọn hơn là biểu thức con) của R

Để mô tả dạng thức của các chuỗi kí tự cần tìm, trong mỗi biểu thức chính quy, sẽ cần sử dụng một số kí tự mà các kí tự này được gán cho những ý nghiã mới khác với ý nghiã của một kí tự thông thưòng. Những kí tự được quy uớc để có riêng các ý nghiã đặc biệt được gọi là các siêu kí tự. Nhiều mệnh lệnh trong Linux sẽ chấp nhận và sử dụng các siêu kí tự này (và đôi khi với ý nghiã không hoàn toàn giống nhau cho từng lệnh) trong đó có các lệnh vi, grep, sed, awk,perl

Các siêu kí tự thông thường

Lưu ý: Các dấu ' dùng trong bảng là để phân định biên giới của chuỗi thí dụ
- nhưng không thuộc nội dung của các chuỗi kí tự này

Siêu
Kí tự
Ý nghiã  Thí dụ 
(Biểu thức  chính quy)
Một số string tương hợp
(Ngăn cách bởi dấu ,)
Không tương hợp
^ Bắt đầu của dòng chữ  /^Hello/ Tất cả các dòng
bắt đầu với 'Hello'
'A Hello',
' Hello','_Hello'
$ Kết thúc dòng  /the END$/ Tất cả các dòng
kết thúc bởi 'the END'
' END','the END.',
'the end'
. Một kí tự bất kì
ngoại trừ dấu xuống hàng
 /B..l/ 'Bill', 'B12l',
'B#(l'
'Bil','Tool',
'Boom'
* Dãy kí tự bất kì tiếp theo
sau kí tự ngay trước nó
 /ab*c/ 'abc','abbxbc', 'ac' 'abb','abcc'
[ ] Tương hợp với một kí tự
duy nhất nào đó bên trong
ngoặc vuông
 /t[ou]/ 'touch','tune','so stupid' 'do', 'tio',
'two', 'tiu'
[x-y] Tương hợp với một kí tự
duy nhất nào đó trong
dãy thứ tự ASCII từ x đến y
 /^[A-Z]ove/ Tất cả các string bắt đầu
với một chữ in hoa và
nối theo là 'ove'
như là Love, Move,...
'love', 'aove',
'myLove'
[^ ] Tương hợp với một kí tự
sao cho nó không có mặt
trong ngoặc vuông
 /file[^1-9]/ 'file' , 'file0', myfileA file1','xfile2',
...,'myfile9'
\ Kí tự thoát cho các siêu kí tự.
Siêu kí tự đứng ngay sau dấu /
sẽ không còn ý nghiã đặc biệt
mà chỉ mang ý nghiã thông thường
 /the end\./ 'the end.','to the end. (y/n)?' 'the endy', 'the end\.'
Những siêu kí tự thêm vào có thể được hỗ trợ bởi nhiều chương trình UNIX/Linux
\< Bắt đầu biên giới của một từ (word) /\<Poison/ 'OK Poison1', ' Poisoning' 'EulerPoison',
'2Poison'
\> Kết thúc biên giới của một từ  /Cap\>/ 'No Cap','HCap y', 'Cap.' 'Capital'
\( \) Các thẻ quy ước \<n>:
dùng để thay thế cho chuỗi
các kí tự tương hợp
trong ngoặc đơn. \1, đại diện
cho RE \( \) thứ nhất,
\2 đại diện cho RE \( \) thứ nhì ...
Có tổng cộng 9 thẻ quy ước là
\1, \2, ...\9
/\(hard\)ship\1y/ RE \( \) đầu tiên từ
bên trái kí hiệu bởi \1
RE  \( \) kế tiếp kí hiệu
là \2,..
Thí dụ này tương đương
với biểu thức
/hardship hardy/
x\{m\} lập lại kí tự x m lần /ab\{3\}c/ tương đương với RE /abbbc/
x\{m,n\} Lập lại kí tự x ít nhất m lần và không quá n lần  /ab\{3,5\}cd/ 'abbbcd', ' abbbbcde', 'abbbbbcdt'
'abbcd', 'abbbbbbcd'

Thí dụ:

/[a-z0-9]/    : là RE tương hợp với tất cả các dòng chữ có chữ cái không viết hoa hay các kí tự số
/[0-9]*\*$/   : là RE tương hợp với tất cả các dòng chữ có một kí tự số theo sau đó là một dãy
kí tự bất kì và dòng này kết thúc bởi dấu * /^A\<f.th\>/  : là RE tương hợp với tất cả các dòng chữ bắt đầu bằng từ "A" sau đó từ thứ nhì
bắt đầu bằng chữ f tiếp theo là một kí tự nào đó và kết thúc của từ này bằng hai kí tự th.

Trong các phụ lục của bài này và các bài sau đó sẽ có hướng dẫn dùng các lệnh quan trọng của Linux có hỗ trợ chế độ dùng RE

Lệnh grep

Lệnh grep rất thông dụng để tìm và hiển thị lại các dòng tương hợp của một dạng thức cho sẵn trong một hay nhiều tập tin. Nếu dạn thức có chứa các kí tự không thấy được (như là các kí tự khoảng trống, nhảy bước, hay xuống hàng) thì dạng thức dùng trong mệnh lệnh phải được để trong các dấu ngoặc dùng cho chuỗi kí tự. grep in ra kết qủa lên stdout và sẽ không thay đổi nội dung hay thuộc tính cài đặt từ trước của các tập tin mà nó đọc. Ngoài các siêu kí tự thông thường, grep hỗ trợ khá nhiều các siêu kí tự thông thường và hỗ trợ thêm một số khác nữa.

lệnh grep

Cú pháp cho lệnh grep là:

grep [Tham_Số] [Dạng_thức] [TÊN_CÁC_TẬP_TIN]

Lưu ý: như các lệnh khác, lệnh grep thường hay được dùng thông qua một ngỏ xuất từ một ống dẫn truyền một cách rất tiện lợi (xem thí dụ dưới đây).

Thí dụ1:

#print the line of name.txt that contains substring 'Thomas' or 'thomas'
grep '[Tt]homas' /data/name.txt  name2.txt  

# using pipe output from ps -A command find all lines contains tty followed by any character ps -A | grep 'tty.'

lệnh grep mở rộng

Ngoài ra, nếu dùng tham số -E thì lệnh grep được gọi là grep mở rộng (extended grep). Lệnh mở rộng này có định nghiã thêm một số siêu kí tự mới. Và như vậy cú pháp viết thành:

grep -E [Tham_Số_Khác] [Dạng_thức] [TÊN_CÁC_TẬP_TIN]

Các siêu kí tự thêm vào để dùng với lệnh grep -E
Siêu
Kí tự
Ý nghiã  Thí dụ (RE)  Tương hợp với Không tương hợp với
\w kí tự là một chữ cái
hay một chữ số
 f\w*\.dat  file.dat, f1.dat  f_.dat, f-i.dat
\W kí tư không phải là
chữ cái hay chữ số
 file\W  tương đương với RE:
file[^a-zA-Z0-9]
 f1, file
\b biên giới của một từ  \bfile\b ' file', ' file '  myfile, file1
+ Ít nhất một kí tự
(hay nhiều hơn) tương hợp
(trùng) với kí tự
đứng liền trước dấu +
 [a-z]+hood  childhood, robinhood, thood  Robinhood, 1hood
? Có tối đa một kí tự tương hợp
(trùng)với kí tự liền trước nó
 bo?t  boot, bot  booot, bt
| Tương thích hoặc like|want  love, like, want
( ) Các dạng thức nhóm trong ngoặc ing|er)  wanted, wanting, wanter

Thí dụ:

nội dung của file.dat:

#remark line
#this is data file of my flight
 SouthWest   SW  Houston   Dallas         8:00  9:00  40
 NorthWest   NW  NewYork   OrangeCounty   6:00  12:00 65
 continental CT  Hongkong  L.A.           7:00  8:00  125
 -a NEW      CTT Hongkong  LA          6:00  19:00 212
 Western     CT2 Hanoi     Houston   
#Grep commands
cat file.dat | grep West    
(Hai dòng đầu và dòng cuối sẽ tìm thấy và in ra)
grep -E '\bCT\b'  file.dat
(Chỉ tìm thấy dòng thứ 3 và in ra)

POSIX: Bên cạnh các siêu kí tự kể trên, grep -E còn hỗ trợ các dạng POSIX ( portable operating system Interface nghiã là "giao diện hệ điều hành khả xuất"). Đây là tiêu chuẩn kĩ nghệ để bảo đảm các chương trình là khả xuất (portable) qua các hệ điều hành

Kí tự POSIX hỗ trợ bởi grep
Tất cả các thí dụ đưới đây dùng cùng một nguồn là file.dat
Lớp ngoặc vuông Ý nghiã  Thí dụ (RE)  Trả về từ file.dat
[:alnum:]  các kí tự chữ và số  grep -E 'CT[[:alnum:]]' file.dat  Hiển thị hai hàng cuối
[:alpha:]  kí tự chữ grep -E 'CT[[:alpha:]]' file.dat  Dòng thứ 4
[:cntrl:]  kí tự điều khiển   (như F1, F2,...)
[:digit:]  kí tự số grep -E 'CT[[:digit:]]' file.dat  Dòng cuối cùng
[:graph:]  kí tự không phải là
 các khoảng trống
 grep -E '^[[:graph:]]' file.dat  Hai dòng đâu
[:lower:]  kí tự dạng chữ thường
[:print:]  giống như [:graph:]
nhưng  cộng thêm
các kí tự khoảng trống
[:punct:] kí tự chấm câu grep -E 'L[[:punct:]]' file.dat  Dòng thứ 3
[:space:]  các kí tự khoảng trống
(đầu dòng, không khí, tab)
grep -E '^[[:space:]][[:space]]' file.dat  Tất cả các dòng
ngoại trừ hai dòng đầu tiên.
[:upper:]  Viết Hoa
[:xdigit:]  số trong hexadecimal

Các tham số thông dụng

Sau đây là một số tham số rất thông dụng của lệnh grep:

  • -A [n] : Hiển thị dòng tìm thấy tương hợp và hiển thị tiếp số [n] các dòng tiếp sau dòng tương hợp này
  • -a: xử lí tập tin nhị phân xem như nó là tập tin văn bản.
    Thí dụ: Hãy thử so sánh hiển thị trả về của hai lệnh
    grep 'do not sort' /bin/ls
    grep -a 'do not sort' /bin/ls
  • -B [n]: in ra luôn số dòng của các dòng chữ tương hợp ở đầu mỗi dòng hiển thị (chẳng hạn: grep -B 2 'Hanoi' file.dat )
  • -b: in thứ tự byte (byte offset) của các dòng tương hợp xuất hiện trong tập tin
    Chẳng hạn:
    grep -b 'Hanoi' file.dat)
  • -c: Chỉ in ra số các dòng tương hợp (mà không in bản thân dòng có chuỗi kí tự tương hợp này)
    Thí dụ:
    grep -c Houston file.dat
  • -i: Không phân biệt chữ in hoa hay in thưòng
    Thí dụ:
    grep -i hongkong file.dat )
  • -l: In tên tập tin có dòng tương hợp thay vì dùng định dạng thông thường.
    Thí du:
    grep -l Hongkong file.dat
  • -m [n]: ngưng đọc từ ngỏ vào nếu như đã đạt tới n dòng tương thích.
    Thí dụ:
    grep -m 1 Hongkong file.dat
  • -n: In số thự tự của dòng trước khi in mỗi dòng tương hợp
    Thí dụ:
    grep -n Hongkong file.dat)
  • -r: đọc thi hành lên tất cả các tập tin có trong thư mục (thi hành grep đệ quy)

Lệnh xargs

Đây là một lệnh rất hữu hiệu để chuyển các ngỏ ra hay các thông báo từ các ngỏ ra chuẩn thành các tham số của những mệnh lệnh khác nhằm thực thi cùng thao tác (một lệnh hay 1 nhóm lệnh) trên nhiều đối tượng khác nhau (các đối tượng này đóng vai trò tham số)

xargs sẽ đọc từng dòng từ ngỏ vào chuẩn của nó để chuyển thành một tham số để thi hành cùng một lệnh cho mỗi dòng đó lần lượt.

Chẳng hạn, nếu ngỏ ra cuả một mệnh lệnh nào đó bao gồm 3 dòng X1, X2, X3 và ngỏ ra này được ống dẫn truyền (pipe) cung cấp cho lệnh xargs để thực thi một lệnh L thì lệnh xargs sẽ thự thi tổng cộng 3 dòng lệnh L1, L2, L3. Trong đó, dòng lệnh L1 sẽ lấy X1 làm tham số. L2 sẽ lấy X2 làm tham số và L3 lấy X3 làm tham số. Các thí dụ sẽ minh hoạ rõ hơn điều này.

Cú pháp thông dụng nhất là:

[Lệnh_1] | xargs [Tham_Số] [Lệnh_2]

Nếu [Lệnh_2] không có mặt thì xargs -i chỉ hiển thị ra màn hình theo sự cài đặt của [Tham_Số].

[Lệnh_1] thường là các lệnh xuất ra nhiều dòng tới stdout, mỗi dòng (hay một vài dòng) như vậy sẽ được gom lại vào thành một bộ tham số cho các dòng [Lệnh_2] theo thứ tự một cách lần lượt cho đến khi không còn dòng xuất nào nữa từ [Lệnh_1]

Ứng dụng

  • Một trong những kết hợp hay thấy nhất là dùng lệnh find để tìm các tập tin đặc trưng rồi từ đó dùng lệnh xargs để chuyển chúng sang thực thi các mệnh lệnh khác lên tên các tập tin vưà tìm thấy. (Sự kết hợp các lệnh có thể dùng với rất nhiều lệnh khác như grep, sed hay awk

Thí dụ1:

Thí dụ sau sẽ chuyển tất cả các tập tin bắt đầu bằng my và có phần mở rộng là .txt trong thư mục test (kể cả các tập tin trong các thư mục con của test) vào trong một thư mục mới tên là mydir.

find ./test -name "my*.txt" | xargs -i mv {} ./mydir

Ở đây, kí hiệu {} thay thế cho các dòng xuất ra từ lệnh find ./test -name "my*.txt". Như vậy, cứ mỗi tập tin dạng my*.txt tìm được qua lệnh find thì tên (đầy đủ) của tập tin này sẽ được thay vào trong ngoặc {} để lần lượt được lệnh mv <tên_tập_tin_cung cấp_từ_lệnh_find> ./mydir di chuyển nó vào trong thư mục ./mydir.

Lưu ý:  trong một số trường hợp (như là khi dùng với các lệnh hỗ trợ biểu thức chính quy chẳng hạn) thì người dùng thay vì dùng kí hiệu {}, có thể định nghiã lại một cặp kí hiệu khác chẳng hạn như căp kí hiệu ~~, $$, [], ##, hay bất kì kí hiệu nào ... Tuy nhiên, một số kí hiệu cần phải dùng chung với kí tự thoát \ để tránh gây lỗi mập mờ (ambiguity).

Như vậy lệnh trên hoàn toàn tương đương với lệnh

find ./test -name "my*.txt" | xargs -i[] mv [] ./mydir  

Ở đây, {} đã được thay bằng cặp kí tự []

Trong thí dụ trên, người dùng có thể thay lệnh mv và lệnh find bởi các lệnh thích hợp để làm các thao tác khác

Thí du2:  Lệnh grep sau đây tìm tất cả các tập tin kết thúc bởi txt được liệt kê trong filelist và chuyển cho lệnh xargs lấy làm tham số cho lệnh rm để xoá các tập tin đó.

#content of "filelist"
./test/mytest.txt
./myfiletxt
./introduction.pdf 

Khi thực thi lệnh

grep 'txt$' filelist |xargs -i rm -f {}

thì 2 dòng

./test/mytest.txt
./myfiletxt

sẽ được grep lọc lựa và hiển thị thông qua ống dn truyền sẽ được lệnh xargs tiến hành thành 2 dòng lệnh:

rm -f ./test/mytest.txt
rm -f ./myfiletxt

Hậu quả là 2 tập tin trên sẽ bị xoá (nếu có)

  • Dùng để kết hợp nhiều dòng hiển thị trong ngỏ ra chuẩn thành 1 dòng duy nhất

Thí dụ3: Lệnh sau đây sẽ hiển thị thời gian và chào người ra lệnh trong cùng một hàng.

(date; echo "Hello, `whoami`.") |xargs
  • Dùng để định dạng lại: việc hiển thị các tập tin dữ liệu có cấu trúc đơn giản, hay hiển thị lại thành 3 cột dữ liệu của một tập tin bất kì thay vì chỉ có một cột

Thí dụ4: Lệnh sau sẽ hiển thị lại tên, họ, ngày sinh, nghề nghiệp của một tâp tin

#content of personal.txt
#first line is name
#secondline is DOB
#last line is Ocupation

Hung Nguyen 12/12/90 Engineer

PhuongDung Vo 04/28/63 Pharmacist

Long Le 08/03/79 Dentist
#End of file personal.txt

Lệnh đơn giản sau đây sẽ hiển thị các thông tin về một người (gồm 3 dòng) trong một dòng. Dòng bỏ trắng sẽ bị tự động loại ra (bởi lệnh xargs), các đòng bị chú sẽ bị loại bỏ bởi lệnh grep -v

grep -v "^#" personal.txt | xargs -n3 

Một ứng dụng khác của tham số -n là dùng để cung cấp nhiều tham số cho cùng một lệnh.

Thí dụ5:  Thực thi lệnh chép các tập tin có tên mysourcefile[i] thành mytargetfile[i] mà danh sách đã được chuẩn bị sẵn trong tập tin myhandle như sau:

#content of myhandle
mysourcefile1
mytargetfile1

mysourcefile2 mytargetfile2

mysourcefile3 mytargetfile3 #End of myhandle
grep -v '^#' myhandle |xargs -i -n2 cp -f 

Trong thí dụ trên, lệnh grep sẽ hiển thị nội dung của tập tin myhandle ngoại trừ các dòng bắt đầu bằng dấu # (tức là loại trừ các dòng bị chú). Sau đó, lệnh xargs sẽ đưa một lúc 2 dòng (tương ứng với -n2) vào cho lệnh cp. Dòng đầu sẽ là tên tập tin nguồn (mysourcefile[i]) cho tham số thứ nhất của lệnh cp và dòng thứ nhì (mytargetfile[i]) trở thành tham số thứ nhì cho lệnh copy. Nghiã là Nếu các mysourcefile[i] tồn tại thì chúng sẽ lần lượt được chép (copy) thành mytargetfile[i] một cách tương ứng.

Các tham số thông dụng cho lệnh xargs

  • -a [Tên_Tập_Tin] : Đọc ngỏ vào từ [Tên_Tập_Tin] thay vì từ ngỏ vào chuẩn. Nếu dùng tham số này, stdin sẽ không thay đổi khi các lệnh đang chạy. Ngoài ra, stdin sẽ được chuyển hướng tới /dev/null.
  • -0 Các dòng thông tin đọc từ ngỏ vào được kết thúc bởi kí tự null thay vì bởi các kí tự khoảng trắng (whitespace); ngoài ra, các dấu ngoặc (" , ') cũng như dấu nghiên về (backslash) \ không còn được mang ý nghiã đặc biệt nữa. Hữu dụng khi ngỏ vào có chứa các kí tự trắng, các dấu ngoặc, hay dấu nghiêng về. Lệnh dùng tham số dạng find -print0 của GNU sẽ được tiện lợi với cách gọi này.
  • -i[Chuỗi_Thay_Thế] Thay vì dùng cặp kí hiệu mặc định là {}, có thể dùng bất kì kí hiệu thay thế nào. Cặp kí hiệu đó sẽ trong khi thực thi sẽ được thay thế bằng mỗi dòng xuất ra từ stdout và thi hành lần lượt cho đến khi không còn dòng nào từ stdout nữa. Lưu ý: Một khi dùng [Chuỗi_Thay_Thế] (hay dùng {} trong mặc định) để cung cấp tham số cho mệnh lệnh cần thi hành ([Lệnh_2]) thì tham số này sẽ lấy quyền ưu tiên đối với tham số -n[Số_Đối_Số_Tối_Đa] và do đó, có thể tạo ra các hiệu ứng không mong muốn. Do đó, nên tránh viết [Chuỗi_Thay_Thế] (hay {} ) vào trong dòng lệnh như là tham số nếu người dùng dự tính khai thác tham số -n
  • -n[Số_Đối_Số_Tối_Đa] Sử dụng [Số_Đối_Số_Tối_Đa] làm các đối số cho mệnh lệnh mà xargs gọi.
  • -p Hiển thị câu hỏi sự chuẩn y của người dùng trước khi lệnh được thi hành. Lệnh được thi hành chỉ khi người dùng trả lời `y ' hay `Y '
  • -r Nếu stdin của xargs chỉ là các dòng trắng thì không thực thi mệnh lệnh

Ôn luyện và đào sâu về sử dụng đổi hướng và ống truyền tên

Đổi hướng

Đổi hướng: là quá trình bắt các thông tin ngỏ ra từ một mệnh lệnh, một tập tin, một chương trình hay ngay cả một đoạn mã và gửi chúng vào ngỏ vào của một mệnh lệnh, một tập tin hay một chương trình khác. trong bài 1 chúng ta đã nói về việc đổi hướng. Giờ là lúc đào sâu thêm các chi tiết.

Bộ mô tả tập tin (file descriptor): Tương tự C/C++ hay các ngôn ngữ khác, mỗi tập tin được mở có thể được gán lên đó một bộ mô tả tập tin (gọi tắt là bộ mô tả). Trong các văn lệnh, mỗi bộ mô tả có thể được gán cho một con số. Riêng các con số 0, 1, 2 được mặc định lần lược dùng cho các bộ mô tả stdin, stdout, và stderr. Các con số khác từ 3 tới 9 có thể được dùng để gán cho bất kì tập tin được mở nào khác.

Việc đổi hướng có thể được hoàn tất bằng cách dùng các kí tự đổi hướng, bằng cách kết hợp với lệnh exec, hay bằng cách kết hợp với các vòng lặp và rẽ nhánh

Dùng kí tự đổi hướng

  • [TÊN_TẬP_TIN] : Đổi hướng vào [TÊN_TẬP_TIN] xoá nội dung có sẵn từ trước của [TÊN_TẬP_TIN]

Thí dụ1:

 ls -l > list_file.txt
 cat list_file.txt

Thí dụ2:

 mount /dev/df0 /mnt/flopy  1>/dev/null  2>/dev/null    
 # redirect output and error messages into  NULL (hide messages released from 'mount')
  •  : > [TÊN_TẬP_TIN] : Cắt bỏ [TÊN_TẬP_TIN] thành tập tin có độ dài 0 byte
  • >>  [TÊN_TẬP_TIN] : Chép nối stdout vào nội dung của [TÊN_TẬP_TIN] (tạo ra tập tin mới nếu nó chưa tồn tại)

Thí dụ3:

LOG=./logfile.txt
echo  "date" > $LOG
echo "the content of /home directory :" >> $LOG
ls -l >> $LOG
# to read what is in log file, invoke command cat ./logfile.txt
  • 2>&1 đổi hướng stderr sang stdout ( tức là chuyển các thông bao lỗi vào cùng một ngỏ ra chuẩn)
  • m>&n đổi hướng tập tin có bô mô tả m sang thành n
  • >&n đổi hướng stdout sang n
  • n<> [TÊN_TẬP_TIN]  : mở [TÊN_TẬP_TIN] cho việc đọc và viết trong bộ mô tả n
  • n<&- đóng ngỏ vào của bộ mô tả n
  • <&- Đóng stdin .
  • n>&- Đóng ngỏ ra của bộ mô tả n
  • >&- Đóng stdout
  • [TÊN_TẬP_TIN] : nhận ngỏ vào từ [TÊN_TẬP_TIN]

Thí dụ4: Đọc toàn bộ nội dung (kể cả định dạng) của ổ cứng /dev/hdb chép thành một tập tin là rawbackup.dat

#read all content of hard drive /dev/hdb and save into a file named as rawbackup.dat
dd < /dev/sdb > ./rawbackup.dat
#note:  you may also compress the output file rawbackup.dat to save space!
However, the file must be decompressed in each restore process

Thí dụ5:

restore the rawbackup.dat into the hard drive /dev/hdc
dd <./rawbackup.dat >/dev/hdc

Dùng kết hợp với lệnh exec

  • exec < [TÊN_TẬP_TIN] được dùng để đổi hướng đọc từ stdin sang đọc từ một tập tin. Cho nên sau khi sử dụng lệnh này, mọi dữ liệu đều được đọc từ tập tin [TÊN_TẬP_TIN] thay vì từ stdin. Ứng dụng của nó là có thể dùng văn lệnh để đọc hay điều chỉnh nội dung của một tập tin

Thí dụ6:

#!/bin/bash
# Redirect stdin by 'exec'

exec 4<&0 # save stdin to descriptor #4. exec < data.txt # stdin is now replaced by file "data.txt" read line1 # Read the first line of file "data.txt". read line2 # Read second line of file "data.txt" read line3 # and the third line

echo echo "3 first lines read from data.txt are:" echo "1st line: $line1 echo "2rd line: $line2 echo "3th line: $line3" echo; echo; echo exec 0<&4 4<&- # restore the original stdin back exit 0

Thí dụ7:

echo 1234567890 > MyFile    # Write string to "File".
exec 5<> MyFile             # Open "File" and assign fd 5 to it.
read -n 2 <&5               # Read only 1st 2 characters; current cursor move to offset 2
echo -n 'hi' >&5            # Write a 'hi' there.
exec 5>&-                   # Close fd 5.
cat MyFile                  # Should be 12hi567890

Dùng kết hợp với các vòng lặp hay mã rẽ nhánh

Các vòng lặp hay mã rẽ nhánh có thể được dùng kết hợp qua kí tự đổi hướng <

Thí dụ8: Giả sử tập tin file.dat kết thúc bằng dòng chữ "THE END"

while [ ! "$line" = "THE END." ]  
do
  read line                 # Reads from file.dat, rather than stdin.
  echo $line
  let "count += 1"
  if [ $count -gt 3 ]; then
      echo "out of range"
      break
  fi
done <"file.dat"           # Redirects stdin to file file.dat. 
echo "$count"              #display content of file.dat

Ống Dẫn Truyền Tên (named pipe)

Trong UNIX/Linux, một kênh trao đổi giữa các tiến trình, FIFO (từ chữ "first-in, first-out"), thường được dùng để chuyển các ngỏ ra chuẩn của một mệnh lệnh lên ngỏ vào chuẩn của một mệnh lệnh khác đang chạy cùng lúc. Đôi khi các tiến trình (process) có thể tự mở các ống dẫn truyền đến các lệnh mà chúng khởi động

Quá trình đổi hướng có thể được xem là một ống dẫn truyền dạng đơn giản. Chúng ta sẽ khai thác kĩ hơn 2 dạng named pipe đơn giản.

command1 | command2 | command3 ...

Dùng để xử lí một dãy các lệnh mà ngỏ ra của lệnh trước chuyển thành ngỏ vào của của sau và chúng ngăn cách nhau bởi dấu |

Thí dụ1: Xếp thứ tự tất cả các dữ liệu xuất từ các tập tin *.dat, xoá các dòng trùng nhau, và lưu trữ lại trong tệp newdata

cat *.dat | sort | uniq > newdata

Thí dụ2: tìm tất cả tệp *.txt trong thư mục hiện hoạt rồi xử lí qua lệnh ls -l và sau cùng lọc bằng lệnh grep các tập tin được tạo ra trong tháng 12

find ./ -name *.txt | xargs -i ls -l | grep "Dec"
#this command may be used to find all *.txt file that created in December

<([LỆNH])

Dùng để gửi ngỏ ra của một lệnh vào một tiến trình khác

Thí dụ3 Lệnh diff so sánh thuộc tính của mọi tập tin trong thư mục dir1 với thư mục dir2 mà các thuộc tính đó lại được rút ra từ hai lệnh ls-l

diff <(ls -l dir1) <(ls -l dir2)

Thí dụ4: Một số lệnh tạo ra tập tin nén dạng *.tar.gz:

tar cpf >(gzip -9  > myfile.tar.gz) myDir
#The command  will create a tar of myDir 
and then compress this into a file named as myfile.tar.gz # It is equivalent to gzip -9 < pipe > myfile.tar.gz & tar cpf pipe myDir rm pipe

Thí dụ5: đọc thông tin từ lệnh lsmod (hiển thị gồm 3 cột) lần lượt vào các biến record[i] và hiển thị chúng

while read record1 record2 record3; do
   echo $record1 $record2 $record3
done < <(lsmod)  

# Output may look like: # Modules Size Use by Not tained # smbfs 40352 2 (Autoclean) # nls_iso8859-1 3520 0 (Autoclean) #let try to compare with the command lsmod itself #The similar pipe command is lsmod | while read record1 record2 record3; do echo $record1 $record2 $record3 done # Same output as above.

Lưu ý: các phương pháp dùng pipe trên tương dương với việc sử dụng FIFO trong C. (thông qua các hàm: popen, pclose ...)


Trở về mục lục

Đọc bài kế

Liên kết đến đây