LẬP TRÌNH TRONG MÔI TRƯỜNGSHELL 2.1 Mục tiêu Bài thực hành này giúp sinh viên: Làm quen và tìm hiểu cách sử dụng ngôn ngữ shell để lập trình Thực hành lập trình một số cầu trúc điều kh
LẬP TRÌNH TRONG MÔI TRƯỜNG SHELL
Mục tiêu
Bài thực hành này giúp sinh viên:
Làm quen và tìm hiểu cách sử dụng ngôn ngữ shell để lập trình
Thực hành lập trình một số cầu trúc điều khiển cơ bản của shell
Viết được một số chương trình đơn giản bằng ngôn ngữ shell
Nội dung thực hành
Thực hành các lệnh tương tác với hệ điều hành Linux thông qua shell
Tìm hiểu và thực hành ngôn ngữ shell
Sinh viên chuẩn bị
Đọc phần hướng dẫn thực hành trước ở nhà
Viết lại các đoạn code trong phần 2.4 theo hướng dẫn
Hướng dẫn thực hành
2.4.1 Sử dụng shell như ngôn ngữ lập trình
Shell có thể được xem như một ngôn ngữ lập trình cho việc viết các chương trình điều khiển hệ thống Có hai cách để làm điều này: cách thứ nhất là gõ các lệnh ngay trên dòng lệnh, đơn giản nhất để thực thi nhanh các tác vụ; cách thứ hai là ghép các lệnh lại thành một tệp script và chạy chúng một lần, tương đương với cách DOS gọi tệp *.bat Phương pháp thứ hai mang lại hiệu quả và tận dụng tối đa khả năng tự động hóa của shell.
2.4.1.1 Điều khiển shell từ dòng lệnh
Chúng ta hãy bắt đầu với ví dụ đơn giản: nếu trên đĩa cứng có nhiều tệp nguồn có phần mở rộng c và bạn muốn tìm kiếm tất cả các tệp chứa chuỗi main() để hiển thị nội dung của chúng, thay vì phải dùng grep để xác định từng file rồi sau đó dùng lệnh more để xem từng file, bạn có thể triển khai một chuỗi lệnh shell tự động theo một pipeline, giúp quét, lọc và hiển thị nội dung của các tệp phù hợp một cách thuận tiện và nhanh chóng.
$ for file in * do if grep -l 'main( ) ' $file then more $fỉle fi done
Khi người dùng gõ một lệnh chưa hoàn chỉnh từ dấu nhắc của shell, shell sẽ hiển thị dấu nhắc ở dạng > và chờ nhập đầy đủ các câu lệnh trước khi thực thi; shell tự động nhận diện đúng lúc bắt đầu và kết thúc của một lệnh, ví dụ với cấu trúc for do done, lệnh sẽ kết thúc bằng từ khóa done Khi gõ xong từ done, shell sẽ bắt đầu thực thi toàn bộ nội dung đã nhập từ phần bắt đầu bằng for; trong ngữ cảnh này, file được xem là một biến của shell, còn ký tự * đóng vai trò là wildcard đại diện cho các tên tệp trong thư mục hiện hành.
Bất tiện của việc điều khiển ngôn ngữ shell từ dòng lệnh là khó lấy lại khối lệnh trước đó để sửa đổi và thực thi lại Việc này khiến quá trình chỉnh sửa và thử nghiệm lệnh trở nên mất thời gian và dễ phạm sai lầm Khi nhấn phím lên/xuống, shell có thể trả lại khối lệnh trước đó, cho phép bạn xem lại, chỉnh sửa nhanh và chạy lại mà không phải gõ lại từ đầu, từ đó tối ưu hóa quy trình làm việc trên dòng lệnh và quản lý lịch sử lệnh một cách hiệu quả.
$ for file in * ; do ; if grep -1 'main( )’
Trong shell Linux, bạn có thể thực thi nhiều lệnh trên cùng một dòng bằng cách phân tách các lệnh bằng dấu chấm phẩy (;) Đây là cách phổ biến mà hầu hết các shell hỗ trợ để ghép nối và chạy liên tiếp các lệnh trên một dòng mà không cần nhập từng lệnh riêng biệt Các lệnh sẽ được thực thi theo trình tự từ trái sang phải, mỗi lệnh kết thúc bằng dấu chấm phẩy hoặc bằng kết thúc dòng, và kết quả của lệnh này sẽ là nền tảng cho lệnh tiếp theo trong chuỗi Ví dụ đơn giản: ls; pwd; echo 'hoàn tất'.
Để tạo thư mục và vào đúng thư mục đó, ta dùng hai lệnh mkdir và cd như: mkdir myfolder; cd myfolder Bạn có thể gõ Enter để thực thi hai lệnh trên một dòng, nhưng chỉnh sửa các khối lệnh như vậy dễ gây lỗi và không linh hoạt; chúng chỉ thực sự tiện khi kết hợp vài ba lệnh Để dễ bảo trì, có thể đưa các lệnh vào một tập tin và yêu cầu shell đọc nội dung tập tin để thực thi, và những tập tin như vậy được gọi là tập tin kịch bản (shell script).
2.4.1.2 Điều khiển shell bằng tập tin kịch bản (script file)
Đầu tiên bạn có thể tạo và chỉnh sửa tập tin first.sh bằng cách dùng lệnh cat > first.sh trên dòng lệnh hoặc mở các trình soạn thảo như vi, emacs (hoặc mc) và gedit để soạn nội dung cho tập tin first.sh, sau đó lưu lại nội dung đã soạn và đảm bảo tập tin này có quyền thực thi nếu bạn muốn chạy nó.
# Script này sẽ tìm trong thư mục hiện hành các chuỗi mang nội dung
# main( ), nội dung của fìle sẽ được hiển thị ra màn hình nếu tìm thấy. for file in * do if grep -l 'main( ) ' $file then more $fỉle fi done exit 0
Trong ngôn ngữ shell, các chú thích (comment) bắt đầu bằng ký tự #; tuy nhiên, trường hợp đặc biệt là dòng #!/bin/sh thực ra không phải chú thích mà là shebang, chỉ thị cho hệ điều hành biết trình thông dịch nào sẽ thực thi tập tin script (ở đây là /bin/sh) và shell sẽ chịu trách nhiệm giải thích và thực thi các lệnh nằm ở tập tin script được tạo ra.
Bạn có thể chỉ định #!/bin/bash làm shell thông dịch cho script thay cho sh, vì trên Linux sh và bash về cơ bản tương đồng về cú pháp; tuy vậy trên các hệ Unix vẫn coi sh là shell chuẩn, nên việc sử dụng sh là thói quen tốt cho lập trình viên Khi làm quen với UNIX, bạn sẽ cảm thấy quen thuộc và tự tin hơn với shell này Để an toàn cho môi trường làm việc, hãy chạy script trong một shell phụ (ví dụ gọi sh), để mọi thay đổi về biến hay thiết lập môi trường do script gây ra không ảnh hưởng tới môi trường làm việc chính.
Chỉ thị #! (shebang) được dùng để chỉ định chương trình sẽ chạy trước khi nội dung script được thực thi, giúp hệ điều hành biết interpreter để xử lý mã, còn lệnh exit đảm bảo script trả về mã trạng thái khi kết thúc và hầu hết các chương trình nên làm như vậy dù trong tương tác trực tiếp từ dòng lệnh mã lỗi ít khi được dùng đến Việc nhận biết mã trả về (return code) của một script sau khi thực thi rất hữu ích khi bạn gọi script từ một script khác; với ví dụ ở trên, exit sẽ trả về 0 để cho biết script đã thực thi thành công và thoát khỏi shell gọi nó Mặc dù có thể lưu tập tin với đuôi sh, UNIX và Linux không bắt buộc dùng đuôi này để nhận diện, vì tên tập tin script có thể tùy ý, tuy nhiên đuôi sh vẫn giúp người dùng nhận diện nhanh chóng một tập tin là script của shell.
Chúng ta vừa tạo ra tập tin script first.sh và nó có thể được gọi thực thi theo hai cách khác nhau: cách đơn giản nhất là gọi trình shell với tên tập tin script làm đối số, ví dụ: sh first.sh; cách thứ hai là cấp quyền thực thi cho tập tin và chạy nó trực tiếp như một chương trình, ví dụ: /first.sh Việc nắm vững hai cách gọi này giúp thao tác với script nhanh chóng hơn và dễ tích hợp vào các chuỗi công việc tự động.
Việc gọi first.sh từ dòng lệnh là thói quen phổ biến, nhưng sẽ quen thuộc hơn nếu bạn có thể chạy nó như một lệnh Linux thông thường ngay từ lần đầu tiên Để làm được điều này, bạn cần cấp quyền thực thi (x) cho tập tin script bằng lệnh chmod, ví dụ: chmod +x first.sh, qua đó cho phép hệ thống thực thi file và chạy nội dung bên trong một cách trơn tru.
Sau đó có thể triệu gọi script theo cách thứ hai tiện lợi hơn:
Đôi khi lệnh bạn gõ không thực thi được và trả về thông báo lỗi 'command not found' (không tìm thấy lệnh) Nguyên nhân chủ yếu là biến môi trường PATH thường không chứa đường dẫn tới thư mục hiện hành Để khắc phục, ta có thể thêm đường dẫn thư mục hiện hành vào PATH, từ đó hệ điều hành có thể tìm thấy và thực thi lệnh một cách nhanh chóng và nhất quán.
Nếu muốn Linux tự động nhớ thư mục hiện hành mỗi khi đăng nhập bạn có thể thêm lệnh PATH=$PATH : vào cuối tệp
.bash_profile là tập tin được gọi khi người dùng đăng nhập vào hệ thống, tương tự như autoexec.bat trong DOS Tuy nhiên cách ngắn gọn và phổ biến nhất là ghi rõ thư mục hiện hành bằng ký hiệu / trước lệnh khi bạn chạy một chương trình từ thư mục đó Ví dụ: để thực thi script trong thư mục làm việc, hãy nhập /script.sh.
Đối với tài khoản root, không nên thêm thư mục hiện hành (.) vào biến PATH để tìm kiếm chương trình, vì điều này làm suy yếu bảo mật Khi PATH cho phép truy cập thư mục hiện hành, quản trị hệ với quyền root có thể vô tình hoặc cố ý chạy một chương trình từ thư mục đó thay vì các chương trình chuẩn ở /bin, gây ra lỗ hổng bảo mật Do đó, thói quen an toàn là không để PATH chứa ký tự '.' truy cập thư mục hiện hành Thay vào đó, hãy gọi tập tin bằng /tên_tập_tin để ám chỉ truy cập từ thư mục hiện hành, đảm bảo chỉ các chương trình đáng tin cậy mới được thực thi và tăng cường bảo mật cho hệ thống Linux.
Bài tập ôn tập
1 Chạy tất cả các đoạn lệnh ví dụ ở phần 2.4 Chụp hình kết quả chạy các file script và lưu vào báo cáo.
2 Viết chương trình cho phép nhập vào tên và mssv Kiểm tra nếu mssv đó không trùng với mình thì bắt nhập lại In ra màn hình kết quả.
3 Viết chương trình cho phép nhập vào một số n Kiểm tra nếu n < 10 thì bắt nhập lại Tính tổng các số từ 1 đến n In kết quả ra màn hình.
4 Viết trình cho phép nhập vào một chuỗi Kiểm tra chuỗi đó có tồn tại trong một file text (ví dụ test.txt) cùng thư mục hay không.