Tài liệu lập trình shell Linux - Unix
Trang 13.3.5 L nh while
3.3.6 L nh intil
3.3.7 L nh case
3.4 Danh shell th c thi l nh (Lists)
3.4.1 Danh sách AND (&&) 3.4.2 Danh sáchl OR ( || ) 3.4.3 Kh i l nh
3.5 Hàm (function)
3.5.1 Bi n c c b và bên toàn c c
3.5.2 Hàm và cách truy n tham s 3.6 Các l nh n i t i c a shell
Trang 23.6.3 L nh : (l nh r ng)
3.6.4 L nh (th c thi) 3.6.5 eval
3.6.6 exec
3.6.8 export 3.6.9 L nh expr
3.6.11 return 3.6.12 set
3.6.15 unset 3.7 L y v k t qu c a m t l nh
3.7.1 c l ng toán h c 3.7.2 M r ng tham s
8.4.1 M nh đ if
8.4.2 M nh đ case
Trang 4Tr c khi b t tay vào vi t nh ng ng d ng không c n t i các ngôn ng l p trình
ph c t p khác, ch ng này s đ c p cách ti p c n v i ngôn ng k ch b n (script) c a h
v (shell, t đây s g i là shell script), dùng đi u khi n và t ng tác v i Linux Khi ti p
c n v i DOS, DOS cung c p m t shell đ t o các x lí theo lô trên nh ng t p tin *.bat,
t ng đ i rõ ràng, đ n gi n Tuy nhiên shell c a DOS không m nh và h u d ng b ng shell script trên Linux Tài li u này s cung c p nh ng ki n th c v a đ đ ng i dùng UNIX/LINUX có th dùng shell t o ra các ch ng trình th c thi h u hi u, th m chí còn
có th dùng shell đ th c hi n đ c m i thao tác ki m soát h đi u hành (nh các nhà chuyên nghi p v n nói) Nh ng đích chính c n đ t đ c nh sau:
đi u hành làm vi c ki u o khác, Unix h tr m t ph ng ti n x lí l nh làm giao di n
gi a l nh máy (mà ng i dùng đ a vào) và vi c th c thi c a l nh đó (b i Unix) Ph ng
ti n đó g i là shell T khi ra đ i Unix đã có vài ki u shell, đó là Bourne, C, Korn shell
Th c ra shell làm gì ? Tòan b m c đích c a shell là đ kh i đ ng các ti n trình x lí
l nh đ a vào: yêu c u đ a (dòng) l nh vào, đ c đ u vào, thông d ch dòng l nh đó, và t o
ra ti n trình đ th c hi n l nh đó Nói cách khác shell quét dòng l nh đ a vào máy tính,
c u hình môi tr ng th c thi và t o ti n trình đ th c hi n l nh
Hình 2: V trí c a shell khi “th c hi n” l nh c a ng i dùng Shell d ch các
l nh nh p vào thành l i g i h th ng, chuy n các ký hi u d n h ng >, >> hay | thành d li u di chuy n gi a các l nh c các bi n môi tr ng đ tìm ra thông tin th c thi l nh
Nh v y tìm hi u shell th c t là h c m t ngôn ng l p trình, cho dù không ph c
t p nh C, hay các ngôn ng khác, nh ng c ng ph i qua nh ng đòi h i c n thi t Trong Unix/Linux có các l ai shell khác nhau và có th l a ch n đ dùng theo nhu c u mà
ng i dùng th y phù h p Hình 2 là mô hình t ng tác gi a các shell, ch ng trình ng
d ng, h X-Window và h t nhân
Trang 5Cac ung dung
C shell (csh)
Bourne Again shell (bash)
X-Wimdows shell
Nhan HDH
l nh trên đ c k t h p b ng hai l nh, ls li t kê toàn b danh sách t p và th m c trên đ a
ra màn hình, n u danh sách quá dài, ls chuy n d li u k t xu t cho l nh more x lý hi n
th k t qu thành t ng trang màn hình Linux có cách k t h p d li u k t xu t c a các
l nh v i nhau thông qua c ch chuy n ti p (redirect), ng d n (pipe)
K t h p các l nh v i nhau ch b ng dòng l nh không ch a đ N u mu n t h p nhi u l nh đ ng th i v i nhau và tùy vào t ng đi u ki n, k t xu t c a l nh, mà có nh ng
ng x thích h p thì sao? Lúc đó s dùng đ n các c u trúc l p trình r nhánh nh if, case
Tr ng h p b n mu n th c hi n các thao tác vòng l p, ph i dùng các l nh nh for, while
Shell chính là trình di n d ch cung c p cho ng i dùng kh n ng này H u h t các Shell trong Unix/Linux s d ng m t ngôn ng g n gi ng v i C (đi u này c ng d hi u
b i trong th gi i Unix/Linux, C là ngôn ng l p trình th ng tr ) Ngôn ng Shell càng
gi ng C thì l p trình viên hay ng i đi u khi n Linux càng c m th y thân thi n v i H H
H th ng cung c p cho ng i dùng r t nhi u ch ng trình shell M i shell có m t
s ti n ích nh h tr ch đ gõ phím, ghi nh l nh K t h p các ti n ích c a shell đ t o
ra m t ch ng trình ch y đ c, thì m t ch ng trình nh v y đ c l u d i d ng m t
t p, g i là t p k ch b n (script, hãy th m m t t p nh v y và quan sát c u trúc c a t p)
Vi t đ c m t t p script, th c ch t là đã l p trình theo shell M t khi đã quen thu c v i
m t shell và cách ho t đ ng c a shell đó, ng i dùng có th làm ch đ c các shell khác
m t cách đ dàng
Các shell trên Unix/Linux:
sh ( Bourne ) shell nguyên th y áp d ng cho Unix
Csh, tcsh và zsh dòng shell s d ng c u trúc l nh c a C làm ngôn ng k ch b n
c t o ra đ u tiên b i Bia Joy Là shell thông d ng th hai sau bash shell
Trang 6bash shell ch y u c a Linux Ra đ i t d án GNU bash (Vi t t t c a
Bourne Again Shell có l i đi m là mã ngu n đ c công b r ng rãi N u bash ch a có s n trong h th ng Unix hay Linux, hãy t i
v , biên d ch và s d ng mi n phí t i đ a ch www.gnu.org
rc shell mô r ng c a csh v i nhi u t ng thích v i ngôn ng C h n
rc c ng ra đ i t d án GNU
Shell chu n th ng đ c các nhà phân ph i Linux s d ng hi n nay là bash shell Khi cài
đ t Linux, trình cài đ t th ng m c đ nh bash là shell kh i đ ng Có th tìm th y ch ng trình shell này trong th m c /bin v i tên ch ng trình là bash bash đôi khi là m t
ch ng trình nh phân đôi khi là m t script g i đ n liên k t nh phân khác Có th dùng
l nh file đ xem bash là m t t p tin nh phân hay script nh sau:
$ file /bin/bash
/bin/bash: ELF 32-bit LSB executable Intel 80386
n u k t qu k t xu t là d ng ELF thì có ngh a là bash là ch ng trình nh phân
Tuy bash là shell s d ng ph bi n trong Linux, nh ng các ví d v l p trình s s
d ng ngôn ng và l nh c a shell sh b i vì sh là shell nguyên th y, có th ch y trên c
Unix B ng l nh file ta s th y trong h u h t các b n Linux hi n nay sh ch là liên k t đ n
bash mà thôi Ví d :
$ file /bin/sh
/bin/sh: symbolic link to bash
đi u này có ngh a là bash hoàn toàn có th di n d ch và đi u khi n các l nh c a shell sh
2 S D NG SHELL NH NGÔN NG L P TRÌNH
Có hai cách đ vi t ch ng trình đi u khi n shell: gõ ch ng trình ngay t dòng
l nh là cách đ n gi n nh t Tuy nhiên m t khi đã thành th o có th g p các l nh vào m t
t p đ ch y (chúng t ng đ ng v i cách DOS g i t p *.bat), đi u này hi u qu và t n
d ng tri t đ tính n ng t đ ng hóa c a shell
2.1 i u khi n shell t dòng l nh
Chúng ta hãy b t đ u, giá s trên đ a c ng có r t nhi u file ngu n c, b n mu n truy tìm và hi n th n i dung c a các t p ngu n ch a chu i main() Thay vì dùng l nh
grep đ tìm ra t ng file sau đó quay l i dùng l nh more đ hi n th file, ta có th dùng
l nh đi u khi n shell t đ ng nh sau:
Khi gõ m t l nh ch a hoàn ch nh t d u nh c c a shell, shell s chuy n d u nh c thành
>, shell ch nh p đ y đ các l nh tr c khi th c hi n ti p Shell t tr ng hi u đ c khi nào thì l nh b t đ u và k t thúc Trong ví d trên l nh for do s k t thúc b ng done
Trang 7Khi gõ xong done, shell s b t đ u th c thi t t c nh ng gì đã gõ vào b t đ u t for đây, file là m t bi n c a shell, trong khi * là m t t p h p đ i di n cho các tên t p tìm th y
trong th m c hi n hành
B t ti n c a vi c đi u khi n ngôn ng shell t dòng l nh là khó l y l i kh i l nh
tr c đó đ s a đ i và th c thi m t l n n a N u ta nh n phím Up/Down thì shell có th
tr l i kh i l nh nh sau:
$ for file in * ; do ; if grep -1 'main( )’ $file;
then ; more $file; fi; done
ây là cách các shell Linux v n th ng làm đ cho phép th c thi nhi u l nh cùng lúc ngay trên dòng l nh Các l nh có th cách nhau b ng d u (;) Ví d :
$ mkdir myfolđer; cd myfolder;
s t o th m c myfolder b ng l nh mkdir sau đó chuy n vào th m c này b ng l nh cd
Ch c n gõ Enter m t l n duy nh t đ th c thi hai l nh cùng lúc Tuy nhiên s a ch a các
kh i l nh nh v y không d dàng và r t d gây l i Chúng ch thu n ti n cho k t h p kho ng vài ba l nh d b o trì b n có th đ a các l nh vào m t t p tin và yêu c u shell
đ c n i dung t p tin đ th c thi l nh Nh ng t p tin nh v y g i là t p tin k ch b n (shell script)
2.2 i u khi n shell b ng t p tin k ch b n (script file)
# Script nay se tìm trong th m c hi n hành các chu i
# mang n i dung main( ) , n i dung c a fìle s đ c hi n th ra màn hình n u tìm
Không nh chú thích c a C, m t dòng chú thích (comment) trong ngôn ng shell b t đ u
b ng ký t # Tuy nhiên đây có m t chú thích h i đ c bi t đó là #!/bin/sh y th c s không ph i là chú thích C p ký t #! là ch th yêu c u shell hi n t i tri u g i shell sh
n m trong th m c /bin Shell sh s ch u trách nhi m thông d ch các l nh n m trong t p tin script đ c t o
Có th ch đ nh #!/bin/bash làm shell thông d ch thay cho sh, vì trong Linux th t ra
sh và bash là m t Tuy nhiên nh đã nêu, trên các h Unix v n s d ng shell sh làm chu n, vì v y v n là m t thói quen t t cho l p trình viên n u s d ng shell sh Khi
Trang 8ti p c n v i UNIX, ta s c m th y quen và thân thu c v i shell này h n Nên ch y script trong m t shell ph (nh g i sh ch ng h n), khi đó m i thay đ i v môi
tr ng mà script gây ra không nh h ng đ n môi tr ng làm vi c chính
Ch th #! Còn đ c dùng đ g i b t kì ch ng trình nào ta mu n ch y tr c khi script
ti p theo đ c d ch L nh exit b o đ m r ng script sau khi th c thi s tr v mã l i, đây là
cách mà h u h t các ch ng trình nên làm, m c dù mã l i tr v ít khi đ c dùng đ n trong tr ng h p th c hi n t ng tác tr c ti p t dòng l nh Tuy nhiên, nh n bi t mã tr
v c a m t đo n script sau khi th c thi, l i th ng r t có ích n u b n tri u g i script t trong m t script khác Trong đo n ch ng trình trên, l nh exit s tr v 0, cho bi t script
th c thi thành công và thoát kh i shell g i nó M c dù khi đã l u t p tin script v i tên sh,
nh ng UNIX và Linux không b t bu c đi u này Hi m khi Linux s d ng ph n đuôi m
r ng c a t p tin làm d u hi u nh n d ng, do đó t p t p script có th là tùy ý Tuy v y sh
v n là cách chúng ta nh n ngay ra m t t p tin có th là script c a shell m t cách nhanh chóng
N u mu n Linux t đ ng nh th m c hi n hành m i khi đ ng nh p b n có th thêm l nh
PATH=$PATH : vào cu i t p bash_profile (file đ c tri u g i lúc h th ng đang nh p
- t ng t autoexec.bat c a DOS) Tuy nhiên cách g n và đ n gi n nh t mà ta v n
th ng làm là đ nh rõ d u th m c hiên hành / ngay trên l nh Ví d :
$ / first.sh
L u ý: i v i tài kho n root, không nên thay đ i bi n môi tr ng PATH (b ng cách thêm d u ch đ nh ) cho phép truy tìm th m c hi n hành i u này không an
toàn và d t o ra l h ng b o m t Ví d , m t qu n tr h đ ng nh p d i quy n root, tri u g i ch ng trình c a Linux mà h t ng th m c qui đ nh nh /bin,
n u bi n PATH cho phép tìm th m c hi n hành thì r t có th nhà qu n tr th c thi ch ng trình c a ai đó thay vì ch ng trình Linux /bin V y nên t o thói quen
đ t d u / tr c m t t p tin đ ám ch truy xu t th m c hi n hành
Trang 9M t khi b n tin r ng first.sh ch y t t, có th di chuy n nó đ n th m c khác thích
h p h n th m c hi n hành N u l nh script ch dành cho m c đích riêng c a b n, b n có
th t o ra th m c /bin trong th m c ch (home) mà nhà qu n tr qui đ nh cho ng i dùng, sau đó thêm đ ng d n này vào bi n môi tr ng PATH N u mu n script đ c g i
b i ng i dùng khác, hãy đ t nó vào th m c /usr/1ocal/bin Thông th ng, đ cho phép
m t script hay ch ng trình th c thi, c n đ c ng i qu n tr cho phép N u b n là nhà
qu n tr , c ng c n c n th n xem xét các script do các ng i dùng khác (hacker ch ng h n)
đ t vào h th ng Ngôn ng script r t m nh, nó có th làm đ c h u nh là m i chuy n
#chmod u=rwx go=rx /usr/1ocal/bin/firsc.sh
o n l nh trên mang ý ngh a: chuy n quy n s h u t p tin cho root, root đ c toàn quy n đ c s a n i dung và th c thi t p tin, trong khi nhóm và nh ng ng i dùng khác root ch đ c phép đ c và th c thi Nên nh m c dù b n lo i b quy n ghi w trên t p tin, UNTX và Linux v n cho phép b n xoá t p tin này n u th m c ch a nó có quy n ghi w
an toàn, v i t cách là nhà qu n tr , nên ki m tra l i th m c ch a script và b o đ m
r ng ch có root m i có quy n w trên th m c ch a các t p sh
3 CÚ PHÁP NGÔN NG SHELL
Chúng ta đã th y cách vi t l nh và g i th c thi t p tin scirpt Ph n ti p theo nay dành cho b n khám phá s c m nh c a ngôn ng l p trình shell Trái v i l p trình b ng trình biên d ch khó ki m l i và nâng c p, l p trình script cho phép b n d dàng s a đ i
l nh b ng ngôn ng v n b n Nhi u đo n script nh có th k t h p l i thành m t script
l n m nh m và r t h u ích Trong th gi i UNIX và Linux đôi lúc g i th c thi m t
ch ng trình, b n khó mà bi t đ c ch ng trình đ c vi t b ng script hay th c thi theo
mã c a ch ng trình nh phân, b i vì t c đ th c thi và s uy n chuy n c a chúng g n
nh ngang nhau Ph n này chúng ta s h c v :
• Bi n: ki u chu i, ki u s , tham s và bi n môi tr ng
• i u ki n: ki m tra lu n lý Boolean b ng shell
• i u khi n ch ng trình: if, elif, for , while, until, case
Trang 10Th ng b n không c n ph i khai báo bi n tr c khi s d ng Thay vào đó bi n s
đ c t đ ng t o và khai báo khi l n đ u tiên tên bi n xu t hi n, ch ng h n nh trong phép gán M c đ nh, t t c các bi n đ u đ c kh i t o và ch a tr ki u chu i (string) Ngay c khi d li u mà b n đ a vào bi n là m t con s thì nó c ng đ c xem là đ nh
d ng chu i Shell và m t vài l nh ti n ích s t đ ng chuy n chu i thành s đ th c hi n phép tính khi có yêu c u T ng t nh b n thân h đi u hành và ngôn ng C, cú pháp
c a shell phân bi t ch hoa ch th ng, bi n mang tên foo, Foo, và FOO là ba bi n khác nhau
Bên trong các script c a shell, b n có th l y v n i dung c a bi n b ng cách dùng
d u $ đ t tr c tên bi n hi n th n i dung bi n, b n có th dùng l nh echo Khi gán
n i dung cho bi n, b n không c n ph i s d ng ký t $ Ví d trên dòng l nh, b n có th gán n i dung và hi n th bi n nh sau:
$ xinahao=hello
$ echo $xinchao
Hello
$ xin chao= "I am here"
$echo $xin chao
I am here
$echo $xin chao
12+1
L u ý, sau d u = không đ c có kho ng tr ng N u gán n i dung chu i có kho ng
tr ng cho bi n, c n bao b c chu i b ng d u “ “
Có th s d ng l nh read đ đ c nh p li u do ng i dùng đ a vào và gi l i trong bi n
M t ti n trình Unix/Linux bao gi c ng g n li n v i các đ u x lí các dòng (stream) d
li u: đ u vào chu n (stdin hay 0), th ng là t bàn phím qua ch c n ng getty(); đ u ra chu n (stdout, hay 1), th ng là màn hình, và c s d li u l i h th ng (stderr, hay 2) Tuy nhiên các h ng vào/ra có th thay đ i đ c b i các thông báo đ c bi t:
Kí hi u Ý ngh a ( … t ng tr ng cho đích đ i h bg)
Trang 11> u ra h ng t i …
>> N i vào n i dung c a …
< L y đ u vào t < … << word đ u vào là đây …
2> đ u ra báo l i s h ng vào … 2>> đ u ra báo l i h ng và ghi thêm vào …
Ví d :
$date > login.time
L nh date không k t xu t ra đ u ra chu n (stdout) mà ghi vào t p login.time >login.time
không ph i là thành ph n c a l nh date, mà đ n gi n mô t ti n trình t o và g i k t xu t đâu (bình th ng là màn hình) Nhìn theo cách x lí thì nh sau: c c m l nh trên ch a
hai ph n: l nh date, t c ch ng trình th c thi, và thông đi p (>login.time) thông báo cho
shell bi t k t xu t l nh s đ c x lí nh th nào (khác v i m c đ nh B n thân date c ng không bi t chuy n k t xu t đi đâu, shell ch n m c đ nh)
Ví d :
$cat < file1
Bình th ng cat nh n và hi n th n i dung t p có tên (là đ i đ u vào) V i l nh trên cat
nh n n i dung t file1 và k t xu t ra màn hình Th c ch t không khác gì khi gõ:
Hãy xem:
$cat < file1 > file2
L nh này th c hi n nh th nào ? Theo trình t s nh sau: cat nh n n i dung c a file1 sau đó ghi vào t p có tên file2, không đ a ra stdout nh m c đ nh L nh cho th y ta có
th thay đ i đ u và đ u ra cho l nh nh th nào Nh ng l nh cho phép đ i đ u ra/vào g i chung là qúa trình l c (filter)
Ví d :
$cat file1 < file2
L nh này ch hi n th n i dung c a file1, không gì h n T i sao ? cat nh n đ i đ u vào là tên t p N u không có đ i nó nh n t stdin (bàn phím) Có đ i thì chính là file1 và đ u ra
là stdout Tr ng h p này g i là b qua đ i h ng Cái gì đây là quan tr ng ? u
$cat < badfile 2> errfile
Thông th ng các l i h th ng qu n lí đ u stderr và s in ra màn hình Tuy nhiên có th chuy n h ng báo l i, ví d vào m t t p (ch ng h n logfile) mà không đ a ra mahn hình
Ví d trên là nh v y Ta bi t stderr là t p có mô t t p = 2, do v y 2>errfile có ngh a đ i
đ u ra c a stderr vào m t t p, t c ghi báo l i vào t p xác đ nh
Trang 12Nh ng gì v a đ c p tác đ ng trên t p vào/ra Ta c ng có cách x lí ngay trong
m t dòng c a t p, cái đó g i là đ i h ng trong dòng (in-line Redirection) L ai này bao
là 1 dòng và c ng là d u hi u shell thông báo nó hòai v ng nh n nhi u (thông tin) đ u vào
ti n trình t ng tác (foreground), mà shell đi u khi n vi c ch y các ti n trình V i &
ch ng trình s t ch y và shell quay ngay v t ng tác v i ng i dùng, tr l i d u nh c ngay Ti n trình n n có nhi u cách đ ki m soát
Trang 13(Hãy xem k t xu t trên màn hình)
3 D u nháy ` ` (backquotes) (là d u phím đi cùng v i ~)
Hay còn g i là d u thay th B t kì l nh nào xu t hi n bên trong d u nháy s đ c th c
hi n tr c và k t qu c a l nh đó s thay th đ u ra chu n (stdout) tr c khi l nh trong dòng l nh th c hi n
Ví d :
$ echo Logged in `date` > login.time
s nói cho shell đi th c hi n date tr c tiên, tr c khi th c hi n các ph n khác còn l i
c a dòng l nh, t c sau đó m i th c hi n l nh echo V y cách di n đ t dòng l nh trên nh
sau:
echo Logged in Fri May 12:52:25 UTC 2004 > login.time
T c là: 1 th c hi n date v i k t qu Fri May 12:52:25 UTC 2004 không hi n ra stdout
(màn hình), nh ng s là đ u vào c a echo;
2 sau đó l nh echo s echo Logged in Fri May 12:52:25 UTC 2004, nh ng không
đ a ra màn hình (stdout) mà đ i h ng vào t p login.time
N u gõ $ cat login.time, ta có k t xu t t t p này ra màn hình:
Logged in Fri May 12:52:25 UTC 2004
Trang 14Tóm t t:
cmd & đ t l nh cmd ch y n n (background)
cmd1 ; cmd2 ch y cmd1 tr c, sau đó ch y cmd2
(cmd) th c hi n cmd trong m t shell con (subshell)
`cmd` đ u ra c a cmd s thay cho đàu ra c a l nh trong dòng l nh
echo "message : $myvar"
echo 'message : $myvar'
echo "messgae :\$myvar"
echo Enter some text
read myvar
echo '$myvar' now equals $myvar
Trang 15Bi n myvar đ c t o ra và kh i gán giá tr chu i Hi there N i dung c a bi n sau
đó đ c hi n th b ng l nh echo trong các tr ng h p b c chuôi b ng nháy kép, nháy đ n
và d u hi n th ký t đ c bi t \ Tóm l i 'n u mu n thay th n i dung bi n trong m t chu i, c n b c chu i b ng nháy kép N u mu n hi n th toàn b n i dung chu i, hãy dùng nháy đ n
3.1.2 Biên môi tr ng (environment variable)
Khi trình shell kh i đ ng nó cung c p s n m t s bi n đ c khai báo và gán tr
m c đ nh Chúng đ c g i là các bi n môi tr ng Các bi n này th ng đ c vi t hoa đ phân bi t v i bi n do ng i dùng t đ nh ngh a (th ng là ký t không hoa) N i dung các bi n này th ng tùy vào thi t l p c a h th ng và ng i qu n tr cho phép ng i dùng h th ng s d ng Danh shell c a các bi n môi tr ng là khá nhi u, nh ng nhìn chung nên nh m t s bi n môi tr ng ch y u sau:
$IFS D u phân cách các tr ng trong danh shell chu i Bi n này ch a
danh shell các ký t mà shell dùng tách chu i (th ng là tham s trên dòng l nh) Ví d $IFS th ng ch a ký t Tab, ký t tr ng
ho c ký t xu ng hàng
$0 Ch a tên ch ng trình g i trên dòng l nh
$# S tham s truy n trên dòng l nh
$$ Mã ti n trình (process id) c a shell script th c thi B i s process
id c a ti n trình là duy nh t trên toàn h th ng vào lúc script th c thi nên th ng các l nh trong script' dùng con s này đ t o các tên file t m Ví d /tmp/tmpfile_$$
Trang 16M i môi tr ng mà uer đ ng nh p ch a m t s danh shell bi n môi tr ng dùng cho m c
đích riêng Có th xem đanh shell này b ng l nh env t o m t bi n môi tr ng m i,
có th dùng l nh export c a shell (m t s shell s d ng l nh setenv)
3.1.3 Bi n tham s (parameter variable)
N u c n ti p nh n tham s trên dòng l nh đ x lý, có th dùng thêm các bi n môi
tr ng sau:
Bi n tham s Ý ngh a
$1, $2, $3 V trí và n i dung c a các tham s trên dòng l nh theo th t t
trái sang ph i
S* Danh shell c a t t c các tham s trên dòng l nh Chúng đ c l u
trong m t chu i duy nh t ph n cách b ng ký t đ u tiên quy đ nh trong bi n $IFS
$@ Danh shell các tham s đ c chuy n thành chu i Không s d ng
foo bar bam
Ta nh n th y, l nh set ti p nh nn 3 tham s trên dòng l nh là foo bar bam Chúng nh
h ng đ n bi n môi tr ng $* và $@ Khi IFS đ c qui đinh là ký t ^ , $* ch a danh shell các tham s phân cách b ng ký t ^ Khi đ t IFS v NULL b ng l nh unset, bi n $*
tr v danh shell thu n tuý c a các tham s t ng t bi n $@
Bi n $# s ch a s tham s c a l nh, trong tr ng h p trên ta có:
$echo " $ # "
3
Khi l nh không có tham s thì $0 chính là tên l nh còn $# tr v giá tr 0
o n trình m u sau s minh h a m t s cách đ n giãn x lý và truy xu t bi n môi
Trang 17echo "The second parameter was $2"
echo "The first parameter was $1"
echo "The parameter list was $*"
echo "The user's home directory is $HOME"
echo "Please enter a new greeting"
$./try_variables.sh foo bar baz
Hello
The program /try_vanables.sh is now running
The second parameter was bar
The first parameter was foo
The parameter list was foo bar baz
The user's home directory is /home/xyz #tên ng i dùng login là xyz
please enter a new greeting
The scnpt is now complete
3.2 i u ki n
N n t ng c b n trong t t c ngôn ng l p trình, đó là kh n ng ki m tra đi u ki n
và đ a ra quy t đ nh r nhánh thích h p tùy theo đi u ki n đúng hay sai Tr c khi tìm
hi u c u trúc đi u khi n c a ngôn ng script, ta hãy xem qua cách ki m tra đi ki n
M t script c a shell có th ki m tra mã l i tr v c a b t k l nh nào có khá n ng tri u g i t dòng l nh, bao g m nh ng t p tin l nh script khác Ó là lý do t i sao chúng ta th ng s d ng l nh exit cu i m i scipt khi k t thúc
3.2.1 L nh test ho c [ ]
Th c t , các script s d ng l nh [] ho c test đ ki m tra đi u ki n boolean r t
th ng xuyên Trong h u h t các h th ng UNIX và Linux thì [ ] và test có ý ngh a t ng
t nhau, th ng l nh [ ] đ c dùng nhi u h n L nh [ ] trông đ n gi n, d hi u và r t g n
v i các ng l p trình khác
Trong m t s shell c a Unix, l nh test có kh n ng là m t l i tri u g i đ n
ch ng trình bên ngoài ch không ph i l nh n i t i c a ngôn ng script B i vì
Trang 18test ít khi đ c dùng và h u h t các l p trình viên có thói quen th ng t o các
ch ng trình v i tên test, cho nên khi th l nh test không thành công bên trong script, thì hãy xem l i đây đó bên trong h th ng có m t ch ng trình tên là test khác bi t nào đó đang t n t i Hãy th dùng l nh which test, l nh này s tr v
cho b n đ ng d n đ n th m c test đ c tri u g i Ch ng h n /bin/test hay /usr/bin/test
D c đây là cách s d ng l nh test đ n gi n nh t Dùng l nh test đ ki m tra xem file mang tên hello.c có t n t i trong h th ng hay không L nh test trong tr ng h p này
có cú pháp nh sau: test -f <mename>, trong script ta có th vi t l nh theo cách sau:
N u thích đ t t khóa then chung m t dòng v i l nh if, b n ph i phân cách then
stringl = string2 true n u 2 chu i bàng nhau (chính xác t ng ký t )
tring1 != string2 true n u 2 chu i không b ng nhau
-n string1 true n u string1 không r ng
-z stringl true n u string1 r ng (chu i null)
So sánh toán h c
expression1 -eq expression2 true n u hai bi u th c b ng nhau
expression1 -ne expression2 true n u hai bi u th c không b ng nhau
Trang 19expression1 -gt expression2 true n u bi u th c expression1 l n h n expression2 expreesion1 -ge expression2 true n u bi u th c expression1 l n h n hay b ng
expression2
expression1 -lt expression2 true n u bi u th c expression1 nh h n expression2 expression1 -le exprebbion2 true n u bi u th c expression1 nh h n hay b ng
expression2
!expression true n u bi u th c expression là false (toán t not)
Ki m tra đi u ki n trên t p tin
-d file true n u file là th m c
-e file true n u file t n t i trên đ a
-f file true n u file là t p tin thông th ng
-g file true n u set-group-id đ c thi t l p trên file
-r file true n u file cho phép đ c
-s f ile true n u kích th c file khác 0
-u file true n u set-ser-id đ c áp đ t trên file
-w file true n u file cho phép ghi
-x file true n u file đ c phép th c thi
L u ý v m t l ch s thì tùy ch n -e không kh chuy n (portable) và -f th ng đ c s
d ng thay th
Câu h i có th đ t ra là group-id và ser-id (còn đ c g i là gid và uid) mang ý ngh a gì Set-uid cho phép ch ng trình quy n c a ch th s h u (owner) thay vì quy n c a user thông th ng T ng t set-gid cho phép ch ng trình quy n c a nhóm
set-T t cá các đi u ki n ki m tra t p tin đ u yêu c u file ph i t n t i tr c đó (có
ngh a là l nh test -f filename ph i đ c g i tr c) L nh test hay [ ] còn có thêm nhi u
đi u ki n ki m tra khác n a, nh ng hi n th i ta ch a dùng đ n Có th tham kh o chi ti t
test b ng l nh help test t d u nh c c a h th ng
3.3 C u trúc đi u khi n
Shell cung c p c u trúc l nh đi u khi n r t gi ng v i các ngôn ng l p trình khác
đó là if, elif, for, while, until, case i v i m t vài c u trúc l nh (ví d nh case), shell
đ a ra cách x lý uy n chuy n và m nh m h n Nh ng c u trúc đi u khi n khác n u có thay đ i ch là nh ng thay đ i nh không đáng k
Trong các ph n sau statements đ c hi u là bi u th c l nh (có th bao g m m t
t p h p các l nh) s đ c th c thi khi đi u ki n ki m tra condition đ c tho
mãn
1 3.3.1 L nh if
L nh if tuy đ n gi n nh ng đ c s d ng nhi u nh t if ki m tra đi u ki n đúng
ho c sai đ th c thi bi u th c thích h p
Trang 20if [ $timeofday = "yes" ]; then
echo "Good morning"
ví d trên chúng ta đã s d ng cú pháp [ ] đ ki m tra đi u ki n thay cho l nh test
Bi u th c ki m tra xem n i dung c a bi n $timeofday có kh p v i chu i "yes" hay không N u có thì l nh echo cho in ra chu i “Good morningg”, n u không (m nh đ else)
in ra chu i “Goođ afternoon"
Shell không đòi h i ph i canh l hay th t đ u dòng cho t ng l nh Chúng ta canh
l đ có pháp đ c rõ ràng M c dù v y sau này b n s th y ngôn ng c a
ch ng trình make s yêu c u canh l và xem đó là yêu c u đ nh n d ng l nh
3.3 2 L nh elif
Th t không may, có r t nhi u v n đ phát sinh v i đo n trình script trên T t c tr
l i khác v i “yes” đ u có ngh a là “no” Chúng ta có th kh c ph c đi u này b ng cách dùng c u trúc đi u khi n elif M nh đ này cho phép ki m tra đi u ki n l n th hai bên
trong else Script d i đãy c a có th đ c s a đ i hoàn ch nh h n, bao g m c in ra thông báo l i n u ng i dùng không nh p đúng câu tr l i “yes” ho c “no”
Ví du 3-4: elif_control.sh
Trang 21#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
if [ $timeofday = "yes" ]; then
echo "Good morning"
elif [ $timeofday = "no" ]; then
echo "Good afternoon"
C ng đ n gián nh ví d 3-3, nh ng chúng ta s d ng thêm elif đ ki m tra tr ng h p
ng i dùng không nh p “no" Thông báo l i đ c in ra và mã l i tr v b ng l nh exit là
1 Tr ng h p ho c “yes” ho c “no” đ c nh p vào, mã l i tr v s là 0
3.3.3 V n đ phát sinh v i các bi n
elif trong ví d trên kh c ph c đ c h u h t các đi u ki n nh p li u và yêu c u
ng i dùng nh p đúng tr c khi ra quy t đ nh th c thi ti p theo M c dù v y, có m t v n
đ khá tinh t còn l i, n u ch y l i elif_control.sh nói trên, nh ng thay vì nh p vào m t
chu i nào đó, hãy gõ Enter (t o chu i r ng cho bi n $timeofday), s nh n đ c thông báo
l i c a shell nh sau:
[ : = : unary operator expected
i u gì x y ra ? L i phát sinh ngay m nh đ if đ u tiên Khi bi n timeofday đ c ki m
tra nó cho tr là r ng và do đó l nh if s đ c shell di n d ch thành:
if [= “yes " ]
và d nhiên shell không hi u ph i so sánh chu i “yes" v i cái gì tránh l i này c n b c
n i dung bi n b ng d u bao chu i nh sau:
Trang 22Ví du: 3-5: elif_control2.sh
#!/bin/sh
echo -n "Is it morning? Please answer yes or no: "
read timeofday
if [ "$timeofday" = "yes" ]; then
echo "Good morning"
elif [ "$timeofday" = "no" ]; then
echo "Good afternoon"
Hãy ki m tra l i elif_controi2.sh b ng cách chi nh n Enter khi shell đ a ra câu
h i Script gi đây ch y r t b o đ m và chu n
L nh echo th ng xu ng hàng sau khi đ a ra thông báo Có th đùng l nh printf
(s đ c p ph n sau) thay cho echo M t vài shell cho phép l nh echo -e trên
m t dòng, nh ng chúng không ph i là ph bi n đ b n s d ng
3.3.4 L nh for
S d ng for đ l p l i m t s l n v i các giá tr xác đ nh Ph m vi l p có th n m trong m t t p h p chu i ch đ nh t ng minh b i ch ng trình hay là k t q a tr v t
Trang 23i u gì s x y ra n u b n thay th l nh for foo in barr fud 13 thành for foo in
“bar fud 13” Hãy nh l i, d u nháy kép cho phép coi t t c n i dung bên trong nháy kép là m t bi n chu i duy nh t K t qu k t xu t n u s d ng d u nháy kép,
l nh echo ch đ c g i m t l n đ in ra chu i "bar fud 13 "
for th ng dùng đ duy t qua danh shell tên các t p tin B ng cách dùng ký t đ i di n * (wildcard) ví d first.sh, ta đã th y cách for tìm ki m t p tin k t h p v i l nh grep Ví
d sau đây cho th y vi c m r ng bi n thành t p h p s d ng trong l nh for Gi s b n
Ví d trên đây c ng cho th y cách s d ng cú pháp $(command) (s đ c chúng
ta tìm hi u chi ti t h n trong ph n sau) Danh shell c a các ph n t trong l nh for đ c
cung c p b i k t qu tr v c a l nh ls f* và đ c b c trong c p l nh m r ng bi n $ ( )
Bi n m r ng n m trong d u bao $ (command) ch đ c xác đinh khi l nh command th c thi xong
3.3.5 L nh while
M c dù l nh for cho phép l p trong m t t p h p giá tr bi t tr c, nh ng trong
tr ng h p m t t p h p l n ho c s l n l p không bi t tr c, thì for không thích h p Ví
Trang 24while [ "$trythis" != "secret" ]; do
echo "Sorry, try again"
M c dù đ password hi n th khi nh p li u rõ ràng là không thích h p, nh ng
đây ta ch y u minh h a l nh while L nh while liên t c ki m tra n i dung bi n $trythis,
yêu c u nh p l i d li u b ng l nh read m t khi $trythis v n ch a b ng v i chu i "secret
"
B ng cách s d ng bi n đ m và bi u th c so sánh toán h c, while hoàn tòan có th thay
th for trong tr ng h p t p d li u l n H theo dõi ví d sau:
Trang 25c l ng m t bi u th c V i các shell c khác có th thay th cú pháp này b ng
l nh expr Tuy nhiên expr không hi u qu B t c khi nào, n u có th hãy nên dùng $ ( ( ) ) thay cho expr
script while_for.sh s d ng l nh [ ] đ ki m tra giá tr c a bi n $foo v n còn nh h n hay
b ng 16 hay không N u còn, l nh l p while s in ra t ng c ng d n c a bi n $foo
L nh until t ng t l nh while nh ng đi u ki n ki m tra bi đ o ng c l i Vòng l p s b
d ng n u đi u ki n ki m tra là đúng Ví d sau s s d ng l nh until đ ch m t user nào
đó đ ng nh p:1
Ví d 3-10: until_user.sh
#!/bin/sh
echo "Locate for user "
until who | grep "$1" > /dev/null
th l nh này, n u ch y ngoài màn hình console, hãy dùng hai màn hình o (Alt+F1 và
Alt+F2), m t màn hình dùng ch y script until_user.sh, màn hình kia dùng đ ng nh p v i tên user mu n ki m tra N u trong ch đ đ h a, b n có th m hai c a s terminal và s
d hình dung h n Hãy ch y until_user.sh t m t màn hình nh sau:
$./until_user.sh xyz
Locate for user
Script s r i vào vòng l p ch user tên là xyz d ng nh p Hãy nh p t m t màn hình khác (v i user tên là xyz), ta s th y màn hình đ u tiên đ a ra thông báo cho th y vòng l p until ch m d t
* * * * * xyz has just logged in * * * * *
Cách ch ng trình làm vi c:
Trang 26L nh who l c danh shell các user đ ng nh p vào h th ng, chuy n danh shell này
cho grep b ng c ch đ ng ng ( | ) L nh grep l c ra tên user theo bi n môi tr ng $1
hi n có n i dung là chu i xyz M t khi l nh grep l c ra đ c d li u, nó s chuy n ra
vùng t p tin r ng /dev/null và tr l i giá tr null, l nh until k t thúc
3.3.7 L nh case
L nh case có cách s d ng h i ph c t p h n các l nh đã h c Cú pháp c a l nh
case nh sau:
case variable in
pattern [ | partten] ) statements;;
pattern [ | partten] ) statements;;
esac
M c dù m i nhìn h i khó hi u, nh ng l nh case r t linh đ ng case cho phép th c
hi n so kh p n i dung c a bi n v i m t chu i m u pattern nào đó Khi m t m u đ c so
kh p, thì (l nh) statement t ng ng s đ c th c hi n Hãy l u ý đ t hai d u ch m nh y
;; phía sau m i m nh đ so kh p pattern, shell dùng d u hi u này đ nh n d ng m u
pattern so kh p ti p theo mà bi n c n th c hi n
Vi c cho phép so kh p nhi u m u khác nhau làm case tr nên thích h p cho vi c
ki m tra nh p li u c a ng i dùng Chúng ta hãy xem l i ví d 3-4 v i phiên b n vi t
"yes") echo "Good Morning";;
"no" ) echo "Good Afternoon";;
"y" ) echo "Good Morning";;
"n" ) echo "Good Afternoon";;
* ) echo "Sorry, answer not recognised";;
esac
exit 0
Cách th c hi n: Sau khi ng i dùng nh p vào câu tr l i, l nh case s l y n i dung c a
bi n $timeofday so sánh v i t ng chu i Khi g p chu i thích h p nó s th c thi l nh đ ng
sau d u ) và k t thúc (không ti p t c so kh p v i các m u khác) Ký t đ i di n * cho phép so kh p v i m i lo i chu i * th ng đ c xem nh tr ng h p so sánh đúng cu i cùng n u các m u so sánh tr c đó th t b i B n có th xem * là m nh đ default trong
l nh switch c a C hay case … else c a Pascal
Vi c so sánh th ng th c hi n t m u th nh t tr xu ng cho nên b n đ ng bao
Trang 27gi đ t * đ u tiên, b i vì nh th b t k chu i nào c ng đ u th a mãn case Hãy đ t
nh ng m u d x y ra nh t trên đ u, ti p theo là các m u có t n s xu t hi n th p Sau cùng m i đ t m u * đ x lý m i tr ng h p còn l i N u mu n có th dùng m u * đ t xen gi a các m u khác đ theo dõi (debug) l i c a ch ng trình (nh in ra n i dung c a
"yes" | "y" | "Yes" | "YES" ) echo "Good Morning";;
"n*" | "N*" ) echo "Good Afternoon";;
* ) echo "Sorry, answer not
ra Cách vi t này th c t th ng dùng và d đ c h n cách vi t th nh t M c dù v y, hãy
th tìm hi u case m t ví d sau cùng này case s d ng l nh exit đ tr v mã l i cho
"yes" | "y" | "Yes" | "YES" )
echo "Good Morning"
echo "Up bright and early this morning?"
echo "Sorry, answer not recognised"
echo "Please answer yes or no"
exit 1
Trang 28Có th không c n đ t ;; m u so kh p cu i cùng trong l nh case (phía tr c esac), vì không còn m u so kh p nào c n th c hi n n a Không nh C yêu c u
ph i đ t l nh break m i m nh đ case, shell không đòi h i đi u này, nó bi t t
đ ng ch m d t khi l nh case t ng ng đã tìm đ c m u tho mãn
làm case tr nên th nh m và so sánh đ c nhi u tr ng h p h n, có th gi i h n các
ký t so sánh theo cách sau: [yy] | [Yy] [Ee] [Ss], Khi đó y,Y hay YES, YES, đ u đ c xem là yes Cách này đúng h n là dùng ký t thay th toàn b * trong tr ng h p [nN]*
3.4 Danh shell th c thi l nh (Lists)
ôi lúc c n k t n i các l nh l i v i nhau th c hi n theo th t ki m tra tr c khi
ra m t quy t đ nh nào đó, ví d , c n ki m tra hàng lo t đi u ki n ph i đúng b ng if tr c khi in ra thông báo nh sau:
Trang 29Hoàn toàn có th dùng if đ th c hi n các yêu c u trên, nh ng chúng không thu n ti n
l m Shell cung c p m t cú pháp danh shell AND và OR g n h n Chúng th ng s d ng chung v i nhau, nh ng ta hãy t m th i xét chúng tách bi t đ d hình dung
3.4.1 Danh sách AND (&&)
Danh shell AND cho phép th c thi m t chu i l nh k nhau, l nh sau ch th c hi n khi l nh tr c đã th c thi và tr v mã l i thành công Cú pháp s d ng nh sau:
Statement1 && statement2 && statement3 &&
B t đ u t bên trái statement1 s th c hi n tr c, n u tr v true thì statement2 ti p t c
đ c g i N u statement2 tr v false thì shell ch m d t danh shell AND ng c l i
statement3 s đ c g i Toán t && dùng đ ki m tra k t q a tr v c a statement
tr c đó
K t qu tr v c a AND s là true n u t t c các l nh statement đ u đ c g i th c
thi Ng c l i là false
Hãy xét ví d sau, dùng l nh touch file_one (đ ki m tra file_one t n t i hay ch a,
n u ch a thì t o m i) ti p đ n rm file_two Sau cùng danh shell AND s ki m tra xem các file có đ ng th i t n t i hay không đ đ a ra thông báo thích h p
Cách ch ng trình làm vi c: L nh touch và rm đ m b o r ng file_one t n t i và file_two
không có Trong danh shell bi u th c if, && s g i l nh [-f file_one ] tr c L nh này thành công vì touch đã t o s n file_one L nh echo ti p t c đ c g i echo luôn tr v tr true nên l nh ti p theo
[-f file_two] thi hành Do file_two không t n t i nên echo "there" không đ c g i Toàn
b bi u th c tr v tr false (vì các l nh trong danh shell không đ c th c thi h t) Do if
nh n tr false nên echo trong m nh đ else c a l nh if đ c g i
Trang 303.4.2 Danh sáchl OR ( || )
Danh shell OR c ng t ng t v i AND là th c thi m t dãy các l nh, nh ng n u
có m t l nh tr v true thì vi c th c thi ng ng l i Cú pháp nh sau:
statementl || statement2 || statement3 &&
B t đ u t bên trái, statementl đ c g i th c hi n, n u statement1 trá v false thì
statement2 đ c g i, n u statement2 tr v true thi bi u th c l nh ch m đ t, ng c l i
statement3 đ c g i K t q a sau cùng c a danh shell OR ch đúng (true) khi có m t
trong các statement tr v true N u && g i l nh ti p theo khi các l nh tr c đó true, thì
ng c l i || g i l nh ti p theo khi l nh tr c đó false
Ví d 3-14 c a danh shell AND có th s a l i thành OR nh sau:
L u ý, danh shell AND và OR s d ng thu t toán th m đ nh t t 1 bi u th c, có ngh a là ch c n m t l nh sai ho c đúng thì coi nh toàn b bi u th c s có cùng chân tr i u này cho th y không ph i m i bi u th c hay l nh c a trong danh shell AND / OR đ u đ c c l ng Hãy đ t các bi u th c hay l nh có đ u tiên cao v bên trái Xác su t c l ng chúng s cao h n các bi u th c hay l nh
n m bên ph i
K t h p c AND và OR s x lý đ c h u nh m i tr ng h p logic trong l p trình Ví
d :
Trang 31[ -f flle_one] && command_for_true || command_for_false
Cú pháp trên b o đ m r ng n u [ -f file_one ] tr v true thì command_for_true s đ c
g i Ng c l i command_for_false s th c thi (m t cách vi t ng n g n khác c a if else)
T ng t các ng trình khác, shell cho phép b n t t o hàm hay th t c đ tri u
g i bên trong script M c dù b n có th g i các script con khác bên trong script chính, chúng t ng t nh vi c g i hàm Tuy nhiên tri u g i các script con th ng tiêu t n tài nguyên và không hi u qu b ng tri u g i hàm
đ nh ngh a hàm, b n khai báo tên hàm ti p theo là c p ngo c đ n ( ) , l nh c a hàm n m trong ngo c nh n { } Cú pháp nh sau:
function_name ( ) {
Statements }
Hãy làm quen v i cách s d ng hàm b ng ví d đ n gi n sau:
Trang 32K t qu k t xu t khi b n ch y script hi n th nh sau
l nh echo "script starting" Khi g p l i foo l n th hai, shell bi t là ta mu n tri u g i hàm, shell quay l i th c hi n n i dung c a hàm foo() M t khi ch m d t l i g i hàm, dòng l nh
ti p theo sau hàm s đ c th c thi Nh ta th y, c n ph i khai báo và đ nh ngh a hàm
tr c khi s d ng và g i nó bên trong script i u này t ng t cách qui đ nh c a Pascal
và C, tuy nhiên shell không cho phép b n khai báo hàm ki u ch nêu nguyên m u c a hàm (forward), mà ch a c n đinh ngh a n i dung chi ti t hàm
3.5.1 Bi n c c b và bên toàn c c
khai báo bi n c c b ch có hi u l c bên trong hàm, hãy dùng t khóa local
N u không có t khóa local, các bi n s đ c xem là toàn c c (global), chúng có th t n
t i và l u gi k t quá ngay sau khi hàm đã ch m d t Bi n toàn c c đ c nhìn th y và có
th thay đ i b i t t c các hàm trong cùng script Tr ng h p đã có bi n toàn c c nh ng
l i khai báo bi n c c b cùng tên, bi n c c b s có giá tr u tiên và hi u l c cho đ n khi hàm ch m d t
Ví d 3-17 function2.sh
#!/bin/sh
sample_text="global variable"
foo() {
local sample_text="local variable"
echo "Function foo is executing"
Trang 33K t q a k t xu t
$./function2.sh
script starting
global variable
Function foo is executing
local variable #sample_text is local in function
foo "paraml", "param2", param3
V y làm cách nào hàm nh n và l y v đ c n i dung đ i s truy n cho nó? Bên trong hàm, ta g i các bi n môi tr ng $*, $1, $2 chúng chính là các đ i s truy n vào khi hàm đ c g i L u ý, n i dung c a $*, $1, $2 do bi n môi tr ng n m gi s đ c shell
t m th i c t đi M t khi hàm ch m d t, các giá tr c s đ c khôi ph c l i
M c dù v y, có m t s shell c trên UNIX không ph c h i tham s môi tr ng v giá tr ban đ u khi hàm k t thúc N u mu n b o đ m, hãy nên t l u tr các bi n tham s
Trang 34môi tr ng tr c tri u g i hàm Tuy nhiên các shell m i và nh t là n u ch mu n h ng
v Linux, thì không c n lo l ng đi u này
echo "In function parameters are $*"
echo "Param 1 $1 and Param2 $2"
echo "Original parameters are $*"
if yes_or_no "Is your name” “ $1?"
Original parameters are HoaBinh SV
In function parameters are Is your name HoaBinh
Param 1 Is your name param 2 HoaBinh
Is your name HoaBinh ?
Enter yes or no : yes
Hi HoaBinh, nice name
Cách làm làm vi c: Hàm yes_or_no( ) đ c đ nh ngh a khi script th c thi nh ng ch a
đ c g i Trong m nh đ if, hàm yes_or_no đ c s d ng v i tham s truy n cho ham là
n i dung c a bi n môi tr ng th nh t ( ví d trên $1 đ c thay th b ng HoaBinh) và chu i “Is your name” Bên trong hàm n i dung c a $1 và $2 đ c in ra (Hãy đ ý là chúng khác v i giá tr $1, $2 c a môi tr ng shell ban đ u) Hàm yes_or_no xây d ng
c u trúc case tùy theo l a ch n c a ng i dùng mà tr v tr 0 hay 1 Khi ng i dùng
ch n yes, hàm trá v giá tr 0 (true) L nh bên trong if đ c g i đ in ra chu i "nice
Trang 35name"
3.6 Các l nh n i t i c a shell
Ngoài các l nh đi u khi n, shell còn cung c p cho các l nh n i t i (build-in) khác
r t h u ích Chúng đ c g i là l nh n i t i b i vì không th th y chúng hi n h u nh
nh ng t p tin th c thi trong m t th m c nào đó trên h th ng t p (Có th xem nh ng
l nh này t ng t khái ni m l nh n i trú c a DOS) Trong quá trình l p trình shell, chúng
s th ng xuyên đ c s d ng
3.6.1 break
T ng t ngôn ng C, shell cung c p l nh break đ thoát kh i vòng l p for,
while ho c until b t k đi u ki n thoát c a các l nh này có di n ra hay không
L nh break th ng ng t ngang logic c a ch ng trình , vì v y nên h n ch dùng
break L nh break không có tham s cho phép thoát kh vòng l p hi n hành N u đ t tham s cho l nh ví d , break 2, break 3 ch ng h n, có th thoát kh i nhi u vòng l p cùng
m t lúc Tuy nhiên chúng s làm cho ch ng trình khó theo dõi T t nh t ta.nên
dùng.break không tham s
3.6.2 continue
L nh continue th ng đ c dùng bên trong vòng l p, continue yêu c u quay l i
th c hi n b c l p k ti p mà không c n th c thi các kh i l nh còn l i
Trang 36c u quay l i duy t ti p file khác Ng c l i l nh echo s in ra tên t p
continue còn cho phép truy n tham s đ xác đ nh s l n l p c n quay l i
L nh : đ c g i là l nh r ng (null command) ôi lúc l nh này đ c đùng v i ý
ngh a logic là true Khi dùng l nh : th c thi nhanh h n vi c so sánh true
M t s shell c còn s d ng l nh : v i ý ngh a chú thích m t dòng l nh Tuy nhiên b t k khi nào có th , hãy nên dùng # thay cho chú thích b ng :
Ví d : 3-21 colon.sh
#!/bin/sh
Trang 37L nh dùng đ g i th c thi m t script trong shell hi n hành i u này có v h i
l , vì ch c n gõ tên script là script có th t th c thi mà không c n t i , tuy v y nó có
m t ý ngh a đ c bi t: thi hành và gi nguyên nh ng thay đ i v môi tr ng mà script tác
đ ng (xem l i fork() và exec())
Thông th ng, khi th c thi m t script, shell s b o l u l i toàn b bi n môi tr ng
hi n hành và t o ra m t môi tr ng m i (hay shell ph - sub shel1) đ script ho t đ ng
M t khi script ch m d t b ng l nh exit, thì toàn b thông s môi tr ng c a shell hi n hành s đ c khôi ph c l i
echo “Script end”
Tr c khi ch y, hãy in ra n i dung c a bi n PATH trong shell hi n hành Ti p đ n ch y
do_command.sh b ng l nh và in l i k t qu c a PATH nh sau:
Trang 38L nh eval cho phép c l ng m t bi u th c ch a bi n Cách d hi u nh t là xem
eval làm vi c trong ví d sau:
K t qu in ra s là 10 Lý do y = '$' $x s đ c di n d ch thành chu i y=$x L nh eval ti p
đ n s c l ng y=$x nh là bi u th c gán K t qu là y mang giá tr c a n i dung bi n
x (10) eval r t h u d ng, cho phép sinh ra các đo n l nh th c thi đ ng ngay trong quá trình script thi hành
3.6.6 exec
L nh exec dùng đ g i m t l nh bên ngoài khác Th ng exec g i m t shell ph
khác v i shell mà script đang th c thi
Ví d 3-23: exec_demo.sh
#! /bin/sh
echo "Try to execute mc program"
exec mc
echo "you can not see this message !"
o n script in ra chu i thông báo sau đó tri u g i mc exec s ch cho ch ng trình g i
th c thi xong m i ch m d t script hi n hành
M c đinh exec s tri u g i exit khi k t thúc l nh Chính vì v y, n u g i exec ngay t
dòng l nh, sau khi l nh th c hi n xong, đi u khi n s thoát ra kh i shell ph , quay tr v shell g c, là màn hình đ ng nh p
Trang 393.6.7 exit n
L nh exit s thoát kh i shell nào g i nó và tr v mã tr ng thái l i n Tr c gi ta
v n g i exit 0 bên trong shell ph N u g i exit ngay t dòng l nh, nó s khi n thoát kh i
shell chính tr v màn hình đ ng nh p luôn (đây c ng là cách th ng dùng đ thoát kh i user hi n hành, đ ng nh p làm vi c d i tên user khác)
exit r t h u d ng trong các script, nó tr v mã l i cho bi t script đ c th c thi thành công hay không Mã l i 0 có ngh a là thành công Các giá tr t 1-125 script tùy nghi s d ng cho nhi u m c đích khác nhau Các giá tr còn l i đ c dành cho m c đích riêng C th là:
126 file không th th c thi
127 L nh không tìm th y
L n h n 128 ã nh n đ c tín hi u (signal) phát sinh
S d ng 0 là giá tr thành công có th gây l m l n cho m t s l p trình viên C ( đó 0
đ c coi là false còn khác 0 là true) Tuy nhiên b ng cách này, u đi m là có th t n
d ng các giá tr khác 0 làm mã qui đ nh l i, không c n ph i dùng thêm bi n toàn c c đ
N u mu n, có th đ i l nh if sang c u trúc danh sách l nh && hay || nh sau:
[ -f profile ] && exit 0 || exit 1
3.6.8 export
Khi b t đ u th c thi m t shell, các bi n môi tr ng đ u đ c l u l i Khi có khai báo và s d ng bi n trong m t script, nó ch có giá tr đ i v i shell ph g i script đó
bi n có th th y đ c t t c các script trong shelll ph hay các script g i t shell khác,
hãy dùng l nh export L nh export có tác d ng nh khai báo bi n toàn c c Ví d sau s cho th y cách s d ng export
Ví d 3-25 export2.sh
echo "Value : $foo”
echo "Value : $bar"
Ví d 3-26 export1.sh #xu t bi n ra toàn c c
Trang 40Value: This is bar
Dòng đ u cho k t qu bi n $foo r ng vì foo không đ c khai báo toàn c c t export1.sh, nên export2.sh không th y đ c bi n Dòng th 2 cho k t qu là n i dung c a bi n $bar
do b t đ c khai báo b ng export Bi n bar tr nên toàn c c và các script khác nhìn th y
bar
N u mu n t t c các bi n m c đ nh là toàn c c trong t t c các script, có th g i
l nh set –a hay set-allexport tr c khi thi t l p n i dung cho bi n
3.6.9 L nh expr
L nh expr tính các đ i đ u vào nh m t bi u th c Th ng expr đ c dùng tr ng
vi c tính toán các k t q a toán h c khi đ i giá tr t chu i sang s Ví d :
x= “12"
x= `expr $x + 1`
K t qu x=13 L u ý, c p d u ‘ ‘ b c bi u th c expr không ph i là d u nháy đ n (Ký t này là phím n m d i phím ESC và bên trái phím 1, chung v i phím ~ Các toán h ng và toán t ph i cách nhau b ng kho ng tr ng đây $x và 1 cách ký t + kho ng tr ng N u
đ chúng sát nhau, khi di n d ch shell s báo l i bi u th c
D i đây là m t s bi u th c c l ng mà expr cho phép:
Bi u th c Ý ngh a axprl | expr2 K t qu là expr1 n u expr1 khác 0 ng c l i là
expr2 axprl & expr2 0 n u m t trong hai bi u th c là zero ng c l i k t
qu là expr1 exprl = expr2 B ng
exprl >expr2 L n h n
exprl < expr2 Bé h n
exprl <= expr2 Bé h n hay b ng
exprl != expr2 không b ng
exprl + expr2 C ng