Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO

Bài này mình sẽ nói tới một trong những trường hợp rất hay gặp nhưng không phải ai cũng để ý tới trong lập trình C và C++.

Các trường hợp được nêu dưới đây gọi là  undefined behavior – một khái niệm khá quen thuộc, nôm na có nghĩa là hành vi không xác định được..

Bắt đầu với trường hợp đầu tiên, các bạn nghĩ kết quả in ra của các đoạn code sau là gì?

int a=1;

printf(“%d%d%d”,++a,a,a++);

hay:

int a=1;

std::cout<<++a<

hoặc:

int a=1,b;

b=++a+a+a–+–a+a++;

std::cout<

Như tiêu đề đã nói ở trên, kết quả là undefined behavior, vì sao? Vì các ví dụ trên một biến bị thay đổi giá trị quá nhiều lần trong một biểu thức mà không xác định được thứ tự trước sau, ví dụ trong biểu thức b=++a+a+a–+–a+a++; thì toán tử ++ được ưu tiên cao nhất, sau đó là –, rồi +, cuối cùng là =. Nhưng compiler sẽ không biết a++ ưu tiên thực hiện trước hay ++a thực hiện trước, tương tự, –a trước hay a– trước. Dẫn tới kết quả của biểu thức là không xác định và hoàn toàn phụ thuộc vào compiler, GNU GCC cho ra kết quả khác, MSVC++ sẽ cho kết quả khác,…

Linux là một hệ điều hành đa người dùng và đa nhiệm (thực hiện nhiều tác vụ cùng lúc). Bài này chúng ta sẽ tìm hiểu tính chất đa nhiệm của Linux và cách nó vận hành với giao diện dòng lệnh.

Giống các hệ điều hành đa nhiệm khác, Linux thực hiện nhiều công việc cùng lúc. Thực tế một vi xử lý đơn của máy tính chỉ xử lý được một việc tại một thời điểm, nhưng nhân Linux đã quản lý phân chia các tiến trình luân phiên nhau tại mỗi lần chúng chạy tại những thời điểm giống nhau. Các lệnh thao tác với các tiến trình trên Linux:

  • ps: Liệt kê danh sách các tiến trình đang chạy trên hệ thống.
  • kill: Gửi một tín hiệu tới một hay nhiều tiến trình (thường dùng để đóng tiến trình).
  • jobs: Một cách thay thế việc liệt kê danh sách các tiến trình mà bạn đang sở hữu.
  • bg: Đẩy một tiến trình vào trong background.
  • fg: Đẩy một tiến trình vào trong forground.

Một số ví dụ thực tế:

Linux cung cấp lệnh xload đối với các hệ thống hỗ trợ giao diện X Windows  dùng hiển thị một đồ thị biểu diễn qúa trình hệ thống chạy. Ví dụ:

leaf@leaf-X455LA:~$ xload

Lưu ý: Nếu bạn đóng cửa sổ xload thì chương trình xload kết thúc.

Đặt một chương trình vào background

Giờ ta sẽ khởi động lại xload lần nữa, nhưng để nó trong chế độ nền (background) và cửa sổ nhắc nhở sẽ xuất hiện lại bằng cách dùng thêm ký tự “&” sau xload:

leaf@leaf-X455LA:~$ xload &
[1] 9538

nhắc nhở (prompt) trở lại bởi vì tiến trình được đặt vào background.

Gỉa sử quên đi ký tự “&” sau xload, để đưa chương trình vào background, bạn có thể gõ Ctrl-Z để tiến trình bị đình chỉ. Nó vẫn tồn tại, nhưng không hoạt động, ví dụ:

leaf@leaf-X455LA:~$ xload
^Z
[1]+  Stopped                 xload
leaf@leaf-X455LA:~$

Để khôi phục tiến trình trong background, bạn dùng lệnh bg, ví dụ:

leaf@leaf-X455LA:~$ bg
[1]+ xload &
leaf@leaf-X455LA:~$

Liệt kê danh sách các tiến trình của bạn

Để liệt kê các tiến trình đang chạy trên hệ thống, bạn dùng jobs hoặc hơn nữa là ps:

leaf@leaf-X455LA:~$ jobs
[1]+  Running                 xload &
leaf@leaf-X455LA:~$ ps
  PID TTY          TIME CMD
 2424 pts/12   00:00:00 bash
 2567 pts/12   00:00:00 xload
 2574 pts/12   00:00:00 ps
leaf@leaf-X455LA:~$

Kill một tiến trình

Gỉa sử chương trình bị not responding, làm cách nào để kết thúc nó? Lúc này có thể dùng lệnh kill, để dùng kill bạn cần PID của tiến trình, PID là process identity nôm na là mã định danh của tiến trình mà nhân cấp cho chương trình khi nó chạy trên hệ thống.  Để lấy PID bạn dùng lệnh jobs hoặc ps, ví dụ để kill tiến trình xload ở trên:

leaf@leaf-X455LA:~$ xload &
[1] 2603
leaf@leaf-X455LA:~$ jobs
[1]+  Running                 xload &
leaf@leaf-X455LA:~$ kill %1
leaf@leaf-X455LA:~$ xload &
[2] 2605
[1]   Terminated              xload
leaf@leaf-X455LA:~$ ps
  PID TTY          TIME CMD
 2424 pts/12   00:00:00 bash
 2605 pts/12   00:00:00 xload
 2606 pts/12   00:00:00 ps
leaf@leaf-X455LA:~$ kill 2605
leaf@leaf-X455LA:~$

Nâng cao về kill

Khi lệnh kill thực hiện, thực chất nó gửi một tín hiệu từ nhân tới tiến trình đó. Chương trình lắng nghe tín hiệu từ hệ thống sau đó đáp ứng lại. Ví dụ, bạn đang mở trình duyệt web mà  thực hiện shutdown máy thì nhân sẽ gửi tín hiệu tới trình duyệt yêu cầu nó tắt, lúc này tất cả những gì đang hoạt động sẽ được lưu lại, sau khi trình duyệt tắt thì hệ thống cũng sẽ shutdown. Lệnh kill có thể gửi những tín hiệu khác nhau, để biết các tín hiệu này, bạn dùng:

kill -l

Đây là bảng một số tín hiệu hay dùng:

Tín hiệu

Tên

Mô tả

1 SIGHUP Tín hiệu cúp. Tín hiệu này được gửi tới các tiến trình trên Terminal khi bạn đóng Terminal
2 SIGINT Tín hiệu ngắt. Dùng để tạm ngắt chương trình, trên terminal có thể ngắt thủ công bằng cách dùng Ctrl-C
15 SIGTERM Tín hiệu kết thúc. Tín hiệu được tiến trình nhận để kết thúc. Đây là tín hiệu mặc định khi thực hiện lệnh kill
9 SIGKILL Tín hiệu kill. Đây là tín hiệu yêu cầu kết thúc ngay lập tức tiến trình của nhân Linux. Chương trình không thể lắng nghe tín hiệu này

Ví dụ, gỉa sử trên hệ thống có một chương trình không hồi đáp.

leaf@leaf-X455LA:~$ ps x | grep bad_program
 2681 pts/12   S+     0:00 grep –color=auto bad_program
[2]+  Terminated              xload
leaf@leaf-X455LA:~$

dùng ps để lấy PID của bad_program, sau đó kill nó bằng lệnh kill:

leaf@leaf-X455LA:~$ kill -SIGTERM 2681

leaf@leaf-X455LA:~$ kill -SIGKILL 2681

cũng có thể kill tiến trình dựa trên PID:

leaf@leaf-X455LA:~$ kill 2681

hoặc dùng tham số là các gía trị của tín hiệu:

leaf@leaf-X455LA:~$ kill -9 2681

Phần các lệnh trên Shell mình kết thúc ở đây, các bài sau mình sẽ hướng dẫn các bạn về Shell script.

Mỗi file/folder trên Linux đều được gán các quyền truy cập khác nhau cho chủ sở hữu của chúng, cho các nhóm quan hệ với chủ sở hữu,…. Bài viết này mình sẽ phân tích kỹ Permission cho từng owner hay group owner trên Linux.

Trước hết hãy đến với  ví du dùng lệnh ls như sau:

leaf@leaf-X455LA:~$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1021112 Th10  8  2014 /bin/bash
leaf@leaf-X455LA:~$

Chúng ta có thể thấy trong kết qủa mà ls trả về:

  • File /bin/bash thuộc sở hữu của user “root” (owner)
  • Superuser (owner) có quyền đọc (r), viết
    Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO
    và thực thi (x) đối với file
  • File này cũng thuộc sở hữu của nhóm “root” (group owner)
  • Thành viên của nhóm “root” (group owner) chỉ có thực thi (x) và đọc (r) file này
  • Những người dùng khác có thể đọc (r) và thực thi (x) file này

Bạn để ý dấu “-“ ở đầu kết qủa trả về của lệnh ls, dấu “-“ có nghĩa là một file, còn nếu ở vị trí này là ký tự “d” thì kết qủa là một thư mục. Các dấu “-“ sau là ký hiệu tượng trưng cho việc không được phép truy cập file/folder đó.

Một ví dụ khác, gỉa sử bạn có một perrmission  drwxr-xr-x :

Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO

Trở lại vấn đề, các quyền “r” (read), “w” (write), “x” (execute) hoặc “-” (access denied) trong 3 nhóm user, group và others cũng có thể được biểu diễn bằng các số octal, khi Shell thực thi chúng trên nhân chúng được dịch ra thành mã nhị phân để thực thi. Đây là cách mà nhân hiểu các permissions:

rwx  rwx  rwx = 111  111  111

rw-  rw-  rw- = 110  110 110

rwx  —  — = 111  000  000

etc,..

và:

notation    binary     octal

rwx             = 111        = 7

rw-             = 110        = 6

—             = 000       = 0

r-x              = 101         = 5

-wx             = 011         = 3

etc,…

Lưu ý, “r”,”w”,”x” được tượng trưng là 1, còn “-“ tượng trưng là 0. Và các permission là một nhóm số có thứ tự, lần lượt là “r”, “w”, và “x” chứ không lộn xộn.

Đây là bảng một số permission hay sử dụng cho file và folder trên Linux:

File permissions: Các số này dùng trong các cài đặt thông thường. Một số bắt đầu với 7 thường dùng với các chương trình, một số khác thì hay gặp ở các file khác.

Giá trị

Ý nghĩa

