chuong 3 - lap trinh shell

Post on 02-Aug-2015

343 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

1

2

Linux và Shell

Sử dụng Shell như ngôn ngữ lập trình

Sử dụng biến

Cấu trúc điều khiển

Danh sách thực thi

Hàm

Dữ liệu kiểu mảng, chuỗi

Các lệnh nội tại của Shell

Lấy kết quả của một lệnh

Debug

Lập trình C shell

• Shell:

– Là trình diễn dịch trung gian, cung cấp khả năng giao tiếp với hạt nhân, gọi là hệ vỏ (shell)

• Linux cung cấp các Shell tương tác rất mạnh mẽ.

• Shell có thể diễn dịch và cho phép người dùng script dưới dạng ngôn ngữ C.

• Shell dịch các lệnh ta 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

3

Tương tác giữa Shell, chương trình ứng dụng, hệ X-Window và

hạt nhân Linux:

4

Các trình ứng dụng

csh (C Shell)

Bash (Bourne Again

Shell)

X-Window (Shell đồ họa)

Hạt nhân

Linux

Có 2 cách để viết chương trình điều khiển shell:

- Nhập từ dòng lệnh

- Gộp các lệnh vào một file, thực thi như 1 file chương trình

1. Điều khiển shell từ dòng lệnh:

Ví dụ: Tìm và hiện thị nội dung của các file chứa chuỗi Hello.

C1: dùng lệnh grep để tìm ra từng file, sau đó dùng lệnh more

C2: ta có thể dùng lệnh điều khiển shell tự động như sau:

$ for file in *

> do

> if grep -l „Hello‟ $file

> then

> more $file

> fi

> done

5

2. Điều khiển shell bằng tập tin kịch bản (script file)

Dùng lệnh cat hay một trình soạn thảo khác để soạn thảo nội dung tệp tin

Cat > vidu1.sh

#! /bin/sh

for file in *

do

if grep -l „Hello‟ $file

then

more $file

fi

done

exit 0

Chú ý:

#: chú thích

#!: yêu cầu shell hiện tại triệu gọi shell (sh) hoặc bất kỳ một chương trình nào mà ta muốn chạy trước khi script tiếp theo được diễn dịch

exit: đảm bảo rằng script sau khi thực thi sẽ trả về mã lỗi thành công

+ Tên file: đuôi .sh hoặc có thể bất kỳ tên mở rộng nào

+ Để nhận biết một file là script hay không ta dùng lệnh: file vidu 6

3. Thực thi script

- Cần chuyển thuộc tính thực thi (x) cho tập tin:

chmod +x <filename>

- Thực thi như sau: ./<filename>

- Lưu ý: chỉ rõ đường dẫn

- Để ngăn script không bị sửa đổi bởi người sử dụng khác, ta có thể sử dụng các lệnh thiết lập quyền:

- Ví dụ:

cp vidu1.sh /usr/local/bin

chown root /usr/local/bin/vidu1.sh

chgrp root /usr/local/bin/vidu1.sh

chmod u=rwx, go=rx /usr/local/bin/vidu1.sh

-Ý nghĩa:

- root được toàn quyền đọc, sửa, thực thi tập tin

- nhóm và người sử dụng được phép đọc và thực thi. - Chú ý: mặc dù tệp tin không được phép ghi (w) nhưng có thể xóa bỏ tập tin này nếu thư mục chứa tập tin có quyền ghi.

7

Đặc điểm biến:

Biến sẽ được tự động tạo ra và khai báo khi lần đầu tiên xuất hiện.

Mặc định, các biến đều được khởi tạo và chứa trị kiểu chuỗi.

Shell và một vài lệnh sẽ thực hiện đổi chuỗi ra số khi có yêu cầu.

Biến có phân biệt chữ hoa chữ thường.

Tên biến: là một chuỗi ký tự bắt đầu bằng chữ cái hoặc dấu “_”.

ví dụ: myvar, _x

8

1. Sử dụng biến do NSD tạo ra

Gán giá trị cho biến: <tên biến>=<giá trị>

Ví dụ:

x=1000

• Sử dụng giá trị của biến: $<tên biến>

• Hiện thị nội dung biến, dùng lệnh echo:

Ví dụ: echo $x

echo -n $x # -n: Không xuống dòng

• Đọc giá trị biến từ bàn phím: read <biến>

Ví dụ: $read name

$echo Hello $name

9

Lệnh echo

Dùng để hiển thị dòng văn bản, giá trị biến …

Cú pháp : echo [options] [chuỗi, biến…]

