Shell script trên Linux/Unix

    Khi lập trình trên nền móng HĐH Linux/Unix tất cả chúng ta thường phải sử dụng Shell script rất là nhiều. Nội dung này được viết để giúp các ae mới làm quen với Linux/Unix có thể tiếp cận & hiểu được một số điều căn bản của lập trình Shell script (còn goi là shell scripting).

Shell script là gì ?

Một Shell script là một file có chứa một loạt các lệnh được liệt kê theo thứ tự thực thi. Trong một Shell script thì ngoài các dòng lệnh thường có thêm các dòng chú giải – bình luận, các dòng bình luận khởi đầu bởi dấu #.

Chương trình Shell của HĐH sẽ đọc Shell script & thực thi các lệnh trong đó giống như chúng được nhập trực tiếp trên cửa sổ dòng lệnh (terminal). Đa số những công việc có thể thực hiện được bằng dòng lệnh trên cửa sổ lệnh đều có thể được thực hiện thông qua Shell script, & trái lại đa phần những công việc mà có thể được thực hiện bằng Shell script đều có thể được thực hiện bằng dòng lệnh.

Các bước để viết & chạy Shell script

  1. Sử dụng bất kỳ trình soạn chẳng trách như: vi, vim, nano, gedit… để viết Shell script
  2. Sau thời điểm viết Shell script thì setup quyền thực thi cho nó theo kết cấu lệnh:

chmod permission script-name

Chẳng hạn →

1

2

3

$

chmod

+

Ҳ

sample_script

$

chmod

755

sample_script

  1. Thực thi script bằng 1 trong các kết cấu lệnh sau:

bash script-name

hoặc

sh script-name

hoặc

./script-name

Chẳng hạn →

1

2

3

4

5

$

bash

sample_script

 

$

sh

sample_script

 

$

.

/

sample_script

Mong muốn tạo một Shell script để in “Hello world” lên màn hình ta làm như sau:

1

2

3

4

5

6

7

8

9

10

11

12

13

$

vi

hello_script

.sh

 

#!/bin/sh

 

#

 

# My first shell script

 

#

 

clear

 

echo

“Hello world”

Sau thời điểm lưu file, biến đổi quyền truy cập cho file

1

$

chmod

755

hello_script

.sh

& chạy script này như sau:

1

$

.

/

hello_script

.sh

Cảnh báo: Shell script file nên có đuôi là .sh để dễ phân biệt này là shell script.

Các biến trong Shell script

Trong Linux/Unix Shell, có hai loại biến:

  1. Biến hệ thống – được tạo & duy trì bởi chính HĐH. Loại biến này được khái niệm bằng các ký tự hoa.
  2. Biến do người dùng khái niệm (UDV – User Defined variables) – được tạo & duy trì bởi người dùng. Loại biến này được khái niệm bằng các ký tự thường.

Bạn có thể xem danh mục các biến hệ thống bằng lệnh set hoặc env. Một vài biến hệ thống trọng yếu:

BASH=/bin/bash – tên shell.

BASH_VERSION=1.14.7(1) – phiên bản của shell.

COLUMNS=80 – số cột cho màn hình.

HOME=/home/tuanpm – thư mục home.

LINES=25 – số dòng của màn hình.

LOGNAME=tuanpm – tên đăng nhập của người dùng.

OSTYPE=Linux – Loại HĐH.

PATH=/usr/bin:/sbin:/bin:/usr/sbin – Seting đường dẫn.

PS1=[u@h W]$ – setup prompt.

PWD=/home/tuanpm/working – thư mục hiện hành.

SHELL=/bin/bash – tên shell.

USERNAME=tuanpm – user nào hiện đang đăng nhập vào máy tính.

==> Bạn có thể in ra bất kỳ biến môi trường nào bằng lệnh echo như sau:

Xem Thêm  Cách tạo một trang web chỉ với JavaScript - cách viết mã một trang web bằng javascript

1

2

3

$

echo

$

USERNAME

 

$

echo

$

HOME

Làm cách nào để khái niệm UDV ?

* Sử dụng kết cấu sau:

variable_name=value

Lệnh trên có nghĩa là giá trị value được gán cho biến variable_name. Chẳng hạn →

1

2

3

$

no

=

10

 

$

vech

=

Bus

* Một số phép tắc đặt tên biến & gán giá trị cho biến (vận dụng cho cả UDV & biến hệ thống):

  1. Biến phải khởi đầu bằng ký tự alphanumeric hoặc underscore (_), theo sau bởi một hoặc nhiều ký tự alphanumeric.

Chẳng hạn, các tên biến hợp lệ: HOME, SYSTEM_VERSION, vech, no…

  1. Không có khoảng trắng giữa hai bên dấu bằng khi gán giá trị biến.

Chẳng hạn, các khai báo sau sẽ có lỗi →

1

2

3

4

5

$

no

=

10

 

$

no

=

10

 

$

no

=

10

  1. Phân biệt chữ hoa & thường.