777 (rwxrwxrwx) Không hạn chế các quyền truy cập. Bất cứ ai có thể thao tác bất cứ gì trên chúng. Tuy nhiên đây không phải là thiết lập tốt vì nó không bảo mật tốt.
755 (rwxr-xr-x) Chủ sở hữu file có thể đọc, ghi, thực thi file. Nhưng người dùng khác chỉ có thể đọc và thực thi file
700 (rwx——) Chủ sở hữu file có thể đọc, ghi, thực thi file. Nhưng người dùng khác thì không được phép truy cập file này.
666 (rw-rw-rw-) Tất cả người dùng chỉ có thể đọc và ghi file.
644 (rw-r–r– ) Chủ sở hữu file có thể đọc và ghi file, nhưng người dùng khác chỉ có thể đọc file.
600 (rw——-) Chỉ chủ sở hữu file mới có thể đọc và ghi file, những người dùng khác không có quyền truy cập file này. Thường dùng khi nào chủ sở hữu file muốn nó là private.

Directory permission:

Ở directory permission các đặc tính “r”,”w”“x” có khác một chút với file permission, cụ thể:

  • r: Cho phép các nội dung của thư mục được liệt kê ra nếu đặc tính “x” cũng được thiết lập.
  • w: Cho phép các file nằm trong thư mục được tạo mới, xóa, đổi tên nếu đặc tính “x” cũng được thiết lập.
  • x: Cho phép một thư mục có thể vào được (ví dụ: khi thực hiện cd dir thì chúng ta sẽ vào trong dir để thực hiện các thao tác).

Giá trị

Ý nghĩa

777 (rwxrwxrwx) Không hạn chế quyền truy cập, bất cứ ai cũng có thể liệt kê các file, tạo mới và xóa các file trong thư mục. Đây không phải là một cài đặt tốt.
755 (rwxr-xr-x) Chủ sở hữu của thư mục có toàn quyền truy cập. Những người dùng khác có thể liệt kê thư mục, nhưng không có quyền tạo mới và xóa file trong chúng. Cài đặt này thường dùng với trường hợp bạn muốn chia sẻ nó với người dùng khác.
700 (rwx——) Chủ sở hữu có toàn quyền truy cập, nhưng người dùng khác thì không được phép truy cập. Cài đặt này thường dùng cho trường hợp chủ sở hữu muốn nó là private.

Giờ chúng ta sẽ tìm hiểu về các lệnh cho phép thay đổi permission của file/folder.

chmod

Lệnh chmod được sử dụng để thay đổi quyền truy cập của file/folder. Cú pháp là:

chmod mod file/folder

trong đó, mod là các số thuộc hai bảng trên.

Ví du:

leaf@leaf-X455LA:~$ chmod 600 example_file.txt
leaf@leaf-X455LA:~$

hoặc:

leaf@leaf-X455LA:~$ chmod 755 example_file.txt
leaf@leaf-X455LA:~$

su và sudo

Trước hết, hệ thống Linux và Unix có một siêu người dùng gọi là root hay super user, nó cũng tương tự như Administrator trên Windows. Người dùng root có thể thực hiện bất cứ thao tác gì trên hệ thống mà không bị hạn chế. Để chuyển sang người dùng super user từ user bình thường, ta dùng lệnh su, sau đó nhập root password:

leaf@leaf-X455LA:~$ su
Password:
su: Authentication failure

Trường hợp bị sai root password như trên, bạn có thể tạo root password mới bằng lệnh:

leaf@leaf-X455LA:~$ sudo passwd
[sudo] password for leaf:
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

sau đó nhập lại lệnh su:

leaf@leaf-X455LA:~$ su
Password:
root@leaf-X455LA:/home/leaf#

Đôi khi một số tác vụ đòi hỏi phải chuyển sang quyền root để thực thi, nhưng mình khuyến cáo nên cẩn thận khi thực hiện điều này, bởi vì nếu sơ ý xóa 1 file nào đó trên hệ thống, hoặc cài phần mềm nào đó chứa mã độc,.. thì sẽ rất nguy hiểm. Để thoát khỏi quyền root, các bạn chỉ cần thực hiện lệnh exit.

Một số Linux distribution như Ubuntu để đảm baỏ an toàn, chúng cho phép bạn thực hiện các thao tác nào đó trên hệ thống với quyền super user nhưng không login vào root user với lệnh sudo. sudo là viết tắt của Superuser Do. Cú pháp: sudo some_command. Nó yêu cầu nhập user password trước khi thực hiện, ví dụ:

leaf@leaf-X455LA:~$ sudo command
[sudo] password for leaf:
sudo: command: command not found
leaf@leaf-X455LA:~$

Thay đổi File Ownership

Bạn có thể thay đổi quyền sở hữu file bằng lệnh chown, ví dụ mình muốn chuyển quyền sở hữu example_file.txt từ user leaf sang tree (gỉa sử trên hệ thống của mình có user tree rồi)

root@leaf-X455LA:/home/leaf# chown tree example_file.txt

hoặc:

leaf@leaf-X455LA:~$ sudo chown tree example_file.txt

Lưu ý là thực hiện lệnh chown phải ở quyền root. Nếu đang ở root user thì sau khi thực hiện chown phải exit, còn nếu dùng sudo thì không cần.

Thay đổi Group Ownership

Có thể thay đổi quyền sở hữu nhóm bằng cách dùng lệnh chgrp. Ví dụ:

leaf@leaf-X455LA:~$ chgrp new_group example_file.txt

Lưu ý: Ở ví dụ trên mình thay đổi quyền sở hữu của file example_file.txt từ nhóm trước cho nhóm new_group và phải là chủ sở hữu của file example_file.txt mới thực hiện được lệnh chgrp.

Bài viết này mình giới thiệu về Expansion.

Mỗi thời điểm bạn gõ một lệnh và nhấn Enter, bash biểu diễn vài xử lý trên các ký tự của bạn trước khi trả về kết qủa. Tiến trình tạo điều này xảy ra gọi là expansion. Với expansion, bạn gõ một cái gì đó rồi được mở rộng thành một cái gì đó khác trước khi Shell xử lý.

Để minh họa, mình nói sơ qua về lệnh echo. echo là một lệnh dạng built-in trên Shell, biểu diễn một tác vụ đơn giản như in ra một đoạn text trên Terminal:

leaf@leaf-X455LA:~$ echo hello
hello
leaf@leaf-X455LA:~$

echo cũng có thể kết hợp với các wildcards để hiệu qủa hơn, ví dụ:

leaf@leaf-X455LA:~$ echo ~/MyData/*
/home/leaf/MyData/AllCode /home/leaf/MyData/Data /home/leaf/MyData/vidu_shell
leaf@leaf-X455LA:~$

Pathname Expansion

Như ví dụ ở trên, việc dùng các wildcards được gọi là expansion tên đường dẫn hay expansion pathname. Ví dụ, liệt kê danh sách tên các thư mục trong thư mục hiện hành bằng ls:

leaf@leaf-X455LA:~$ ls
Desktop    Downloads  examples.desktop  Music   opencv    Public  Templates
Documents  Dropbox    Matlab            MyData  Pictures  Qt      Videos
leaf@leaf-X455LA:~$

Hay in ra các thứ (file/folder) bắt đầu bằng “M” có trong thư mục hiện hành (Chú ý là chỉ trong thư mục hiện hành, nếu muốn in ra trong thư mục con của nó, bạn dùng lệnh cd tới thư mục con của nó):

leaf@leaf-X455LA:~$ echo M*
Matlab Music MyData
leaf@leaf-X455LA:~$

Hoặc in ra các thứ (file/folder) bắt đầu bằng các ký tự in hoa:

leaf@leaf-X455LA:~$ echo [[:upper:]]*
Desktop Documents Downloads Dropbox Matlab Music MyData Pictures Public Qt Templates Videos
leaf@leaf-X455LA:~$

Bạn có thể thử thêm với một số wildcards khác!

Tidle expansion (dấu “~”)

Bài viết về các lệnh điều hướng trên Shell, các bạn có thấy qua  các ví dụ của mình có dùng cd ~/Downloads hoặc cd ~/MyData,… thì giờ bạn sẽ hiểu rõ “~” là phím tắt của cái gì:

leaf@leaf-X455LA:~$ echo ~
/home/leaf

Như trên ví dụ, “~” tượng trưng cho thư mục /home/user trên Linux, trường hợp của mình là /home/leaf.

Arithmetic expansion (số học)

Bạn có thể in ra kết quả của một biểu thức số học bằng cách sử dụng echo kèm theo cú pháp: $((expression)), ví dụ:

leaf@leaf-X455LA:~$ echo $((2 + 2))
4

Một số ví dụ khác:

leaf@leaf-X455LA:~$ echo $((5**2))
25

Toán tử “**” trên Shell là phép lũy thừa, các bạn lưu ý.

leaf@leaf-X455LA:~$ echo $(($((3**2))*2))
18

leaf@leaf-X455LA:~$ echo $((6/2))
3

Bạn cũng có thể in ra kết qủa biểu thức kèm với đoạn text, ví dụ:

leaf@leaf-X455LA:~$ echo five plus three equal $((5+3))
five plus three equal 8
leaf@leaf-X455LA:~$

Brace Expansion (Dấu ngoặc nhọn)

Dấu ngoặc nhọn {…} trên Shell có nhiều công dụng trên Shell, ví dụ, bạn có thể in ra nhiều đoạn text với các thành phần chứa trong dấu ngoặc nhọn:

leaf@leaf-X455LA:~$ echo Get-{1,2,3}-out
Get-1-out Get-2-out Get-3-out
leaf@leaf-X455LA:~$

Hoặc bạn có thể dùng nó như một mảng, chứa các thành phần nào đó, ví dụ:

leaf@leaf-X455LA:~$ echo {1..9}
1 2 3 4 5 6 7 8 9
leaf@leaf-X455LA:~$ echo {A..Z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
leaf@leaf-X455LA:~$

Hoặc:

leaf@leaf-X455LA:~$ echo a{A{1,2},B{1,2}}b
aA1b aA2b aB1b aB2b
leaf@leaf-X455LA:~$

Parameter Expansion (Biến)

Trên Linux Shell có hai loại biến, đó là biến hệ thống và biến người dùng tự định nghĩa. Biến hệ thống do Linux tạo ra, được viết hoa ví dụ: USER, HOME,… còn biến tự định nghĩa do người dùng đặt ra, viết thường ví dụ name, age,…. Các bạn ghi nhớ chỗ này, sau này phần viết script chúng ta sẽ sử dụng biến khá nhiều.

Ví dụ, chúng ta in ra gía trị của biến với echo $ten_bien:

leaf@leaf-X455LA:~$ echo $USER
leaf
leaf@leaf-X455LA:~$ echo $HOME
/home/leaf
leaf@leaf-X455LA:~$

hoặc:

leaf@leaf-X455LA:~$ echo $((age = 22))
22

Lưu ý ở đây age là tên biến do mình đặt tên, USER, HOME là các biến hệ thống của Linux, để xem tên biến hệ thống của Linux, chúng ta dùng lệnh sau:

leaf@leaf-X455LA:~$ printenv | less

Nếu các bạn chưa hiểu ý nghĩa lệnh trên thì có thể xem lại pipelines trong phần chuyển hướng I/O của mình ở bài viết trước.

Command Subsitution (Lệnh thay thế)

Command substitution cho phép chúng ta xuất một lệnh như là một biểu thức, ví dụ:

leaf@leaf-X455LA:~$ echo $(ls)
Desktop Documents Downloads Dropbox examples.desktop Matlab Music MyData opencv Pictures Public Qt Templates Videos
leaf@leaf-X455LA:~$

hay như lệnh sau, nó nhận kết qủa của lệnh which cp như là tham số của ls rồi thực hiện:

leaf@leaf-X455LA:~$ ls -l $(which cp)
-rwxr-xr-x 1 root root 130304 Th03 11 02:10 /bin/cp
leaf@leaf-X455LA:~$

Có một cú pháp thay thế cho command substitution có trên các chương trình Shell và dĩ nhiên nó được hỗ trợ trên bash. Nó sử dụng dấu back-quotes (là dấu này ` `) để thay thế cho ký hiệu lấy gía trị (là cái này $(…)), ví dụ:

leaf@leaf-X455LA:~$ ls -l `which cp`
-rwxr-xr-x 1 root root 130304 Th03 11 02:10 /bin/cp

Quoting

Để tìm hiểu quoting là gì, bạn hãy lướt qua hai ví dụ sau:

leaf@leaf-X455LA:~$ echo Day la    vi du 1
Day la vi du 1

và:

leaf@leaf-X455LA:~$ $() echo Tong diem la $10.00
Tong diem la 0.00
leaf@leaf-X455LA:~$

Ở ví dụ thứ nhất, bạn muốn in ra đoạn chữ “Day la     vi du 1”, nhưng Shell chỉ in ra “Day la vi du 1”, bởi vì Shell đã tự bỏ qua nhiều ký tự khoảng trắng liên tiếp. Còn ở ví dụ thứ hai, Shell sẽ thay thế gía trị rỗng của biểu thức trước lệnh echo vào ký vị trí ký tự $ đằng sau.

Để khắc phục điều này, Shell cung cấp một kỹ thuật gọi là quoting, nếu bạn muốn khắc phục ví dụ thứ nhất, ta có thể làm như sau:

leaf@leaf-X455LA:~$ echo “Day la    vi du 1”
Day la    vi du 1
leaf@leaf-X455LA:~$

Double quotes (dấu nháy kép)

Nếu đặt một đoạn text vào trong dấu nháy kép, tất cả các ký tự đặc biệt được sử dụng bởi Shell mất hết tác dụng của nó và được sử dụng như các ký tự thông thường trong bảng chữ cái. Nhưng có ba trường hợp ngoại lệ là ký tự “$”, “\” (backslash) và “` `” (back-quotes), nghĩa là khi sử dụng chúng trong double quotes đoạn text sẽ bị phân chia ra, các tidle, brace, pathname expansion sẽ bị dồn nén, nhưng các arithmetic, parameter expansion vẫn được thực hiện. Dùng double quotes chúng ta sẽ xử lý được trường hợp tên file hoặc folder có chứa khoảng trắng. Nếu trong các file của bạn có file nào có tên chứa khoảng trắng trong đó, khi sử dụng nó như một tham số của lệnh, Shell sẽ cố nhận lệnh đó với hai tham số, sẽ gây ra lỗi. Các bạn xem ví dụ sau:

leaf@leaf-X455LA:~$ ls -l van ban.txt
ls: cannot access van: No such file or directory
ls: cannot access ban.txt: No such file or directory
leaf@leaf-X455LA:~$

khi sử dụng double quotes:

leaf@leaf-X455LA:~$ ls -l “van ban.txt”
-rw-rw-r– 1 leaf leaf 10 Th04  5 14:45 van ban.txt
leaf@leaf-X455LA:~$

Ghi chú là các thao tác với parameter expansion, arithmetic expansion và command substitution vẫn thực hiện được trong double quotes, ví dụ:

leaf@leaf-X455LA:~$ echo “$USER $((2*3)) $(cal)”
leaf 6    Tháng tư 2016
CN T2 T3 T4 T5 T6 T7
1  2
3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

leaf@leaf-X455LA:~$

Single quotes (dấu nháy đơn)

Nếu bạn muốn chặn tất cả các expansion, bạn sử dụng dấu nháy đơn, các bạn theo dõi ví dụ sau:

leaf@leaf-X455LA:~$ echo text ~/*.txt {a,b} $(echo leaf) $((2+3)) $USER
text /home/leaf/van ban.txt a b leaf 5 leaf
leaf@leaf-X455LA:~$ echo “text ~/*.text {a,b} $(echo leaf) $((2+3)) $USER”
text ~/*.text {a,b} leaf 5 leaf
leaf@leaf-X455LA:~$ echo ‘text ~/*.text {a,b} $(echo leaf) $((2+3)) $USER’
text ~/*.text {a,b} $(echo leaf) $((2+3)) $USER
leaf@leaf-X455LA:~$

Escaping characters (các ký tự thoát)

Nếu bạn muốn quote một ký tự đơn thì có thể dùng một dấu blackslash trước một ký tự. Các ký tự này được gọi là các escaping characters. Thường nó được dùng trong các double quotes để ngăn chặn các expansions. Ví dụ:

leaf@leaf-X455LA:~$ echo “So tien con lai cua nguoi dung $USER la: \$5.00”
So tien con lai cua nguoi dung leaf la: $5.00

Các escaping cũng được sử dụng khá phổ biến để loại bỏ các ý nghĩa đặc biệt của ký tự có trong tên file, thường là các ký tự “$”, “&”, “!”,” “. Ví dụ:

leaf@leaf-X455LA:~$ cat > ten\ xau.txt
day la mot ten xau
leaf@leaf-X455LA:~$ mkdir good_name
leaf@leaf-X455LA:~$ mv ten\ xau.txt good_name
leaf@leaf-X455LA:~$

Lưu ý, để in ra dấu “\” thì bạn sử dụng “\\” và nếu dùng backslash trong single quote thì nó sẽ mất đi ý nghĩa đặc biệt của mình và được sử dụng như một ký tự thông thường.

More backslash tricks

Nếu nhìn vào các man pages (Ở các bài trước), bạn sẽ chú ý sẽ có những tùy chọn được tạo thành bởi một dấu “-” (dash) và một ký tự, nhưng cũng có những tùy chọn được tạo bởi hai dấu dash (“–“) và một cái tên dài. Ví dụ:

ls -r

ls –reverse

Shell hỗ trợ cả hai bởi vì tùy thuộc vào người dùng, có người dùng trên Terminal thích kiểu ngắn gọn, còn có người thì viết script cần ý nghĩa rõ ràng.

Bây giờ, câu hỏi đặt ra là nếu một câu lệnh nào đó rất dài cho một dòng của Terminal, làm thế nào để xuống dòng mà Shell vẫn hiểu các dòng đó đều thuộc một câu lệnh? Vấn đề sẽ được giải quyết nếu bạn sử dụng backslash (\). Ví dụ:

leaf@leaf-X455LA:~$ echo “xin chao cac ban,\
>  day la vi du ve cong dung cua \
>  dau \\ tren shell”
xin chao cac ban, day la vi du ve cong dung cua  dau \ tren shell
leaf@leaf-X455LA:~$

Sử dụng backslash cho phép chúng ta nhúng ký tự newline vào một câu lệnh, sau đây là một số ký tự đặc biệt khi sử dụng với backslash:

Escaping characters

Tên

Có thể dùng

\n Ký tự xuống dòng Thêm các dòng trống vào đoạn text
\t Tab Chèn các ký tự tab ngang vào đoạn text
\a Alert Làm cho Terminal phát tiếng bip
\\ Dấu backslash Chèn vào một dấu backslash
\f Formfeed Gửi nó tới máy in bỏ ra trang

Ví dụ:

leaf@leaf-X455LA:~$ echo -e “Inserting several blank lines \n\n\n”
Inserting several blank lines

leaf@leaf-X455LA:~$ echo -e “Words\tseparated\tbyhorizonal\ttabs.”
Words    separated    byhorizonal    tabs.
leaf@leaf-X455LA:~$ echo -e “\aMy computer went \”beep\”.”
My computer went “beep”.

leaf@leaf-X455LA:~$ echo -e “DEL C:\\Win2k\\LEGACY_OS.exe”
DEL C:\Win2k\LEGACY_OS.exe
leaf@leaf-X455LA:~$

Dấu “\” được sử dụng khá phổ biến, nếu bạn đã học lập trình C/C++ hoặc vài ngôn ngữ khác, bạn cũng sẽ thấy công dụng tương tự. Bài viết này kết thúc ở đây, chào các bạn!

Bài viết này chúng ta sẽ tìm hiểu các tính năng mạnh mẽ của việc chuyển hướng I/O.

Các lệnh mà chúng ta đã biết, ví dụ như ls sẽ hiển thị ra màn hình output của nó. Nhưng chúng ta có thể chuyển hướng đầu ra của một số lệnh bằng các ký tự đặc biệt ra files, các thiết bị, hoặc làm input cho bất cứ lệnh nào khác.

Trên một hệ thống Unix-like như Linux thì có các khái niệm sau:

Standard Output

Hầu hết chương trình dạng command line sẽ hiển thị kết quả của nó ra một thiết bị xuất cơ bản gọi là Standard Ouput, thông thường là màn hình. (Nếu các bạn học qua C/C++ thì sẽ rõ khái niệm này). Mặc định, Standard Ouput hướng nội dung kết quả của chương trình để hiển thị. Để chuyển hướng standard output ra một file thì sử dụng ký hiệu “>” cú pháp:

command > file

trong đó, command là lệnh thực thi, file là tên một file cần xuất kết quả của lệnh vào, ví dụ:

cr0ss@cr0ss-X455LA:~$ ls > text.txt
cr0ss@cr0ss-X455LA:~$

Ở ví dụ trên, sau khi Shell thực thi lệnh ls, kết quả sẽ được ghi vào file text.txt mà không in ra màn hình.

Mỗi thời điểm, nếu lệnh chuyển hướng như ví dụ ở trên tới file text.txt nó sẽ ghi đè lên nội dung cũ của file. Nếu muốn bổ sung nội dung vào file text.txt từ end of file để không ghi đè lên nội dung trước đó, bạn dùng ký hiệu “>>”, ví dụ:

cr0ss@cr0ss-X455LA:~$ ls >> text.txt
cr0ss@cr0ss-X455LA:~$

khi chuyển hướng standard ouput, nếu file chưa tồn tại thì nó sẽ được tạo mới. Có thể kiểm tra nội dung file text.txt bằng lệnh less.

Standard Input

Nhiều lệnh có thể nhận input từ một thiết bị nhập chuẩn cơ bản gọi là Standard Input. Mặc định, Standard Input lấy nội dung đầu vào từ keyboard, nhưng cũng giống Standard Output, nó cũng có thể được chuyển hướng. Để chuyển hướng Standard Input dùng file thay thế cho keyboard, bạn dùng ký hiệu “<“ theo sau lênh, cú pháp

command < file

lấy ví dụ với file text.txt lúc nãy:

cr0ss@cr0ss-X455LA:~$ sort < text.txt
cocos2d-x-3.10
Documents
Downloads
Dropbox
Music
MyData
opencv
Pictures
Public
Qt
shell
sketchbook
Templates
text.txt
Videos
WP_backup_codespdf
cr0ss@cr0ss-X455LA:~$

ví dụ trên sử dụng lệnh sort nhận đầu vào từ file text.txt, sau đó sắp xếp nội dung của nó rồi xuất ra màn hình. Nếu bạn muốn kết quả sau khi sorted lưu vào file thì có thể chuyển hướng standard output ra một file mới, ví dụ:

cr0ss@cr0ss-X455LA:~$ sort < text.txt > sorted_text.txt
cr0ss@cr0ss-X455LA:~$

Nếu file sorted_text.txt chưa tồn tại thì Shell sẽ tạo mới. Bạn có thể kiểm tra nội dung của các file bằng lệnh less.

Như các bạn thấy trên ví dụ trên, một lệnh có thể được chuyển hướng cả standard input và standard output. Thứ tự chuyển hướng không quan trọng, nhưng các toán tử chuyển hướng như (“>”,”<“) phải nằm sau các tùy chọn và đối số của các lệnh.

Pipelines

Thứ hữu ích và mạnh mẽ nhất có thể làm với chuyển hướng I/O là kết nối nhiều lệnh với nhau với cái được gọi là pipelines. Với pipelines, Standard Output của một lệnh có thể được nhận làm Standard Input của một lệnh khác. Ví dụ:

cr0ss@cr0ss-X455LA:~$ ls -l | less

drwxrwxr-x 15 cr0ss cr0ss 4096 Th03 3 18:11 cocos2d-x-3.10
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Documents
drwxr-xr-x 2 cr0ss cr0ss 4096 Th04 2 20:05 Downloads
drwx—— 6 cr0ss cr0ss 4096 Th04 2 15:04 Dropbox
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Music
drwx—— 5 cr0ss cr0ss 4096 Th03 30 20:13 MyData
drwxrwxr-x 13 cr0ss cr0ss 4096 Th03 3 16:38 opencv
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 13 20:24 Pictures
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Public
drwxrwxrwx 8 cr0ss cr0ss 4096 Th03 3 16:28 Qt
drwxrwxr-x 2 cr0ss cr0ss 4096 Th03 30 20:26 shell
drwxrwxr-x 3 cr0ss cr0ss 4096 Th03 20 02:41 sketchbook
-rw-rw-r– 1 cr0ss cr0ss 144 Th04 2 22:28 sorted_text.txt
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Templates
-rw-rw-r– 1 cr0ss cr0ss 144 Th04 2 22:24 text.txt
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Videos
-rw——- 1 cr0ss cr0ss 57940 Th03 28 01:53 WP_backup_codespdf
(END)

Đầu ra của lệnh ls được nhận vào đầu vào của lệnh less. Bằng việc dùng mẹo ” | less” bạn có thể chuyển hướng output đi bất kỳ đâu. Kết nối các lệnh với nhau, bạn có thể hoàn thành nhiều công việc tuyệt vời, dưới đây là các ví dụ:

Lệnh

Công dụng

ls -lt | head

Hiển thị 10 file mới nhất trong thư mục hiện hành

du | sort -nr

Hiển thi danh sách các thư mục và không gian nhớ chúng chiếm dùng, đồng thời sắp xếp từ lớn nhất tới nhỏ nhất

find . -type f -print | wc -l

Hiển thị tổng số file trong thư mục hiện hành và các thư mục con của nó

Filters

Một loại chương trình thường xuyên sử dụng pipelines được gọi là Filters. Filters nhận standard input và thực hiện một hành động tới khi nó gửi kết quả đến standard output. Bằng cách này chúng có thể được kết hợp với nhau để xử lý thông tin một cách mạnh mẽ, dưới đây là bảng các Filters phổ biến:

Chương trình

Công dụng

sort

Sắp xếp standard input và xuất kết quả được sắp xếp ra standard output.

uniq

Cho một dòng dữ liệu đã được sắp xếp từ standard input, sau đó loại bỏ các dòng trùng lặp dữ liệu (đảm bảo rằng mỗi dòng vào là duy nhất).

grep

Kiểm tra mỗi dòng dữ liệu vào nhận được từ standard input và xuất ra mỗi dòng có chứa những mẫu ký tự đặc biệt.

fmt

Đọc văn bản từ standard input sau đó xuất văn bản đã được định dạng ra standard output.

pr

Lấy văn bản từ standard input và chia dữ liệu thành các trang với các ngắt trang, headers footers để chuẩn bị in

head

Xuất ra một vài dòng đầu tiên của đầu vào của nó. Hữu ích đối với việc lấy header của file.

tail

Xuất ra vài dòng cuối của đầu vào. Hữu ích cho việc nhận các mục gần đây của file log

tr

Dịch ký tự. Có thể được sử dụng để thực hiện các nhiệm vụ như chuyển đổi chữ hoa / chữ thường hoặc các ký tự chấm dứt việc thay đổi dòng từ một loại khác (ví dụ, chuyển đổi file văn bản DOS vào file text kiểu Unix).

sed

Stream editor, có thể thực hiện chuyển đổi văn bản phức tạp hơn lệnh tr

awk

Toàn bộ một ngôn ngữ lập trình được thiết kế để xây dựng các filter. Cực kỳ mạnh mẽ.

Thực hiện các tác vụ với pipelines

  1. In từ command line: Linux cung chương trình lpr nhận standard input và gửi nó tới máy in. Nó được sử dụng với các pipe và filter, ví dụ:
    cat text.txt  | fmt | pr | lpr
    cat text.txt | sort | uniq | pr | lpr
    trong ví dụ thứ nhất, sử dụng cat để đọc file và xuất nó ra standard output, đó là một pipe vào một standard input của fmt, fmt định dạng văn bản thành các đoạn gọn gàng và xuất nó ra standard output, là standard input của pr, pr chia đoạn văn bản thành các trang và xuất nó ra standard output, là standard input của lpr, lpr đưa nó tới standard input và gửi tới máy in.
    Ví dụ thứ hai cũng tương tự như ví dụ thứ nhất
  2. View nội dung của các file tar: Bạn đã biết, các file lưu trữ trên Linux được tạo ra bởi tar, nén bởi gzip theo các họ tar.gz hoặc targz. Để xem các thư mục của một tập tin trong hệ thống Linux thì dùng lệnh sau: tar tzvf ten_cua_file_tar.tar.gz | less

Bài này kết thúc ở đây, chào các ban!

Ở các bài trước, chúng ta đã tìm hiểu được vài lệnh trên Shell, về ý nghĩa, các tùy chọn và đối số của nó,…

Tất cả các lệnh trên Shell chúng ta đã học và sắp học đều thuộc 4 loại sau:

  • Một chương trình thực thi: tất cả chúng  được chứa trong /usr/bin (các bạn có thể mở thư mục này để xem). Với loại này, chương trình có thể được compile thành các file binary. Như một chương trình được viết bằng C, C++ hoặc một ngôn ngữ script như Ruby, Python, Perl,..
  • Lệnh được xây dựng sẵn (built-in) trên Shell: ví như lệnh cd, ls, cp,mv,.. trên Shell là các lệnh được xây dựng sẵn.
  • Một hàm Shell: Là một Shell script thu nhỏ được tích hợp vào trong môi trường. Chúng ta sẽ tìm hiểu về cấu hình môi trường và viết một hàm Shell ở các bài học sau.
  • Một tên giả (alias): Những lệnh mà bạn có thể tự định nghĩa, xây dựng từ các lệnh khác. Chúng ta sẽ tìm hiểu sau.

Các lệnh trên Shell cùng các tùy chọn hay đối số của nó có khi nào khiến bạn thoắc mắc nó thuộc nhóm nào trong 4 nhóm trên hay bên trong nó có những bí ẩn gì không? Nếu có, giờ chúng ta cùng khám chúng thông qua các lệnh sau:

Xác định các lệnh:

type

Lệnh này là một trong các lệnh built-in của Shell. Dùng để hiển thị thể loại của lệnh có tên cụ thể mà Shell sẽ thực thi. Cú pháp của nó như sau:

type command

Với command là tên lệnh cần tìm hiểu. Ví du:

cr0ss@cr0ss-X455LA:~$ type cp
cp is /bin/cp
cr0ss@cr0ss-X455LA:~$ type ls
ls is aliased to `ls –color=auto’
cr0ss@cr0ss-X455LA:~$ type mv
mv is /bin/mv
cr0ss@cr0ss-X455LA:~$

Lưu ý ở lệnh type ls sẽ cho kết quả ls là một alias to `ls –color=auto’, điều này lý giải tại sao khi các bạn thực hiện lệnh ls trên Terminal của mình sẽ có các màu khác nhau cho các file và thư mục.

which

Thỉnh thoảng có nhiều hơn một phiên bản của chương trình thực thi nào đó được cài đặt lên hệ thống. Điều này không gây ra bất thường gì trên các servers lớn khi mà nó không chung các hệ thống Desktop. Cú pháp:

which command

trong đó command là lênh cần xác định, dùng để xác định chính xác địa điểm của chương trình thực thi. Ví dụ:

cr0ss@cr0ss-X455LA:~$ which ls
/bin/ls

––> Lưu ý: which chỉ dùng cho các chương trình thực thi, không dùng cho các lệnh được xây dựng sẵn hay alias, mà là thay thế cho các chương trình thực thi thực tế.

Lấy tài liệu hướng dẫn của các lệnh:

help

bash có một trợ giúp built-in cho các Shell built-in. Cú pháp sử dụng:

help option command

trong đó option có thể là -m để thay đổi định dạng của ngõ ra, ví dụ:

cr0ss@cr0ss-X455LA:~$ help -m cd
NAME
cd – Change the shell working directory.

SYNOPSIS
cd [-L|[-P [-e]] [-@]] [dir]

DESCRIPTION
Change the shell working directory.

Change the current directory to DIR. The default DIR is the value of the
HOME shell variable.

The variable CDPATH defines the search path for the directory containing
DIR. Alternative directory names in CDPATH are separated by a colon (:).
A null directory name is the same as the current directory. If DIR begins
with a slash (/), then CDPATH is not used.

If the directory is not found, and the shell option `cdable_vars’ is set,
the word is assumed to be a variable name. If that variable has a value,
its value is used for DIR.

Options:
-L force symbolic links to be followed: resolve symbolic links in
DIR after processing instances of `..’
-P use the physical directory structure without following symbolic
links: resolve symbolic links in DIR before processing instances
of `..’
-e if the -P option is supplied, and the current working directory
cannot be determined successfully, exit with a non-zero status
-@ on systems that support it, present a file with extended attributes
as a directory containing the file attributes

The default is to follow symbolic links, as if `-L’ were specified.
`..’ is processed by removing the immediately previous pathname component
back to a slash or the beginning of DIR.

Exit Status:
Returns 0 if the directory is changed, and if $PWD is set successfully when
-P is used; non-zero otherwise.

SEE ALSO
bash(1)

IMPLEMENTATION
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later

cr0ss@cr0ss-X455LA:~$

––> Lưu ý: Khi một dấu ngoặc vuông xuất hiện trong một mô tả cú pháp của lệnh, trong dấu ngoặc vuông, dấu “|” dùng để phân cách các tùy chọn của lênh, trong ví dụ trên ta thấy:

cd [-L|-P] [dir]

Có nghĩa là lệnh cd được tùy chọn bởi -L hoặc -P và theo sau bởi tham số dir.

–help

Nhiều chương trình thực thi có hỗ trợ tùy chọn –help để mô tả các hỗ trợ về cú pháp của lệnh. Ví dụ:

cr0ss@cr0ss-X455LA:~$ cp –help
Usage: cp [OPTION]… [-T] SOURCE DEST
or: cp [OPTION]… SOURCE… DIRECTORY
or: cp [OPTION]… -t DIRECTORY SOURCE…
Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

Mandatory arguments to long options are mandatory for short options too.
-a, –archive same as -dR –preserve=all
–attributes-only don’t copy the file data, just the attributes
–backup[=CONTROL] make a backup of each existing destination file
-b like –backup but does not accept an argument
–copy-contents copy contents of special files when recursive
-d same as –no-dereference –preserve=links
-f, –force if an existing destination file cannot be
opened, remove it and try again (this option
is ignored when the -n option is also used)
-i, –interactive prompt before overwrite (overrides a previous -n
option)
-H follow command-line symbolic links in SOURCE
-l, –link hard link files instead of copying
-L, –dereference always follow symbolic links in SOURCE
-n, –no-clobber do not overwrite an existing file (overrides
a previous -i option)
-P, –no-dereference never follow symbolic links in SOURCE
-p same as –preserve=mode,ownership,timestamps
–preserve[=ATTR_LIST] preserve the specified attributes (default:
mode,ownership,timestamps), if possible
additional attributes: context, links, xattr,
all
–no-preserve=ATTR_LIST don’t preserve the specified attributes
–parents use full source file name under DIRECTORY
-R, -r, –recursive copy directories recursively
–reflink[=WHEN] control clone/CoW copies. See below
–remove-destination remove each existing destination file before
attempting to open it (contrast with –force)
–sparse=WHEN control creation of sparse files. See below
–strip-trailing-slashes remove any trailing slashes from each SOURCE
argument
-s, –symbolic-link make symbolic links instead of copying
-S, –suffix=SUFFIX override the usual backup suffix
-t, –target-directory=DIRECTORY copy all SOURCE arguments into DIRECTORY
-T, –no-target-directory treat DEST as a normal file
-u, –update copy only when the SOURCE file is newer
than the destination file or when the
destination file is missing
-v, –verbose explain what is being done
-x, –one-file-system stay on this file system
–help display this help and exit
–version output version information and exit

By default, sparse SOURCE files are detected by a crude heuristic and the
corresponding DEST file is made sparse as well. That is the behavior
selected by –sparse=auto. Specify –sparse=always to create a sparse DEST
file whenever the SOURCE file contains a long enough sequence of zero bytes.
Use –sparse=never to inhibit creation of sparse files.

When –reflink[=always] is specified, perform a lightweight copy, where the
data blocks are copied only when modified. If this is not possible the copy
fails, or if –reflink=auto is specified, fall back to a standard copy.

The backup suffix is ‘~’, unless set with –suffix or SIMPLE_BACKUP_SUFFIX.
The version control method may be selected via the –backup option or through
the VERSION_CONTROL environment variable. Here are the values:

none, off never make backups (even if –backup is given)
numbered, t make numbered backups
existing, nil numbered if numbered backups exist, simple otherwise
simple, never always make simple backups

As a special case, cp makes a backup of SOURCE when the force and backup
options are given and SOURCE and DEST are the same name for an existing,
regular file.

Report cp bugs to
GNU coreutils home page: General help using GNU software: For complete documentation, run: info coreutils ‘cp invocation’
cr0ss@cr0ss-X455LA:~$

Một vài chương trình không có tùy chọn –help, nhưng nếu bạn cố thử thì nó sẽ báo lỗi trên Terminal.

man

Hầu hết các chương trình thực thi dạng command line có cung cấp một phần chính thức của tài liệu được gọi là manual hoặc man page. man là một chương trình phân trang đặc biệt có cú pháp:

man program

trong đó program là của một lệnh cần view. Các man page thường khác nhau nhưng hình thức vẫn là mô tả cú pháp của lệnh, mục đích của lệnh, danh sách các tùy chọn của lệnh, được sử dụng như một tài liệu tham khảo không phải là một hướng dẫn. Ví dụ:

cr0ss@cr0ss-X455LA:~$ man ls

sẽ view các cú pháp, tùy chọn, mục đích của lệnh ls. Khi muốn thoát khỏi man page bạn bấm q.

Trên hầu hết các hệ thống Linux thì man sử dụng less để view các man page.

Bài sau chúng ta sẽ tìm hiểu các lệnh chuyển hướng I/O, chào các bạn!

Bài viết này giới thiệu các lệnh manipulate files/folders trên Shell.

Shell có cung cấp vài tính năng để thao tác các lệnh một cách hiệu quả hơn. Khi Shell sử dụng quá nhiều tên file, nó cung cấp cho bạn các kí tự đặc biệt để xác định một cách nhanh chóng nhóm các file. Các ký tự này được biết đến với cái tên wildcards. Bao gồm:

Wildcard

Ý nghĩa

* Tương ứng với bất kỳ ký tự nào
? Tương ứng với bất kỳ ký tự đơn nào
[character] Tương ứng với bất kỳ ký tự nào là một thành viên của các ký tự được đặt sẵn có thể được thể hiện như là một lớp các ký tự trên hệ thống POSIX.

POSIX Character class

[:alnum:] Các ký tự số

[:alpha:] Các ký tự alphabet

[:digit:] Các số

[:upper:] Các ký tự alphabet viết hoa

[:lower:] Các ký tự alphabet viết thường

[!character] Tương ứng với bất kỳ ký tự nào mà không phải là một thành viên của các ký tự được đặt sẵn

Ví dụ:

  • * là tên tất cả các tập tin có trong thư mục hiện hành.
  • g* là tên các tập tin bắt đầu bằng g trong thư mục hiện hành.
  • b*.txt là tên tất cả các tập tin bắt đầu bằng ký tự b và kết thúc bằng đuôi định dạng .txt.
  • Data??? là tên bất kỳ tập tin nào bắt đầu bằng Data và thêm 3 ký tự phía sau nữa
  • [abc]* là tên bất kỳ tập tin nào bắt đầu với a hoặc b hoặc c và theo sau bởi các ký tự khác.
  • [[:upper:]]* là tên tập tin bất kỳ bắt đầu bằng các ký tự alphabet hoa và theo sau bởi các ký tự khác. (đây là ví dụ cho lớp các ký tự đặt sẵn trên POSIX)
  • BACKUP.[[:digit:]][[:digit:]] là tên bất kỳ file nào bắt đầu bằng các ký tự “BACKUP” và theo sau nó là hai số
  • *[![:lower:]] bất kỳ file nào không kết thúc bởi ký tự alphabet thường.

––> Ghi chú: Có thể sử dụng wildcard với bất kỳ lệnh nào trên Shell cho phép nhận tên file làm đối số của lệnh.

Các lệnh manipulate:

cp

Lệnh cp cho phép copy file và thư mục. Có các dạng đơn giản như:

cr0ss@cr0ss-X455LA:~$ cp file1 file2

Cho phép sao chép nội dung của file1 vào file2. Với file1, file2 là tên các file cần thao tác.

cr0ss@cr0ss-X455LA:~$ cp file… directory

Cho phép chép file vào directory. Lưu ý: các ký tự … theo sau file có thể là nhiều tên file, có tác dụng copy nhiều file một lúc.

Ví dụ, trong thư mục hiện tại của mình đang chứa 2 file là file1.txt và file2.txt, giờ mình sẽ xem nội dung  file1.txt trước.

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file1.txt

123
file1.txt (END)

tiếp đến là file2.txt

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file2.txt

456
file2.txt (END)

OK, giờ mình sẽ thực hiện lệnh cp

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt file2.txt
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$

và giờ xem lại nội dung từng file nhé, trước hết là file1.txt

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file1.txt

123
file1.txt (END)

và file2.txt

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file2.txt

123
file1.txt (END)

phần copy file vào thư mục thì các bạn tự demo thử nha!

Một số ví dụ thường gặp về lệnh cp:

  • cp file1 file2: copy nội dung file1 vào file2, nếu file2 chưa tồn tại, nó sẽ tạo. Nếu file2 đã tồn tại, nó sẽ ghi đè lên nội dung cũ của file2.
  • cp -i file1 file2: -i (iteractive) là ký hiệu đặc biệt.  Nếu file2 đã tồn tại, Shell sẽ nhắc nhở bạn trước khi ghi đè nội dung của file1 lên file2.
  • cp file1 dir1: copy file1 vào thư mục dir1
  • cp -R dir1 dir2: copy nội dung của thư mục dir1 vào thư mục dir2, nếu dir2 đã tồn tại, Shell sẽ ghi đè lên nội dung cũ của nó, nếu dir2 chưa tồn tại, Shell sẽ tạo mới dir2.

mv

Lệnh mv dùng để chuyển hoặc đổi tên file hoặc thư mục tùy vào cách nó được sử dụng như thế nào. Cú pháp như sau:

cr0ss@cr0ss-X455LA:~$ cp file1 file2

Để chuyển file vào một thư mục:

cr0ss@cr0ss-X455LA:~$ mv file… directory

Các ví dụ về lệnh mv gồm các tùy chọn:

  • mv file1 file2: Nếu file2 chưa tồn tại, nó sẽ đổi tên file1 thành file2. Nếu file2 đã tồn tại, nó sẽ thay thế nội dung của file2 thành nội dung của file1.
  • mv -i file1 file2: -i (iteractive) là một tùy chọn đặc biệt, nếu file2 đã tồn tại, Shell sẽ hỏi bạn có chắc về việc thay thế nội dung của file2 thành nội dung file1 không.
  • mv file1 file2 file3 dir: Chuyển file1, file2, file3 đến thư mục dir. Nếu dir chưa tồn tại, Shell sẽ báo lỗi.
  • mv dir1 dir2: Nếu dir2 chưa tồn tại, Shell sẽ đổi tên dir1 thành dir2. Nếu dir2 đã tồn tại, Shell sẽ chuyển thư mục dir1 vào trong thư mục dir2.

Phần demo các bạn tự làm nhé! 🙂

rm

Lệnh rm trên Shell dùng để xóa file hoặc thư mục. Cú pháp là:

cr0ss@cr0ss-X455LA:~$ rm file…

Dùng để xóa file. Và

cr0ss@cr0ss-X455LA:~$ rm -r dir…

Để xóa thư mục. (Các bạn lưu ý tùy chọn -r trong lệnh xóa thư mục).

Các ví dụ về lệnh rm:

  • rm file1 file2: Xóa file1 và file2.
  • rm -i file1 file2: Có thêm tùy chọn -i, Shell sẽ nhắc nhở bạn khi thực hiện xóa mỗi file.
  • rm -r dir1 dir2: Thư mục dir1, dir2 sẽ được xóa cùng với tất cả các thành phần chứa trong nó.

–-> Lưu ý các bạn nên cẩn thận khi sử dụng lênh rm. Trước khi dùng nó bạn phải tuyệt đối cân nhắc, bằng cách sử dụng các lệnh hữu ích khác như ls để liệt kê các file để chắc chắn rằng mình sẽ xóa đúng file. Bởi nếu bạn xóa nhầm một file hệ thống nào đó sẽ gây hậu quả rất nghiêm trọng

mkdir

Lệnh mkdir dùng để tạo một thư mục, cú pháp:

cr0ss@cr0ss-X455LA:~$ mkdir directory

Lệnh này sẽ tạo ra một thư mục có tên directory trong thư mục hiện hành.

––> Các lệnh có sử dụng wildcard

  • cp *.txt text_files: Copy tất cả các file kết thúc bằng đuôi .txt trong thư mục hiện hành vào một thư mục đã tồn tại có tên text_files.
  • mv my_dir ../*.bak my_new_dir: Chuyển thư mục con my_dir và tất cả các file kết thúc bằng .bak trong thư mục cha hiện hành vào trong thư mục mới đã tồn tại có tên là my_new_dir.
  • rm *~: Xóa tất cả các file kết thúc bằng ~ trong thư mục hiện hành. Một vài ứng dụng sẽ tạo file sao lưu sử dụng sơ đồ đặt tên này. Dùng lệnh này sẽ xóa tất cả ra khỏi thư mục.

Có một lệnh khá hữu ích nữa trên Shell đó là lệnh clear. Lệnh này dùng để xóa màn hình trên Terminal. Chính xác là sau khi bạn dùng lệnh này Terminal sẽ chuyển sang một page mới bằng một ký tự đặc biệt, ví dụ, màn hình Terminal của mình trước khi dùng clear là như thế này:

cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file1.txt
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ less file2.txt
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt… ~/Desktop
cp: cannot stat ‘file1.txt…’: No such file or directory
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt … ~/Desktop
cp: target ‘/home/cr0ss/Desktop’ is not a directory
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt … ~/Doccuments
cp: target ‘/home/cr0ss/Doccuments’ is not a directory
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cd ~
cr0ss@cr0ss-X455LA:~$ mkdir shell
cr0ss@cr0ss-X455LA:~$ cd ~/MyData/vidu_shell
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt … ~/shell
cp: cannot stat ‘…’: No such file or directory
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cp file1.txt ~/shell
cr0ss@cr0ss-X455LA:~/MyData/vidu_shell$ cd ~
cr0ss@cr0ss-X455LA:~$ clear

và sau khi  Enter ở dòng clear:

cr0ss@cr0ss-X455LA:~$

Ở bài sau mình sẽ nói về các lệnh xác định và lệnh hỗ trợ khi bạn không biết dạng lệnh của nó trên Shell như thế nào. Chào các bạn!

Bài viết này sẽ đề cập đến một số vấn đề mình đã nói sơ qua ở bài trước như cấu trúc thư mục trong Linux hay hệ thống Unix-like, quyền truy cập file (permisson),.. và mình sẽ giới thiệu một số lệnh khác.

Thư mục trên Linux.

Để hiểu được ý nghĩa của các tham số trong các câu lệnh, chẳng hạn như  cd ~/Downloads, bạn phải hiểu được cấu trúc của hệ thống thư mục trên Linux và Unix-likes

Không giống như trên Windows, các cây thư mục đều bắt nguồn từ các ổ đĩa, các hệ thống Unix-like lại bắt đầu bằng thư mục gốc, hay thư mục root (ký hiệu là /). Khái niệm ổ đĩa của Windows hay thư mục / của Unix-like đều là sự trừu tượng hóa tài nguyên lưu trữ (phần cứng) của hệ điều hành mà thôi. Các cây thư mục đều biểu diễn cấu trúc tổ chức thư mục trên một hệ điều hành, chỉ khác nhau một điểm đó là Windows có thể có nhiều cây thư mục tùy thuộc vào việc bộ nhớ của nó được trừu tượng thành bao nhiêu ổ đĩa, còn hệ thống Unix-like chỉ có một cây thư mục duy nhất bắt nguồn từ /.

Tóm tắt ý nghĩa của từng thư mục chính trên Unix-Linux.

Directory Description
/ Đây là thư mục gốc (root directory), là nơi bắt đầu của các file hệ thống, trong hầu hết các trường hợp, thư mục gốc chỉ chứa các thư mục con
/boot Đây là nơi mà Nhân Linux và file boot của hệ thống được lưu trữ, Nhân linux là file được gọi là vzlinuz.
/etc Thư mục /etc chứa các file cấu hình (configuration) của hệ thống. Các file trong /etc đa số là các file text. Điển hình là:

/etc/passwd: file này chứa thông tin cần thiết cho mỗi người dùng, trên đó chứa những người dùng được định nghĩa trên hệ thống

/etc/fstab: file này chứa một bảng các thiết bị được gắn kết khi hệ thống boot. File này định nghĩa ổ đĩa của bạn

/etc/hosts: file này liệt kê danh sách các host mạng  và địa chỉ IP và bản chất của hệ thống

/etc/init.d: thư mục này chứa các script, bắt đầu những dịch vụ thông thường khác nhau của hệ thống tại thời điểm boot

/bin, /usr/bin Hai thư mục này chưa hầu hết các chương trình trên hệ thống. /bin chứa các chương trình cần thiết để hệ thống yêu cầu tổ chức. Trong khi đó, /usr/bin lại chứa các chương trình ứng dụng cho các người dùng trên hệ thống
/sbin, /usr/sbin Thư mục /sbin chứa các chương trình cho người quản trị hệ thống, được sử dụng thông qua tên gọi superuser
/usr Thư mục này chứa các thứ đa dạng hỗ trợ cho người dùng ứng dụng. Ví dụ như:

/usr/share/X11: hỗ trợ người dùng hệ thống X windows

/usr/share/dict: các từ điển kiểm tra chính tả, Linux có một bộ phận kiểm tra chính tả, tiêu biểu là look và ispell

/usr/share/doc: các file tài liệu khác nhau trong một sự đa dạng các định dạng

/usr/share/man: các trang người dùng được giữ ở đây

/usr/src: chứa các file source code, nếu bạn cài đặt gói mã nguồn của nhân, bạn sẽ tìm thấy toàn thể source code của nhân ở trong này

/usr/local Nó là thư mục con dùng để cài đặt phần mềm hoặc các file khác dùng trên máy cục bộ. Nó có ý nghĩa khi phần mềm không là một phần của sự phân tán chính thức (thường ở trong /usr/bin).

Khi bạn tìm thấy một chương trình yêu thích trên hệ thống, chúng được cài đặt trong một trong các thư mục nằm trong /usr/local. Hầu hết, thư mục được chọn là /usr/local/bin

/var Thư mục này có chứa các file thay đổi khi hệ thống khởi chạy. Bao gồm:

/var/log: thư mục chứa các file log, chúng sẽ cập nhật khi hệ thống chạy, bạn nên xem file này trong từng thời điểm để nắm bắt “sức khỏe” của hệ thống.

/var/spool: thư mục này giữ các file được xếp hàng cho một vài tiến trình, như tin nhắn mail hoặc in công việc. Khi mail của người dùng gửi đến hệ thống lần đầu tiên trong một hệ thống cục bộ, tin nhắn được lưu trữ đầu tiên ở /var/spool

/lib Chứa các thư viện chia sẻ được (tương tự như các thư viện DLL trên windows)
/home Là nơi người dùng giữ việc của mình. Thông thường, nó chỉ là nơi người dùng được phép viết file. Nó giữ mọi thứ tốt và sạch sẽ. Bởi vì hệ thống Linux cho phép nhiều người dùng khác nhau trên một hệ thống. Sẽ thật tê nếu như bạn làm gì ảnh hưởng đến người dùng khác J
/root Là thư mục của superuser
/tmp Thư mục mà chương trình có thể viết các file tạm
/dev Là một thư mục khá đặc biệt, nó không chứa các file theo đúng nghĩa, nó chỉ chứa các thiết bị trên hệ thống. (trong hệ thống Linux hoặc Unix, các thiết bị được xem như file, chẳng hạn, bàn phím, màn hình, ổ đĩa,… đều là file trên Unix-Linux) ví dụ /dev/SDA là IDE ổ cứng đầu tiên trên hệ thống (nếu bạn cài Linux rồi thì bạn sẽ biết tới cái này)
/proc Nó cũng là thư mục khá đặc biệt. Trên thực tế, không phải tất cả các thư mục đều tồn tại, có một số là ảo. /proc là một trong số đó, nó chứa các lỗ dẫn tới nhân. Chúng là một nhóm các lối vào trong thư mục này tương ứng với tất cả các tiến trình đang chạy trên hệ thống. Một vài trong số chúng có thể view được, chẳng hạn bạn vào /proc/cpuinfo.
/media, /mnt /media là một thư mục đặc biêt, nó dùng để chuyển các điểm. Như chúng ta đã biết, các thiết bị lưu trữ vật lý như ổ cứng được đính kèm trong hệ thống cây thư mục. Tiến trình đính kèm một thiết bị vào cây  gọi là mounting.

Khi hệ thống khởi động, nó đọc danh sách các lệnh mounting trong /etc/fstab mô tả thiết bị được chuyển và trong cây thư mục. Tuy nhiên có nhiều thiết bị yêu cầu file tạm(tempotary file) như CD-ROM,  /media được dùng cho các thiết bị mounting tự đông, còn /mnt cung cấp một nơi thuận tiện để mounting các thiết bị có thể tháo được như CD-ROM, bạn sẽ thường thấy  thư mục /mnt/cdrom. Để xem các thiết bị và mount point bạn có thể gõ mount trên Terminal.

Tiếp theo sẽ là các Permission của người dùng.

Bài trươc mình đã nói sơ qua về quyên của người dùng đối với một file, cụ thể sau khi gõ ls -l hoặc ls -l ~/Downloads (hai lệnh này mình đã nói ở bài viết trước, các bạn tham khảo lại nhé) thì nó sẽ hiện ra một danh sách các file/thư mục có trong thư mục hiện hành (đối với ls -l) hoặc trong thư mục /hom/user_name/Downloads (đối với lệnh ls -l ~/Downloads) với định dạng đầy đủ, ví dụ mình lấy một trong các kết quả in ra sau khi gõ lệnh ls -l ~/Downloads trên Terminal của mình (thư mục hiện hành của mình là /hom/cr0ss/) là:

cr0ss@cr0ss-X455LA:~$ ls -l ~/Downloads
total 453160
-rw-rw-r– 1 cr0ss cr0ss 326412652 Th03 11 03:25 android-sdk_r24.4.1-linux.tgz
-rw-rw-r– 1 cr0ss cr0ss 96036772 Th03 19 23:56 arduino-1.6.8-linux64.tar.xz

-rwxr-xr-x 1 cr0ss cr0ss 108 Th03 28 06:58 example.sh
-rw-rw-r– 1 cr0ss cr0ss 52758 Th03 28 20:02 bash.png
-rw-rw-r– 1 cr0ss cr0ss 20250097 Th03 10 16:43 codeblocks_16.01.tar.gz
-rw-rw-r– 1 cr0ss cr0ss 59092 Th03 29 14:08 file_permissions.png
-rw-rw-r– 1 cr0ss cr0ss 68472 Th03 28 15:42 filesystem-structure.png
-rw-rw-r– 1 cr0ss cr0ss 161280 Th03 28 01:04 thuat-toan-horner.doc
-rw-rw-r– 1 cr0ss cr0ss 20940288 Th03 25 21:55 vlc-2.2.1.tar.xz
cr0ss@cr0ss-X455LA:~$

Hai trong số các kết quả in ra :

-rw-rw-r-- 1 cr0ss cr0ss 20940288 Th03 25 21:55 vlc-2.2.1.tar.xz -rwxr-xr-x 1 cr0ss cr0ss 108 Th03 28 06:58 example.sh ---------- ------- ------- -------- ------------ ------------- | | | | | | | | | | | File Name | | | | | | | | | +--- Modification Time | | | | | | | +------------- Size (in bytes) | | | | | +----------------------- Group | | | +-------------------------------- Owner | +---------------------------------------------- File Permissions

các dòng khác thì tương tự. Đi từ phải sang trái:

  • vlc-2.2.1.tar.xz hoặc example.sh là file name.
  • Th03 25 21:25  hoặc Th03 28 06:58 là thời gian gần nhất bạn thao tác lên file đó (đọc, ghi, thực thi).
  • 20940288 hoặc 108 là kích thước của file.
  • cr0ss là nhóm người dùng có thể sử dụng được file đó.
  • cr0ss tiếp theo là tên user sở hữu file đó 1 là số thành phần có trong file/thư mục.
  • -rw-rw-r-- hoặc -rwxr-xr-x là file permissions là quyền truy cập file, trên hệ thống,do Linux là hệ thống phân quyền nên thông số này rất quan trọng.

∗ Ở đây mình chỉ tập trung vào thông số file permissions, các tham số file permissions có 4 nhóm: - Đầu tiên là dấu - có nghĩa là file hoặc d có nghĩa là thư mục - Tiếp theo là nhóm 3 ký tự kế tiếp: là các quyền của chủ sở hữu của file đó - Tiếp đến là nhóm 3 ký tự tiếp theo: là quyền của nhóm chủ sở hữu của file - Cuối cùng là nhóm 3 ký tự cuối: là quyền của các user khác Các chữ cái r, w, x, - tiếp theo nghĩa là quyền đọc ( r ), ghi ( w ),thực thi ( x ) và không được phép ( - ). Tất cả được giải thích theo hình vẽ dưới đây:

Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO

Bài viết sau này khi giới thiệu chi tiết về thay đổi quyền truy cập file sẽ nói chi tiết nhất về vấn đề này. Còn một lệnh nữa là lệnh less. less dùng để view một file text bất kỳ trong thư mục hiện hành hoặc trong bất kỳ thư mục nào kèm theo đường dẫn tới đó. Ví dụ mình đang ở thư mục /home/cr0ss/Downloads, khi gõ lệnh less example.sh trên Terminal sẽ cho kết quả như sau:

cr0ss@cr0ss-X455LA:~/Downloads$ less example.sh

#!/bin/bash
if [ $(id -u) != “0” ]; then
echo “You must be the superuser to run this script” >&2
exit 1
fi

và để thoát khỏi lệnh less thì bạn chỉ cần bấm q.

Các điều hướng trong less:

  • Page Up or b: Cuộn lên một trang
  • Page Down or space: Cuộn xuống một trang
  • G: Tới Cuối tập tin
  • 1G: Tới đầu tập tin
  • lcharacter: Tìm kiếm theo chiều xuôi của tập tin cho tới khi một ký tự character xuất hiện
  • n: Lặp lại tìm kiếm trước đó
  • h: Hiển thị danh sách đầy đủ ít các lệnh và lựa chọn
  • q: Thoát ra khỏi less

Bài này kết thúc ở đây, bài sau mình sẽ giới thiệu tiếp với các bạn các lệnh thao tác như cp, mv, rm,… và các lệnh thay đổi permission. Xin chào!

Các thao tác cơ bản trên Terminal

Hôm nay mình sẽ giới thiệu các thao tác trên terminal. Các bạn đọc bài giới thiệu của mình tại đây.

Giao diện sau khi mở của Terminal sẽ khác nhau đôi chút tùy vào hệ điều hành bạn sử dụng. Ví dụ Elementary OS nó sẽ trông như thế này:

cr0ss@cr0ss-X455LA:~$

Đầu tiên, ta test thử bàn phím trên Terminal bằng cách nhập 1 chuỗi ký tự bất kỳ, ví dụ

cr0ss@cr0ss-X455LA:~$ lskdjslakjfl

Terminal sẽ trả về kết quả như sau:

lskdjslakjfl: command not found

Nếu bạn nhận lại dòng lệnh như trên thì đừng lo lắng, mọi thứ đang vận hành tốt.

Ngoài bàn phím, bạn cũng có thể sử dụng chuột trên Terminal bằng cách cuộn trang lên-xuống, bôi đen kí tự, dòng,…

Ok, tất cả đã sẵn sàng cho các dòng lệnh đầu tiên trên Shell

Nhóm lệnh điều hướng (Nagavition) trên Shell: pwd (in ra thư mục làm việc hiện hành – print working directory), cd (chuyển thư mục – change directory), và ls (in ra danh sách các file và thư mục có trong thư mục đang làm việc), file (xác định kiểu dữ liệu được chứa trong file và in nó ra)

pwd

Trước tiên, các bạn xem cấu trúc thư mục của Linux và các hệ điều hành Unix-like

Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO

Về ý nghĩa và công dụng của các tên thư mục trong cây thư mục mình sẽ giải thích ở bài sau, giờ chúng ta sẽ tìm hiểu cách thao tác các lệnh cơ bản, nên mình nói sơ lược, hệ thống thư mục trên Linux bắt đầu bằng thư mục /, nó là thư mục gốc, các thư mục khác là thư mục con của nó. Thông thường khi các bạn mở Terminal lên, thư mục làm việc của các bạn sẽ là /home/user_name.  Các bạn có thể dùng lênh pwd để kiểm tra:

cr0ss@cr0ss-X455LA:~$ pwd

và kết quả sẽ là

/home/cr0ss

cd

Lệnh cd chuyển thư mục làm việc tới một thư mục nào đó bất kỳ tồn tại trên hệ thống. Cú pháp như sau: cd  _directory, trong đó, directory là đường dẫn tới một thư mục. Ví dụ:

cr0ss@cr0ss-X455LA:~$ cd /mnt   #mình chuyển tới thư mục /mnt
cr0ss@cr0ss-X455LA:/mnt$  #bây giờ thư mục làm việc sẽ chuyển đến đây

cr0ss@cr0ss-X455LA:/mnt$ pwd  #in ra thư mục hiện hành
/mnt

các câu sau dấu “#” trong đoạn demo trên là các comment, Shell sẽ bỏ qua các kí tự sau dấu #. Về sau mình sẽ nói rõ trong phần trong phần viết một Shell script.

Khi cd tới một thư mục không tồn tại trên hệ thống thì sẽ báo lỗi, ví dụ:

cr0ss@cr0ss-X455LA:/mnt$ cd /home/cr0ss/adad
bash: cd: /home/cr0ss/adad: No such file or directory

––> Lưu ý phím tắt cho thư mục /home/user_name sẽ là ~/, ví dụ mình sẽ chuyển thư mục làm việc của mình tới thư mục /home/cr0ss/Dowloads bằng cách sử dụng phím tắt:

cr0ss@cr0ss-X455LA:~$ cd ~/Downloads
cr0ss@cr0ss-X455LA:~/Downloads$

––> Ngoài ra còn có thể  chuyển thư mục làm việc ra  thư mục cha của nó bằng cách dùng lệnh cd ..

cr0ss@cr0ss-X455LA:~/Downloads$ cd ..
cr0ss@cr0ss-X455LA:~$

––> Lưu ý trong lệnh cd, kí hiệu “.” chính là thư mục đó tự tham chiếu đến chính nó, ví dụ khi đang ở thư mục làm việc là /home/user_name, bạn dùng lệnh “cd .” chính là chuyển thư mục làm việc đến chính nó, “cd ./directory” là chuyển thư mục làm việc tới thư mục con nằm trong /home/user_name.  Ví dụ:

cr0ss@cr0ss-X455LA:~$ cd .
cr0ss@cr0ss-X455LA:~$ pwd
/home/cr0ss

cr0ss@cr0ss-X455LA:~$ cd ./Downloads
cr0ss@cr0ss-X455LA:~/Downloads$

ls

Lệnh ls có nghĩa là in ra danh sách các file và  thư mục trong thư mục đang làm việc. ls có một số dạng như sau:

  1. ls: in ra danh sách các file và thư mục chứa trong thư mục hiện đang làm việc
  2. ls _directory: in ra danh sách các file trong _directory
  3. ls -l: in ra danh sách các file trong thư mục hiện hành theo dạng đầy đủ
  4. ls -l _directory: in ra danh sách các file trong _directory dưới dạng đầy đủ
  5. ls -la .. : in ra danh sách các file (gồm cả các file ẩn –  file ẩn  hoặc thư mục ẩn trên linux  bắt đầu bằng dấu chấm, bạn có thể xem bằng cách bấm Ctrl+H trong ứng dụng Files) trong thư mục cha đang làm việc với định dạng đầy đủ

Ví dụ:

ls

cr0ss@cr0ss-X455LA:~$ ls
cocos2d-x-3.10   Dropbox   opencv   Qt   Videos
Documents   Music   Pictures   sketchbook   WP_backup_codespdf
Downloads   MyData   Public   Templates

ls ~/Downloads

cr0ss@cr0ss-X455LA:~$ ls ~/Downloads
android-sdk_r24.4.1-linux.tgz   filesystem-structure.png
arduino-1.6.8-linux64.tar.xz   thuat-toan-horner.doc
codeblocks_16.01.tar.gz   vlc-2.2.1.tar.xz
cr0ss@cr0ss-X455LA:~$

ls -l

cr0ss@cr0ss-X455LA:~$ ls -l
total 112
drwxrwxr-x 15 cr0ss cr0ss 4096 Th03 3 18:11 cocos2d-x-3.10
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Documents
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 28 15:42 Downloads
drwx—— 6 cr0ss cr0ss 4096 Th03 28 13:56 Dropbox
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Music
drwx—— 4 cr0ss cr0ss 4096 Th03 3 13:24 MyData
drwxrwxr-x 13 cr0ss cr0ss 4096 Th03 3 16:38 opencv
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 13 20:24 Pictures
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Public
drwxrwxrwx 8 cr0ss cr0ss 4096 Th03 3 16:28 Qt
drwxrwxr-x 3 cr0ss cr0ss 4096 Th03 20 02:41 sketchbook
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Templates
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Videos
-rw——- 1 cr0ss cr0ss 57940 Th03 28 01:53 WP_backup_codespdf

ls -l ~/Downloads

cr0ss@cr0ss-X455LA:~$ ls -l ~/Downloads
total 453040
-rw-rw-r– 1 cr0ss cr0ss 326412652 Th03 11 03:25 android-sdk_r24.4.1-linux.tgz
-rw-rw-r– 1 cr0ss cr0ss 96036772 Th03 19 23:56 arduino-1.6.8-linux64.tar.xz
-rw-rw-r– 1 cr0ss cr0ss 20250097 Th03 10 16:43 codeblocks_16.01.tar.gz
-rw-rw-r– 1 cr0ss cr0ss 68472 Th03 28 15:42 filesystem-structure.png
-rw-rw-r– 1 cr0ss cr0ss 161280 Th03 28 01:04 thuat-toan-horner.doc
-rw-rw-r– 1 cr0ss cr0ss 20940288 Th03 25 21:55 vlc-2.2.1.tar.xz
cr0ss@cr0ss-X455LA:~$

ls -la ..

cr0ss@cr0ss-X455LA:~$ ls -la ..
total 12
drwxr-xr-x 3 root root 4096 Th03 3 12:03 .
drwxr-xr-x 23 root root 4096 Th03 23 14:24 ..
drwxr-xr-x 31 cr0ss cr0ss 4096 Th03 28 13:55 cr0ss
cr0ss@cr0ss-X455LA:~$

––> Lưu ý, các thư mục hay file mà ls in ra có màu khác nhau đối với từng loại.

file

Lệnh file được dùng theo cú pháp như sau: file name_of_file. Nó sẽ in ra xem xét thông tin về kiểu dữ liệu mà file đang chứa. Dưới đây là bảng mô tả các loại file trên Linux

Câu lệnh sau xuất ra màn hình bao nhiêu chữ xin CHAO For i 123 to 456 do writeln xin CHAO

––> Lưu ý trong phần ví dụ in ra của lệnh ls -l, ls -l ~/Downloads có các đoạn như:

drwxrwxr-x 15 cr0ss cr0ss 4096 Th03 3 18:11 cocos2d-x-3.10
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Documents
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 28 15:42 Downloads
drwx—— 6 cr0ss cr0ss 4096 Th03 28 13:56 Dropbox
drwxr-xr-x 2 cr0ss cr0ss 4096 Th03 3 12:15 Music
drwx—— 4 cr0ss cr0ss 4096 Th03 3 13:24 MyData
drwxrwxr-x 13 cr0ss cr0ss 4096 Th03 3 16:38 opencv
-rw——- 1 cr0ss cr0ss 57940 Th03 28 01:53 WP_backup_codespdf

các bạn để ý những chỗ mình underline, phần sau mình sẽ phân tích chi tiết về những kí tự này, sơ lược thì những chữ được underline ở đầu các dòng đó là “permissions” nôm na là quyền truy cập file, còn những số mình gạch dưới đó là kích thước (byte) của thư mục/file đó

Nguồn hình ảnh: sưu tầm

Chào các bạn! Trước khi bắt đầu bài viết, mình xin giới thiệu đôi chút về mục đích bài viết. Thực tế đa số hệ điều hành của các máy tính hiện nay chủ yếu thuộc hai kiểu đó là Microsoft Windows (năm 1985 bởi Microsoft) và kiểu Unix (năm 1960-1970 tại AT&T Bell Labs bởi Dennis Ritche và Ken Thompson), trong đó Linux (1991 bởi Linus Tovald) là một họ các hệ điều hành kiểu Unix được xây dựng từ chung một nhân Linux và các tiện ích đi kèm gọi là các Linux Distribution. Nếu các bạn đã quá quen thuộc Windows thì có vẻ như  Linux hay các hệ điều hành kiểu Unix còn hơi xa lạ và khó sử dụng (nhất là đối với Việt Nam mình 🙂 ). Ở đây mình không so sánh Windows với Linux hoặc Unix, mình viết bài này để giới thiệu cho các bạn mới làm quen và còn lạ lẫm với Unix-Linux để các bạn có thể làm chủ hệ điều hành của mình (dĩ nhiên là một cách tương đối thôi nhé, vì mình cũng không am hiểu tất tần tật về Unix-Linux, mình chỉ giới thiệu những gì mình biết thôi, hihi 🙂 ). Bài viết này và các bài viết sau của mình về Shell chủ yếu đều tham khảo trong cuốn The Linux Command Line của tác giả William E. Shotts, Jr. Nào, giờ thì bắt đầu thôi!

Nếu bạn đã và đang tìm hiều về  Linux hoặc một hệ điều hành Unix nào đó thì chắc hẳn ít nhất một lần các bạn đã nghe tới Shell, vậy Shell là cái gì? 🙂

Như bạn đã biết, hệ điều hành tương tác với người dùng thông qua giao diện đồ họa (GUIs) và giao diện dòng lệnh (CLIs). Thì Shell là một trình thông dịch lệnh tương tác giữa người dùng và hệ điều hành theo giao diện dòng lệnh có trên các hệ điều hành Unix-like như Linux, MacOS,…. Shell tương tự như Command Prompt trên Windows dùng để phục vụ các mục đích giống như các chương trình dùng  giao diện đồ họa. Giờ chúng ta cùng đi vào tìm hiểu chi tiết về Shell nhé!

Các loại Shell:

Hầu hết trên các hệ điều hành Linux đều có sẵn bash (viết tắt của Bourne Again Shell, là một phiên bản nâng cao của shell nguyên thủy sh trên Unix được viết bởi Steve Bourne). Ngoài bash ra còn có các loại shell khác trên các hệ thống Linux như tcsh, ksh, zsh.

Một Terminal là gì?

Dịch sát nghĩa thì nó là một thiết bị đầu cuối dùng để tương tác với người dùng, tuy nhiên ở đây mình chỉ nêu ý nghĩa của nó chứ không cố gắng dịch nghĩa nó ra cho các bạn  😀 Nó là một chương trình gọi là terminal emulator. Khi bạn gọi nó thì nó mở ra 1 cửa sổ và để bạn tương tác với shell. Có nhiều loại terminal emulator tùy vào các Linux distribution như kconsole, gnome-terninal, xterm, eterm, nxterm, rxvt, kvt.

Khởi động Terminal.

Trình quản lý cửa sổ của bạn có thể khởi động terminal theo các cách khác nhau. Ví dụ mình sử dụng Elementary OS, muốn mở Terminal có thể rê chuột lên trên góc trái màn hình click vào Applications, trong ô search gõ Terminal -> Enter. Nếu bạn sử dụng môi trường desktop KDE có thể gọi kconsole hoặc sử dụng Gnome có thể gọi gnome-terminal bằng cách sử dụng các phím tắt,…

Bài đầu tiên kết thúc ở đây. Bài sau mình sẽ hướng dẫn các bạn sử dụng Terminal thao tác với shell. Chào các bạn!