Các option :

-n : không in ký tự xuống dòng.

-e : cho phép hiểu những ký tự theo sau dấu \ trong chuỗi

\a : alert (tiếng chuông)

\b : backspace

\c : không xuống dòng

\n : xuống dòng

\r : về đầu dòng

\t : tab

\\ : dấu \

ví dụ : echo –e “một hai ba \a\t\t bốn \n” 10

Dấu bọc chuỗi (quote)

† Chuỗi chứa khoảng trắng nên cần bọc bởi dấu nháy đơn ' hay nháy kép "

† Dấu nháy kép: nếu chuỗi có kí hiệu $ thì nó vẫn có hiệu lực

† Dấu nháy đơn: mạnh hơn, vô hiệu hóa kí tự $ trong chuỗi.

† Dùng dấu \ để hiển thị kí tự đặc biệt $

† Ví dụ: vidu2.sh

#! /bin/sh

myvar="Hi there"

echo $myvar -> Hi there

echo "$myvar“ -> Hi there

echo '$myvar„ -> $myvar

echo "\$myvar“ -> $myvar

echo '\$myvar„ -> \$myvar

Dấu `: Nháy ngược, thực thi lệnh

echo “hôm nay là `date`“ 11

2. Biến môi trường (environment variable)

- Được khai báo và gán trị mặc định Shell khởi động.

- Được viết hoa để phân biệt với các biến do người dùng định nghĩa,

có nội dung tùy vào thiết lập của hệ thống và người quản trị.

- Một số biến môi trường:

$HOME: chứa nội dung thư mục chủ.

$PATH: chứa danh sách đường dẫn. Linux thường tìm các lệnh cần

thi hành trong biến $PATH

$PS1: dấu nhắc, thường là $ cho user không phải root

$PS2: dấu nhắc thứ cấp, thông báo người dùng nhập thêm thông tin

trước khi thực hiện lệnh (>)

$IFS: dấu phân cách các trường trong danh sách chuỗi

12

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ý, dùng thêm biến:

$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 của shell script khi thực thi

- Xem danh sách biến môi trường, lệnh: env

- Tạo thêm biến môi trường mới: export <var>=<value>

$1, $2, $3….: vị trí và nội dung của các tham số trên dòng lệnh, từ trái sang

phải

$*: danh sách 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 sách các tham số được chuyển thành chuỗi, không sử dụng dấu

phân cách của biến $IFS

13

Ví dụ:

$IFS=”^”

#tiếp nhận 3 tham số trên dòng lệnh là var1 var2 var3

$set var1 var2 var3

$echo “$@” => var1 var2 var3

$echo “$*” => var1^var2^var3

#đặt IFS về null, biến $* trả về danh sách thuần túy của các tham số

$unset IFS

$echo “$*” => var1 var2 var3

$echo “tham so thu 1 la $1” => var1

$echo “tham so thu 3 la $3” => var3

Biến $# sẽ chứa số tham số của lệnh, ở ví dụ trên ta có:

$echo “$#” => 3

14

4. Điều kiện Để kiểm tra điều kiện boolean: lệnh test hoặc [ ] test <condition> hoặc [ condition ] Ví dụ: kiểm tra xem file mang tên hello.c co tồn tại trong hệ thống không?

if test -f hello.c

then

fi

hoặc: if [ -f hello.c ]

then

….

fi

Lưu ý: đặt khoảng trắng giữa lệnh [] và biểu thức kiểm tra

15

Các kiểu so sánh:

So sánh chuỗi

s1 = s2 -> true nếu 2 chuỗi bằng nhau chính xác từng ký tự một

s1 != s2 -> true nếu 2 chuối không bằng nhau

-n s1 -> true nếu s1 không rỗng

-x s1 -> true nếu s1 rỗng

So sánh toán học

exp1 -eq exp2 -> true nếu hai biểu thức bằng nhau

exp1 -ne exp2 -> true nếu 2 biểu thức không bằng nhau

exp1 -gt exp2 -> true nếu exp1 lớn hơn exp2

exp1 -ge exp2 -> true nếu exp1 lớn hơn hay bằng exp2

exp1 -lt exp2 -> true nếu exp1 nhỏ hơn exp2

exp1 -le exp2 -> true nếu exp1 nhỏ hơn hay bằng exp2

! exp -> true nếu exp là false 16

Kiểm tra điều kiện tập tin

-d file -> true nếu file là thư mục

-e file -> true nếu file tồn tại trong đĩ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. (set-gid cho phép chương trình quyền của nhóm)

-r file -> true nếu file cho phép đọc

-s file -> true nếu kích thước file khác 0

-u file -> true nếu set-user-id được thiết lập trên file. (set-uid cho phép chương trình quyền của chủ sở hữu (owner) thay vì quyền của user thông thường)

-w file -> true nếu file cho phép ghi

-x file -> true nếu file được phép thực thi

Chú ý: khi dùng các điều kiện trên file phải tồn tại (trừ -f)

17

Tính toán trong Shell:

1. Sử dụng $((...))

ví dụ :

x=4

x=$x+5

echo $x

4+5

x=$(($x+5))

y=$(($x*2))

echo $x, $y

-> 9,18

# or: x=$((x+5))

# or: x=$(( x + 5 ))

# or: x=$((x + 5))

18

2. Sử dụng: `expr

