a. Cú pháp tổng quát của một lệnh
Ta hãy kiểm tra cú pháp của một lệnh theo các quy tắc của Shell.
Một lệnh được viết dưới dạng đơn giản nhất bao gồm một tên lệnh tiếp sau dấu nhắc của Shell. Ví dụ:
% cd
Giữa dấu nhắc và tên lệnh có thể có khoảng trống bởi gõ một hay nhiều phím <SPACE> hoặc <TAB>. Ví dụ:
% pwd
Tiếp theo tên lệnh, ta có thể điền các đối số (argument) như: các tuỳ chọn, tên tệp, chuỗi ký tự v.v. nhưng giữa chúng phải có khoảng trống.
Giữa một dấu chỉnh hướng và một đối số thì không có khoảng trống.
Một lệnh có thể được viết trên nhiều dòng với điều kiện đặt dấu \ trước khi bấm phím xuống dòng <Enter> hoặc <RETURN>. Ví dụ:
% rm tệp1 tệp2 \ tệp3
Thực ra dấu “\” chỉ có nhiệm vụ che ký tự <RETURN> đi sau nó. Chính xác hơn, tổ hợp bao gồm dấu “\” và <RETURN> sẽ được thay thế bằng ký tự <SPACE>. Ví dụ:
% echo phan\ lan<RETURN> phan lan
Một lệnh có thể kết thúc bằng dấu “;” nhưng không bắt buộc. Ví dụ: %mkdir cata4 ;
Một dòng có thể chứa nhiều lệnh được phân cách với nhau bởi dấu “;”. Các lệnh này được sẽ được xử lý tuần tự. Ví dụ:
% cd /usr ; pwd<RETURN> usr
Một lệnh có thể được kết thúc bằng một chú giải, với điều kiện phải đặt dấu # ở trước chú giải. Trong chế độ tương tác, chú giải chỉ được chấp nhận trong Bourne Shell. Ví dụ:
$ cat tệp #lệnh này chỉ là của Bourne Shell Chú ý:
Trong những phiên bản trước đây của UNIX, ký tự # được dùng như ký tự xóa.
Các lệnh có thể được nhóm lại với nhau trong ngoặc đơn ( ) . Điều này được dùng để chỉnh hướng các luồng dữ liệu vào\ra. Như vậy lệnh:
% (cat tệp1; cat tệp2; cat tệp3) > kết quả sẽ tương đương với 3 lệnh sau:
% cat tệp1 > kết quả % cat tệp2 >> kết quả % cat tệp3 >> kết quả
b. Cách Shell diễn dịch một dòng lệnh
Shell diễn dịch theo những quy tắc chính xác và theo một thứ tự xác định sẵn.
1- Đọc m t ộ đầu vào chu nẩ
Shell sẽ đọc đầu vào từ tệp chuẩn stdin (bàn phím) cho đến khi gặp một ký tự kết thúc dòng lệnh, tức là một trong ba ký tự sau:
-một ký tự <new line> (không bị che bởi “\”) -một ký tự “;”
-một ký tự “&”
2- Xem xét vi c ch nh hệ ỉ ướng
Shell sẽ chỉnh hướng (redirection) nếu gặp các dấu “>”, hoặc “<”, tức là sẽ thay thế các tệp đầu vào chuẩn stdin hoặc tệp đầu ra chuẩn stdout bằng các tệp được quy định tuỳ theo những dấu đó.
3- Thay th các bi nế ế
Khi xuất hiện một tên biến sau ký tự $, Shell sẽ thay thế biến đó bằng giá trị của nó. Ví dụ:
Trong Shell C, ta thiết lập (tức định nghĩa) và khởi tạo một biến có tên var bằng lệnh:
% set var = thứ năm
Trong Bourne Shell, ta sẽ có cùng kết quả như trên với lệnh: % var=thứ năm # nhớ viết liền các chữ với dấu "=" Ta có thể sử dụng giá trị này của biến var trong lệnh sau:
% echo $var<RETURN> và nhận được:
Thứ năm
Shell như vậy quả thật đã thay thế biến var bằng giá trị của nó là “thứ năm”.
4- Thay th các l nhế ệ
Mỗi lệnh viết giữa các dấu huyền (back quotes) trên dòng lệnh, sẽ được shell thực hiện ngay và luồng dữ liệu do nó sinh ra sẽ được shell thay vào vị trí của lệnh đó trên cùng dòng lệnh (xem thêm ở sau)
5- Phân bi t các ệ đối s c a l nhố ủ ệ
Shell sẽ phân biệt các đối số bằng các khoảng trống hoặc các ký tự <tab> chen giữa các đối số.
Chỉ riêng trong Bourne Shell, một biến được xác định trước tên là IFS sẽ thể hiện tất cả các dấu phân cách có thể được chấp nhận.
6- Th t x lýứ ự ử
Shell sẽ xử lý trước các ký tự đặc biệt của lệnh, sau đó mới sinh ra các tên tệp.
c. Diễn dịch các ký tự đặc biệt
1- Các bi u th c thông thể ứ ường
Đó là trong trường hợp riêng của các lệnh grep, egrep, sed, các ký tự đặc biệt sẽ trực tiếp liên quan đến chính các lệnh này.
Đối với các lệnh đó, các ký tự đặc biệt của các biểu thức thông thường sẽ được diễn dịch theo những quy tắc đã đưa ra ở mục “Xử lý các tệp”.
2- Các siêu ký tự
Đối với các lệnh nói chung, Shell sẽ phải diễn dịch các siêu ký tự như đã được định nghĩa ở mục “Xử lý các tệp”.
Tuy nhiên vẫn có thể trung hoà hiệu ứng của các siêu ký tự bằng cách lập lại ý nghĩa nguyên thuỷ của các ký tự đặc biệt như sau :
-nếu một chuỗi ký tự đặc biệt được viết giữa các dấu nháy kép (double quotes) trên dòng lệnh, mọi siêu ký tự sẽ được trung hoà ngoại trừ :
$ ký tự tính giá trị của biến ‘ ký tự thay thế lệnh
-nếu một chuỗi ký tự đặc biệt được viết giữa các dấu nháy đơn (simple quotes) trên dòng lệnh, mọi ký tự trong đó đều sẽ không có nghĩa đặc biệt đối với shell
-nếu một ký tự đặc biệt được viết sau dấu “\” chéo ngược (backslash) thì nó sẽ không có nghĩa đặc biệt đối với shell
Ví dụ :
% set var = thứ năm<RETURN> % echo $var<RETURN> thứ năm % echo "$var"<RETURN> thứ năm % echo ’$var’<RETURN> $var % echo \$var<RETURN> $var
% echo hôm nay là "thứ hai"<RETURN> hôm nay là thứ hai
% echo "hôm nay là "thứ hai ""<RETURN> hôm nay là thứ hai
% echo "hôm nay là ’thứ hai’"<RETURN> hôm nay là ’thứ hai’
% echo ’hôm nay là ’thứ hai’’<RETURN> hôm nay là thứ hai
3- Vi c thay th l nhệ ế ệ
Nếu trong một lệnh chính có một lệnh phụ đặt giữa các dấu huyền "`" thì: - lệnh phụ sẽ được thực hiện trước
- luồng dữ liệu sinh ra từ lệnh phụ sẽ được xử lý như sau:
-shell sẽ tách từng từ của luồng dữ liệu ra -mỗi từ đó sẽ làm đối số cho lệnh chính
Ví dụ:
% echo Số tệp trong thư mục hiện hành = `ls -l | wc -l`<RETURN> Số tệp trong thư mục hiện hành = 12
d. Các đường dẫn đến các tệp lệnh
Giá trị định trước của biến đường dẫn (PATH trong Bourne shell và path trong C shell) thuộc mỗi user sẽ giúp user đó gõ tên các lệnh mà không cần gõ đường dẫn đến các tệp lệnh ấy, ví dụ:
$ echo $PATH<RETURN>
.:/home/lan_anh/bin:/bin:/usr/bin:/usr/ucb:/etc:\ /usr/etc
Ta thấy trong ví dụ thứ nhất (Bourne shell) dấu phân cách là ":". % echo $path<RETURN>
. /home/lan_anh/bin /bin /usr/bin /usr/ucb /etc\ /usr/etc
Trong ví dụ thứ hai (C shell) dấu phân cách là <SPACE>.