Chẳng hạn, các biến sau là các biến khác nhau →

1

2

3

4

5

6

7

$

no

=

10

 

$

No

=

11

 

$

NO

=

20

 

$

nO

=

2

  1. Bạn có thể khái niệm biến NULL như sau:

1

2

3

$

vech

=

 

$

vech

=

“”

Khi in ra các biến NULL này, thì không có gì trên màn hình bởi vì chúng không có giá trị.

  1. Không sử dụng ?, *…để đặt tên cho biến.

* In & truy cập giá trị của UDV

$variablename

hoặc

echo $variablename

Tính toán trong Shell script

Sử dụng các phép toán số học sau theo kết cấu sau:

expr parameter1 math-operator parameter2

Chẳng hạn →

1

2

3

4

5

6

7

8

9

10

11

$

expr

1

+

3

 

$

expr

2

1

 

$

expr

10

/

2

 

$

expr

20

%

3

 

$

expr

10

*

3

 

$

echo

`

expr

6

+

3

`

Trích dẫn (quote)

Có 3 loại quote trong Shell script:

  • single quote:

1

  

# This is single quote

Single quote được sử dụng để bao xoay quang đoạn text để ngăn không cho Shell biên dịch bất kỳ ký tự đặc biệt nào trong đó. Các dấu $, dấu cách, & , * & các ký tự đặc biệt khác đều được giữ nguyên khi được đóng trong dấu single quote.

  • double quote:

1

  

# This is double quote

Double quote giống như single quote, loại trừ việc double quote vẫn cho phép Shell biên dịch các dấu $, ” & dấu .

  • back quote:

1

`

  

# This is back quote

Back quote hoàn toàn không giống như single quote & double quote. Nó không có công dụng ngăn chặn việc biên dịch các ký tự đặc biệt, thay vào đó back quote sẽ thực thi các lệnh đặt bên trong nó. Sau thời điểm các lệnh đó được thực thi, kết quả của chúng sẽ được thay thế vào chỗ của back quote trong dòng lệnh gốc.

Điều này sẽ cụ thể hơn với một vài chẳng hạn sau →

1

$

echo

‘$PATH’

=> in ra: $PATH

1

$

echo

“$PATH”

=> in ra: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

1

$

echo

“Today is `date`”

=> in ra: Today is Fri Feb 2 16:30:58 CET 2018.

Hiện trạng chấm dứt (exit status)

Mặc định trong Linux nếu lệnh/shell script được thực thi, nó sẽ trả về hai loại giá trị – được sử dụng để xem lệnh/shell script được thực thi thành công hay không.

  1. Trả về giá trị 0: thành công.
  2. Trả về giá trị khác 0: không thành công hoặc có một vài lỗi khi thực thi lệnh/shell script.
Xem Thêm  Ngắt và tiếp tục JavaScript - vòng lặp for bỏ qua đến javascript tiếp theo

=> giá trị này gọi exit status.

Chẳng hạn → Nếu unknow1file không tồn tại trong đĩa cứng thì lệnh “rm unknow1file” sẽ in ra lỗi như sau:

rm: cannot remove `unkowm1file’: No such file or directory.

& sau đó nếu bạn gõ lệnh $ echo $? thì nó sẽ in ra giá trị khác 0 để nêu ra rằng có lỗi.

Đọc dữ liệu từ keyboard

Để nhận dữ liệu từ keyboard & lưu vào biến, ta sử dụng cú pháp sau:

read variable1, variable2, …,variableN

Chẳng hạn, script sau sẽ hỏi tên người dùng & chờ họ nhập vào từ keyboard. Sau thời điểm người dùng nhập tên & nhấn Enter thì tên sẽ được lưu trong biến name →

1

2

3

4

5

6

7

8

9

10

11

$

vi

read_sample

#!/bin/sh

#

#Script to read your name from key-board

#

 

echo

“Your name please:”

 

read

name

 

echo

“Hello $name !”

Chạy script:

1

2

3

4

5

6

7

$

chmod

755

read_sample

 

$

.

/

read_sample

 

Your

name

please

:

tuanpm

 

Hello

tuanpm

!

Wild cards

  1. *: bất kỳ chuỗi hoặc nhóm ký tự nào.

Chẳng hạn →

$ ls * – hiển thị toàn bộ các file.

$ ls α* – hiển thị toàn bộ các file mà tên của nó khởi đầu bằng ký tự ‘a’.

$ ls *.ͼ – hiển thị toàn bộ các file có bằng mở rộng là .ͼ

  1. ?: bất kỳ 1 ký tự nào.

Chẳng hạn →

$ ls ? – hiển thị toàn bộ các file mà tên của nó có bề dài 1 ký tự.

$ ls fo? – hiển thị toàn bộ các file mà tên của nó có 3 ký tự & tên file khởi đầu bằng fo.

  1. […]: bất kỳ 1 trong các ký tự trong dấu ngoặc.

Chẳng hạn →