ví dụ :

x=”12”

x=`expr $x + 1`

y=`expr $x \* 2`

echo $x, $y

->13, 26

3. Sử dụng: let

Ví dụ:

x=5

let x=$x+2

let y=$x*3

echo $x,$y

-> 7,21

# or: let x=x+2

1. Lệnh if

Cú pháp:

if condition

then

statements

else

statements

fi Ví dụ

2. Lệnh elif trong if Cho phép kiểm tra điều kiện lần thứ 2 bên trong else

if condition1

then

statements

elif condition2

statements

else

statements

fi Ví dụ 19

Vấn đề phát sinh với các biến nhận giá trị chuỗi:

Ví dụ:

if [ $answer = “yes” ].

Nếu ko nhập giá trị cho biến answer thì sẽ nhận thông báo lỗi:

[: =: unary operator expected

Vì: shell diễn dịch là:

if [ = “yes” ]

Để tránh lỗi này, ta nên bọc nội dung biến bằng dấu “ “:

if [ “$answer” = “yes” ].

Lúc đó, shell sẽ diễn dịch:

if [ “ “ = “yes” ]

Nếu là số thì ko cần

Nên bắt lỗi trong các trường hợp này.

20

3. Lệnh for

Sử dụng for để lặp lại một số lần với giá trị xác định

Cú pháp:

for variable in values

do

statements

done Ví dụ

Hoặc có pháp giống C (với Ub /bin/bash)

4. Lệnh while

While cho phép lặp vô hạn khi điều kiện kiểm tra vẫn còn đúng

Cú pháp:

while codition

do

statements

done

Ví dụ

21

5. Lệnh until

Cú pháp:

until codition

do

statements

done

Vòng lặp sẽ dừng lại khi điều kiện kiểm tra là đúng. Ví dụ 6. Lệnh case

Cú pháp:

case mau in

mau1)

cau_lenh;;

mau2)

cau_lenh;;

….

*)

cau_lenh ;;

Esac Ví dụ vd

22

Trong đó, mau được so sánh lần lượt với các mẫu mau1, mau2...

Nếu có một mẫu trùng khớp thì (các) câu lệnh tương ứng sẽ được thực hiện cho đến khi gặp hai dấu chấm phảy (;;).

Nếu không có mẫu nào trùng khớp thì (các) câu lệnh trong khối * được thực hiện.

Chú ý:

- Ký tự đại diện * cho phép so khớp với mọi loại chuỗi, nó 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.

- Muốn sử dụng nhiều mẫu trên một dòng so sánh của một lệnh case thì sử dụng dấu | để phân cách giữa các mẫu, ví dụ:

case “$answer” in

“yes” | “y” | “YES” | “Yes” ) echo “Good morning”;;

“no” | “No” ) echo “Good afternoon”;;

* ) echo “sorry, not found”;;

esac

23

1. Danh sách AND - &&

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 đã được thực thi xong và trả về mã lỗi

thành công.

Cú pháp: statements1 && sratements2 && ….

Kết quả trả về của AND sẽ là true nếu tất cả các lệnh được

thực hiện, ngược lại là false.

Ví dụ: vidu11.sh Ví dụ

Dùng lệnh touch file1 để kiểm tra file1 đã tồn tại hay chưa, nếu

chưa thì tạo mới, tiếp đến lệnh xóa file rm file2. Sau cùng dùng

danh sách AND để kiểm tra xem các file có đồng thời tồn tại

không để đưa thông báo thích hợp.

24

2. Danh sách OR - ||

Tương tự AND, OR cho phép thực thi một chuỗi lệnh kề nhau, nhưng

nếu có một lệnh trả về true thì việc thực thi dừng lại.

