Các Lược Giảng Chuyên Sâu về Sử Dụng Văn Lệnh BASH trong Linux/Bài 3A
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
Mục lục
Biểu thức chính quy (Regular Expressions)[sửa]
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,
và
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àySiê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[sửa]
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[sửa]
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[sửa]
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.datLớ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ốnggrep -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[sửa]
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
- và
-
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[sửa]
Đâ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[sửa]
-
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
hayawk
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
thành
[i]
mytargetfile
mà
danh
sách
đã
được
chuẩn
bị
sẵn
trong
tập
tin
[i]
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
)
cho
tham
số
thứ
nhất
của
lệnh
cp
và
dòng
thứ
nhì
([i]
mytargetfile
)
trở
thành
tham
số
thứ
nhì
cho
lệnh
copy.
Nghiã
là
Nếu
các
[i]
mysourcefile
tồn
tại
thì
chúng
sẽ
lần
lượt
được
chép
(copy)
thành
[i]
mytargetfile
một
cách
tương
ứng.[i]
Các tham số thông dụng cho lệnh xargs[sửa]
-
-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ủaxargs
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[sửa]
Đổi hướng[sửa]
Đổ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[sửa]
-
> [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[sửa]
-
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[sửa]
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)[sửa]
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 ...[sửa]
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]
)[sửa]
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 ...)