$ ls [abc]* – trổ tài toàn bộ các file khởi đầu với mẫu tự α, ɓ, ͼ.

  1. […-…]: Một cặp các ký tự được phân tách bởi dấu trừ để ghi nhận một dãy.

Chẳng hạn →

$ ls /bin/[a-c]* – hiển thị toàn bộ các file khởi đầu với mẫu tự α, ɓ, ͼ.

Cảnh báo: Nếu ký tự trước tiên theo sau [ là ! hoặc ^, thì bất kỳ ký tự nào không phù hợp sẽ được hiển thị.

$ ls /bin/[!a-o]

$ ls /bin/[^a-o]

=> sẽ hiển thị toàn bộ các file trong thư mục bin mà ký tự trước tiên không phải là α, ɓ, ͼ…σ.

Nhiều lệnh trên một dòng lệnh

command1;command2

Chẳng hạn →

1

$

date

;

who

sẽ in ra ngày hiện thời theo sau là tên người dùng đăng nhập hiện thời.

Nhập xuất dữ liệu sử dụng file

Đa số các lệnh đều kết xuất ra màn hình hoặc nhận tham số từ keyboard nhưng tất cả chúng ta cũng có thể xuất dữ liệu ra file hoặc đọc dữ liệu từ file.

1) Xuất dữ liệu ra file sử dụng ‘>’

command > filename

xuất kết quả của lệnh ra file có tên là filename. Nếu như filename tồn tại, nó sẽ ghi đè lên, trái lại file mới sẽ được tạo.

Chẳng hạn →

1

$

ls

>

filename

2) Xuất dữ liệu ra file sử dụng ‘>>’

Xem Thêm  Dự án học máy đầu tiên của bạn bằng Python từng bước - mã máy học python

command >> filename

xuất kết quả vào phần cuối của file có tên là filename. Nếu như filename tồn tại, nó sẽ được mở & kết quả của command sẽ được ghi vào cuối file, không sợ mất dữ liệu/thông tin trước. & nếu filename không tồn tại, thì file mới được tạo.

Chẳng hạn →

1

$

date

>

>

myfiles

3) Import dữ liệu từ file sử dụng ‘<‘

command < filename

đọc dữ liệu từ file thay vì keyboard.

Chẳng hạn →

1

$

cat

<

myfiles

Filter & Pipe

Bạn có thể nối hai lệnh với nhau để đầu ra của lệnh đó là đầu vào của lệnh kế tiếp. Hai hoặc nhiều lệnh được connect trong phương pháp này tạo nên một Pipe. Để tạo một pipe, đặt ký hiệu | giữa hai lệnh trên dòng lệnh. Khi một lệnh nhận đầu vào từ một lệnh khác, thực hiện một vài giải quyết trên đầu vào đó, & ghi kết quả ra thì nó được gọi là một Filter.

Một số filter thông dụng:

Filter
Tính năng

head
In ra ɳ dòng dữ liệu trước tiên.

tail
In ra ɳ dòng dữ liệu từ dưới lên.

sort
Xếp đặt dữ liệu.

nl
Hiện thị dòng dữ liệu kèm số thứ tự dòng.

wc
Đếm ký tự, từ, dòng, byte.

cut
Cắt dữ liệu.

sed
Tìm kiếm & thay thế dữ liệu.

uniq
Bỏ dòng trùng lặp.

tac
Hiển thị dữ liệu từ dưới lên. Trái lại đối với cat.

Một số filter thông dụng:

Chẳng hạn →

1

$

ls

~

|

grep

php

=> Ở giai đoạn này lệnh grep là một filter nhận input từ lệnh ls. Kết quả là dòng lệnh trên sẽ liệt kê các tên file & thư mục có chứa từ “php”

Process

Công cuộc là một chương trình (lệnh) để thực thi một công việc xác nhận. Trong Linux khi bạn khởi tạo một quá trình, nó sẽ cho quá trình đó một con số gọi là process-id (PID) , PID bắt nguồn từ 0 đến 65535.

Chẳng hạn →

1

$

ls

lR

lệnh ls là một quá trình, nó sẽ liệt kê các file trong thư mục hoặc toàn bộ thư mục con trong thư mục hiện hành.

Một số lênh khác liên quan đến process:

  • ps – xem quá trình đang chạy.
  • kill – dừng bất kỳ quá trình nào thông qua PID của nó.
  • killall – dừng quá trình thông qua tên của nó.
  • ps -ag – lấy thông tin về toàn bộ các quá trình đang chạy.
  • kill 0 – dừng toàn bộ các quá trình trừ shell của các bạn.
  • command & – chạy lệnh ở background.
  • ps aux – hiển thị chủ sở hữu của các quá trình cùng với các quá trình đó.
  • ps ax | grep process_id – xem từng quá trình có id là  process_id đang chạy hay không chạy.
  • top – xem quá trình đang chạy & các thông tin khác như bộ nhớ lưu trữ, bộ xử lý usage cùng với thời gian thực.
  • pstree – hiển thị cây các quá trình.

— Sưu tầm —

Viết một bình luận