Cú pháp: statements1 || statements2 || ….

Kết quả trả về của OR sẽ là true nếu một trong các lệnh là true.

Lệnh && gọi lệnh tiếp theo khi các lệnh trước đó true

Kết hợp cả AND và OR, ta có thể xử lý được hầu hết mọi trường hợp

logic trong lập trình.

Ví dụ:

[ -f file1 ] && command_for_true || command_for_false

Đây là một cách viết ngắn gọn của if else Ví dụ

3. Khối lệnh {}

Trường hợp muốn thực thi một khối lệnh tại nơi chỉ cho phép đặt

một lệnh (như trong AND hay OR), ta sử dụng {} để bọc khối lệnh

vd 25

1. Cú pháp function_name () { statements } Ví dụ 2. Biến cục bộ và biến toàn cục Biến cục bộ: có hiệu lực trong hàm dùng từ khóa: local. Nếu không có từ khóa local thì các biến được xem là biến toàn cục. 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 Nó có thể tồn tại và lưu giữ kết quả sau khi hàm chấm dứt. * Nếu biến cục bộ và toàn cục trùng tên thì biến cục bộ được ưu tiên và có hiệu lực đến khi hàm chấm dứt. Ví dụ

Hàm có thể trả về một giá trị số, dùng lệnh: return try_func() { return <gtri> }

26

Để trả về giá trị chuỗi, dùng lệnh echo và chuyển hướng nội dung

kết xuất của hàm khi gọi, ví dụ:

try_fun() {

echo “Sample text”

}

x=$(try_func)

biến x sẽ nhận trị trả về của hàm là “Sample text”.

$(function_name) là cách lấy về nội dung của một lệnh

Hoặc để lấy trị trả về của hàm, ta sử dụng biến toàn cục (do biến

toàn cục vẫn lưu lại giá trị ngay cả khi hàm chấm dứt).

27

3. Hàm và cách truyền tham số

Shell không có cách khai báo tham số cho hàm.

Ta truyền tham số cho các hàm tương tự như truyền tham số trên dòng lệnh.

Ví dụ, truyền tham số cho hàm funvd(), ta gọi hàm như sau:

funvd para1, para2,…..

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ị sẽ được khôi phục lại.

Ví dụ 15

28

Ex, Viết hàm tìm max 2 số

Dùng hàm để tìm max 4 số

max2so()

{

if [ $1 –gt $2 ]

then

m=$1

else

m=$2

fi

echo $m

return $m

}

#Main

max=$1

for i in $*

do

max=$(max2so $max $i)

done

echo “Max 4 so: $max”

exit 0

29

1. Mảng

a. Khai báo: (không cần phải khai báo)

array[xx]

Có thể khai báo mảng bằng lệnh declare –a array

- Phần tử của mảng mặc định bắt đầu từ chỉ số 0

b. Gán giá trị cho mảng:

array=( zero one two three four )

Hoặc:

array[0]=zero ; array[4]=four

Hoặc:

Array=( [xx]=XXX [yy]=YYY ...)

Hoặc :

array[5]=`expr ${array[11]} + ${array[13]}`

30

c. Lấy giá trị mảng/:

${array[xx]}

Ví dụ: array=( zero one two three four five )

echo ${array[0]} # zero

echo ${array:0} # zero

echo ${array[3]} # three

echo ${array:1} # ero : lấy từ vị trí số 1 của phần tử thứ hai

echo ${array[2]:1:2] # wo: lấy từ vị trí số 1 đi 2 kí tự của phần tử thứ ba

31

c. Lấy giá trị mảng : ${array[xx]}

- Lấy tất cả phần tử mảng:

${array[@]} hoặc ${array[*]}

Vd: array=( one two three four five )

echo ${array[@]} # one two three four five: tất cả

echo ${array[@]:0} # one two three four five: tất cả

- Lấy một số phần tử trong mảng:

echo ${array[@]:1} # two three four five: lấy từ pt thứ 2

echo ${arrayZ[@]:1:2} # two three : lấy từ phần tử thứ 2 đi 2 pt

32

33

d. Chiều dài mảng/1 phần tử mảng:

${#array[@]} hoăc ${#array[*]}

Ví dụ: array=( zero one two three four five )

echo ${#array[0]} # 4 : chiều dài của phần tử thứ nhất

echo ${#array} # 4

echo ${#array[1]} # 3 : chiều dài của phần tử thứ 2

echo ${#array[*]} # 6 : Số phần tử của mảng

echo ${#array[@]} # 6 : Số phần tử của mảng.

e. Xoá mảng : dùng lệnh unset

Ví dụ:

unset array[1] : xóa phần tử thứ 2 của mảng array

unset array : xóa toàn bộ mảng array

f. Khai báo mảng rỗng

array1=( ' ' ) # mảng array1 có một phần tử rỗng.

array2=( ) # mảng array2 rỗng

34

g. Nới rộng mảng: Khai báo thêm phần tử vào mảng

Ví dụ:

array0=( "${array0[@]}" "new1" )

# ${array0[@]} là mảng cũ, new1 là phần tử mới

hoăc

array0[${#array0[*]}]="new2"

# ${array0[@]} là mảng cũ, new2 là phần tử mới

h. Chép mảng

Ví dụ:

array2=( "${array1[@]}" )

# sao chép mảng array 2 giống mảng array1

hoặc: array2="${array1[@]}"

35

echo "nhap so pt mảng"

read n

for (( i=1; i <= $n;

i++ ))

do

echo –n "pt thu $i"

read a[i]

done

echo "mang la: ${a[@]}"

Dc=0

Dl=0

T=0

for (( i=1; i <= $n;

i++ ))

do

if [ `expr ${a[i]} % 2`

-eq 0 ]

then

Dc=`expr $Dc + 1`

else

Dl=`expr $Dl + 1`

fi

T=`expr $T + ${a[i]}`

done

echo "Co $Dc so chan.

Co $Dl so le. Tong la

$T"

exit 0

2. Chuỗi

a. Chiều dài chuỗi :

${#string} hoặc expr

Ví dụ: stringZ=abcABC123ABCabc

echo ${#stringZ} # 15

echo `expr length $stringZ` # 15

echo `expr "$stringZ" : '.*'` # 15

b. Vị trí chuỗi con:

expr index $string $substring

Ví dụ :

stringZ=abcABC123ABCabc

echo `expr index "$stringZ" C12` # 6 : C vị trí C

echo `expr index "$stringZ" c` # 3 : vị trí c

36

c. Lấy chuỗi con : ${string:position}

Lấy chuỗi con của chuỗi String bắt đầu từ vị trí position kể từ đầu chuỗi bên trái

${string:position:length} : Lấy length kí tự của chuỗi string từ vị trí position

Ví dụ: stringZ=abcABC123ABCabc

# 0123456789..... index tính từ 0

echo ${stringZ:0} # abcABC123ABCabc

echo ${stringZ:1} # bcABC123ABCabc

echo ${stringZ:7} # 23ABCabc

echo ${stringZ:7:3} # 23A : lấy 3 kí tự từ vị trí thứ 7

Có thể lấy từ cuối chuỗi (từ bên phải chuỗi).

Ví dụ:

echo ${stringZ:-4} # abcABC123ABCabc :Không hoạt động

echo ${stringZ:(-4)} # Cabc, dùng dấu ngoặc

echo ${stringZ: -4} # Cabc, dùng khoảng trắng sau dấu : 37

Cách khác:

expr substr $string $position $length

Lấy length kí tự của chuỗi string từ vị trí position. Ví dụ:

stringZ=abcABC123ABCabc

# 123456789...... Index tin h tư 1

echo `expr substr $stringZ 1 2` # ab

echo `expr substr $stringZ 3 4` # ABC1

38

d. Xoá chuôi con

Xóa chuỗi substring ngắn nhất tính từ đầu chuỗi khỏi chuỗi string”

${string#substring}

Xóa chuỗi substring dài nhất tính từ đầu chuỗi khỏi chuỗi string

${string##substring}

Ví dụ:

stringZ=abcABC123ABCabc

# |--------|

# |-------------------|

echo ${stringZ#a*C} # 123ABCabc

echo ${stringZ##a*C} # abc

Xóa chuỗi như trên nhưng tính từ cuối chuỗi:

${string%substring} và ${string%%substring}

Ví dụ:

stringZ=abcABC123ABCabc

#|-|

# |----------------|

echo ${stringZ%b*c} # abcABC123ABCa

echo ${stringZ%%b*c} # a 39

1. Nhóm lệnh thực hiện trong chương trình: a. break, b. continue, c. : (rỗng) 2. Nhóm lệnh thực thi chương trình: a. . (Thực thi), b. exec, c. exit, d. export, e. trap 3. Nhóm lệnh về toán học: a. eval, b. expr, c. return, d. printf 4. Nhóm lệnh về biến: a. set, b. shift, c. unset

40

1. Nhóm lệnh thực hiện trong chương trình: a. Break Để thoát khỏi vòng lặp for, while, until bất kể điều kiện của các lệnh này có diễn ra hay không. vd b. Continue Thường được dùng bên trong vòng lặp, Nó yêu cầu vòng lặp 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. vd c. Lệnh : (rỗng) - (null command). Đôi lúc lệnh này được dùng với ý nghĩa logic là true. Khi dùng lệnh : việc thực thi nhanh hơn việc so sánh true. Ví dụ while : sẽ tương đương với while true. vd

41

2. Nhóm lệnh thực thi chương trình:

a. Lệnh . (thực thi)

- Dùng để gọi thực thi một script trong shell hiện hành.

ý nghĩa: là nó thi hành và giữ nguyên những thay đổi về mội trường mà script tác động.

Cú pháp: . ./shell_script

b. exec

- Dùng gọi một lệnh bên ngoài khác. Thường gọi một shell phụ khác

c. exit n

- Lệnh exit sẽ thoát khỏi shell nào đó và trả về mã lỗi n. Trong các script, nó trả về mã lỗi cho biết script được thực thi thành công hay ko.

- Mã lỗi 0 có nghĩa là thành công. Các giá trị khác:

từ 1-125 có ý nghĩa với các mục đích khác nhau

126: file không thể thực thi

127: Lệnh không tìm thấy

>128: nhận được tín hiệu phát sinh.

- Sử dụng exit trên dòng lệnh thì sẽ thoát khỏi shell chính và trở về màn hình login.

42

d. export Lệnh export có tác dụng khai báo biến toàn cục (biến môi trường). Khi bắt đầu thực thi 1 shell, các biến môi trường đều được lưu lại. Biến khai báo trong script: có giá trị đối với shell triệu gọi script đó. Biến khai báo bằng lệnh export : thấy được ở tất cả các script trong các shell khác

#!/bin/sh foo="This is foo" export bar="This is bar” # biến khai báo export echo "Value: $foo" echo "Value: $bar“ Kết quả: Value: This is foo #gtrị biến trong script Value: This isbar # gtri biến khai báo=export

43

e. trap dùng để bẫy một tín hiệu do hệ thống gửi đến shell trong quá trình thực thi script. Tín hiệu thường là 1 thông điệp của hệ thống gửi đến chương trình yêu cầu hay thông báo về công việc nào đó mà hệ thống sẽ t. hiện. Với Script, trap giúp ta đón bắt và xử lý một số tín hiệu rất thường xảy ra Cú pháp: trap command signal Lưu ý: command yêu cầu trap thực hiện được đặt trong dấu „ „ để giải hoặc vô hiệu hóa lệnh trap trước đó, ta thay command bằng dấu – Các tín hiệu: HUP (1) -> Hang-up, nhận được khi người dùng logout INT (2) -> Interrupt, tín hiệu ngắt khi người dùng nhấn ^C QUIT (3) -> Quit, nhận được khi nhấn Ctrl-\ ABRT (6) -> Abort, tín hiệu chấm dứt, nhận khi timeout ALRM (14) -> Alarm, t. báo được dùng xử lý cho tình huống timeout TERM (15) -> terminate, nhận được khi hệ thống y. cầu shutdown

44

3. Nhóm lệnh về toán học: eval, expr, return, printf

a. eval

Lệnh eval cho phép bạn ước lượng một biểu thức chứa biến

vd

b. expr

Lệnh expr ước lệ giá trị đối số truyền cho nó như là một biểu thức. Thường expr được dùng trong việc tính toán các kết quả toán học đổi giá trị từ chuỗi sang số.

Ví dụ:

x=”12”

x=`expr $x + 1` => kết quả là 13

- Chú ý: Cặp dấu ` ` bọc biểu thức expr. Các toán tử và toán hạng phải cách nhau bằng khoảng trắng

- Sau đây là một số biểu thức ước lượng mà expr cho phép:

expr1 | expr2 -> Kết quả là expr1 nếu expr1 khác 0 ngược lại là expr2

expr1 & expr2 -> 0 nếu một trong 2 biểu thức là zero ngược lại kết quả là expr1

45

expr1 = expr2 -> bằng

expr1 > expr2 -> lớn hơn

expr1 >= expr2 -> lớn hơn hoặc bằng

expr1 < expr2 -> nhỏ hơn

expr1 <= expr2 -> nhỏ hơn hoặc bằng

expr1 != expr2 -> không bằng

expr1 + expr2 -> cộng

expr1 - expr2 -> trừ

expr1 * expr2 -> nhân

expr1 / expr2 -> chia

expr1 % expr2 -> chia dư module

Các shell sau này, lệnh expr được thay thế bằng cú pháp $((...))

ví dụ :

z=$((z+3))

z=$(($m*$n))

vi du:

46

c. return

Lệnh return dùng để trả về giá trị của hàm. Lệnh không có tham số sẽ trả về mã lỗi của lệnh vừa thực hiện sau cùng.

d. printf

Cho phép in một chuỗi ra màn hình. Lệnh này không hỗ trợ định dạng số có dấu chấm động (float) bởi các tính toán của shell đều dựa trên số nguyên.

Sau đây là danh sách các ký tự đặc biệt có thể sử dụng với dấu \, chúng được gọi là các chuỗi thoát:

\\ -> cho phép hiện thị ký tự \ trong chuỗi

\a -> phát tiếng chuông bip

\b -> ký tự xóa backspace

\f -> đẩy dòng

\n -> sang dòng mới

\r -> về đầu dòng

\t -> canh tab ngang

\v -> canh tab dọc

47

Định dạng số và chuỗi bằng ký tự %, bao gồm:

d -> số nguyên

c -> ký tự

s -> chuỗi

% -> hiện thị ký hiệu %

Ví dụ:

$printf “Your name %s. It is nice to meet you \n” Van An

Your name Van An. It is nice to meet you

$printf “%s %d \t %s” “Hi there” 10 “people”

Hi there 15 people

Lệnh printf thường được dùng thay thế echo, mục đích để in chuỗi không sang dòng mới (printf chỉ sang dòng mới khi dùng \n).

48

4. Nhóm lệnh về biến: set, shift, unset

a. set

Lệnh set dùng để áp đặt giá trị cho các tham số môi trường như $1, $2, $3… Lệnh set loại bỏ các khoảng trống không cần thiết và đặt nội dung của chuỗi truyền cho nó vào các biến tham số.

Ví dụ:

$set anh binh canh

$echo $1

anh

$echo $3

canh

49

b. shift

Lệnh shift di chuyển nội dung tất cả các tham số môi trường $1, $2, $3… xuống một vị trí. Bởi vì hầu như ta chỉ dùng được tối đa 9 tham số từ $1 đến $9, tham số từ $10 trở lên sẽ được dùng bằng lệnh shift ($10 thường được hiểu là $1 và „0‟).

Ví dụ: try_shift.sh

$! /bin/sh

while [ “$1” !=” “ ]; do

echo “$1”

shift

done

exit 0

Chạy chương trình: ./try_shift.sh xin chao ban 1 2

Kết qủa:

xin

chao

ban

1

2 50

c. unset

Lệnh unset dùng để loại bỏ biến khỏi môi trường shell.

Ví dụ:

#! /bin/sh

bien=”Hello Hello”

echo $bien

unset bien

echo $bien

51

Cú pháp: $(command) hoặc `command

Ví dụ:

echo thu muc hien thoi la $PWD

echo no chua $(ls -a) file

Lệnh $( ) rất mạnh và sử dụng phổ biến trong lập trình shell cho Linux.

Ta có thể lấy kết quả của $( ) làm đối số truyền tiếp cho các lệnh khác.

52

- Tương tự lập trình Shell, ta cũng cũng dùng một trình soạn thảo để soạn thảo chương trình theo ngôn ngữ C. Đặt tên tệp với đuôi *.c.

- Sau đó ta cần biên dịch chương trình *.c này: cc/gcc [-o outputfile] file.c

- Mặc định output file sẽ là một file executable tên là a.out.

- Tạo ra file executable khác, dùng -o file_name

- Chạy chương trình: ./a.out

Ví dụ: hello.c

#include <stdio.h>

main() {

printf("Xin chao C!\n");

}

Biên dịch và chạy chương trình hello.c như sau:

$ cc hello.c

$ ./a.out

hoặc $ cc -o hello hello.c

$ ./hello 53

# if…. Then….fi

#! /bin/sh

echo Are you John?

read answer

if [ $answer = yes ]

then

echo Hello $answer

else

echo Sorry

exit 1

fi

exit 0

54

# Script to test if..elif...else- number a

read var

if [ "$var" -gt 0 ]

then

echo $var is positive

elif [ "$var" -lt 0 ]

then

echo $var is negative

elif [ "$var" -eq 0 ]

then

echo $var is zero

else

echo Opps! $var is not number, give

number

fi

exit 0

55

# For…do…done: sum 1+2+…+n

#! /bin/sh

read n

s=0

for (( i = 1; i <= $n; i++ ))

do

let s=s+i

done

echo “tong la: $s”

exit 0

# print column – row 1-5

#!/bin/bash

for (( i = 1; i <= 5; i++ )) ### Outer FOR

do

for (( j = 1 ; j <= 5; j++ )) ### Inner for

do

echo -n "$i "

done

echo "" #### print the new line ###

done

56

for i in a b c d e f do echo i done don

#While… do… done:view number

#! /bin/sh

t=0

X=1

While (( X <=10 )) # while [ $x –le 10 ]

do

Echo “hello X is : $X“

Let t=t+1

Done

# view files

#! /bin/sh

reply=y

while test "$reply" != "n"

do

echo –n "Enter file name?"

read fname

cat ${fname}

echo –n "wish to see more files :"

read reply

Done

57

#Until…. Do… done

#! /bin/sh

var=10

until [ $var -eq 0 ]

do

echo -n " $var "

var=`expr $var - 1`

echo

Done

58

# view users loging

#! /bin/sh

echo “locate for user “

until who | grep “$1” > /dev/null

do

sleep 60

done

#in ra chuong

echo –e \\a

# Hien thi ten user da login

echo “*********$1 has just logged in***********”

exit 0 Chương trình thực hiện: Lệnh who lọc ra danh sách các user đăng nhập vào hệ thống. Nó chuyển danh sách 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 “tên user”. 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ả về giá trị true, lệnh until kết thúc.

59

# Case .. In .. esac

#! /bin/sh

echo “Is it morning?”

read answer

case “$answer” in

“yes”) echo “Good morning”;;

“no”) echo “Good afternoon”;;

* ) echo “sorry, not found”;;

esac

exit 0

60

#! /bin/sh

while true

do

echo "Enter choice"

echo "(press 'q' to exit)"

echo "1 date 2 who"

echo "3 ls 4 pwd"

read choice

case $choice in

1)date;;

2)who;;

3)ls -la;;

4)pwd;;

q)break;;

*)echo "That was not one of the

choices";;

esac

done

61

#! /bin/sh

touch file1

rm –f file2

if [ -f file1 ] && echo “hello” && [ -f file2 ]

&& echo “there”

then

echo –e “in if”

else

echo –e “in else”

fi

exit 0

62

#! /bin/sh

rm –f file1

if [ -f file1 ] || echo “hello” || echo “there”

then

echo “in if”

else

echo “in else”

fi

exit 0

Khối lệnh:

if [ -f file1 ] && {

ls -l

echo "Khoi lenh"

}

then

echo "Lenh hoan thanh"

fi

63

# function

#! /bin/sh

try_func () {

echo “2. Function is executing”

}

echo “1. Script vidu starting”

try_func

echo “3. Script vidu ended”

exit 0

64

# function_ variable

# /bin/sh

name_var="global variable"

try_func() {

local name_var="local varable"

echo "Function is executing"

echo $name_var

}

echo "Script starting"

echo $name_var

try_func

echo "Script ended"

echo $name_var

exit 0

65

#! /bin/sh

ask() {

echo “ Bien trong ham la $*”

echo “Bien 1 $1 va bien 2 $2”

while true; do

echo -n “Nhap yes or no”

read x

case “$x” in

y | yes) return 0;;

n | no) return 1;;

*) echo “Tra loi yes or no”

esac

done

}

echo “Bien goc la $*”

if ask “Your name” “$1?”

then

echo “Hi $1”

else

echo “Sorry”

fi

exit 0

Thực thi: ./vidu15.sh Anh Ba

66

#!/bin/sh

rm -rf fred*

echo > fred1

echo > fred2

mkdir fred3

echo > fred4

for file in fred*

do

if [ -d "$file" ]; then

echo $file

break

echo “hello”

fi

done

echo "first directory fred was $file"

exit 0

Kq:

fred3

first directory fred was fred3

67

#!/bin/sh

rm -rf fred*

echo > fred1

echo > fred2

mkdir fred3

echo > fred4

for file in fred*

do

if [ -d "$file" ]; then

continue

fi

echo "file is $file"

done

exit 0

68

#!/bin/sh

rm -f fred

if [ -f fred ]

then

:

else

echo "file fred does not exist"

fi

exit 0

69

foo=10

x=foo

y='$'$x

echo $y

######

foo=10

x=foo

eval y='$'$x

echo $y

In ra kết quả là chuỗi $foo

In ra kết quả là 10

70

top related