Câu lệnh shell

**Câu lệnh shell** (tiếng Anh: **Shell script**) là một chương trình máy tính được thiết kế để chạy hoặc thực thi bởi Unix shell bởi một trình thông dịch theo dòng lệnh. Các hoạt động thường được thực hiện bởi các câu lệnh shell bao gồm thao tác file, chạy chương trình và in văn bản.

## Capabilities

### Phím tắt
Tập lệnh shell có thể cung cấp một biến thể thuận tiện của lệnh hệ thống trong đó cài đặt môi trường đặc biệt, tùy chọn lệnh hoặc xử lý hậu kỳ tự động áp dụng, nhưng theo cách cho phép tập lệnh mới vẫn hoạt động như một lệnh Unix hoàn toàn bình thường.

Một ví dụ sẽ là tạo một phiên bản ls, lệnh liệt kê các tệp, đặt cho nó một tên lệnh ngắn hơn là l, thường được lưu trong thư mục bin của người dùng là / home / *username* / bin / l và một bộ mặc định của các tùy chọn lệnh được cung cấp trước. 
```bash
#!/bin/sh
LC_COLLATE=C ls -FCas "$@"
```
 Ở đây, dòng đầu tiên (shebang) cho biết trình thông dịch nào sẽ thực thi phần còn lại của tập lệnh và dòng thứ hai tạo một danh sách với các tùy chọn cho các chỉ báo định dạng tệp, cột, tất cả các tệp (không bỏ qua) và kích thước trong các khối.  Các LC_COLLATE = C đặt trật tự đối chiếu mặc định để không gấp trường hợp trên và dưới với nhau, không intermix dotfiles với tên tập tin bình thường như một tác dụng phụ của phớt lờ dấu chấm trong tên (dotfiles thường chỉ được hiển thị nếu một tùy chọn như -a được sử dụng), và "$ @" làm cho bất kỳ tham số nào được cung cấp cho l chuyển qua dưới dạng tham số cho ls, do đó tất cả các tùy chọn thông thường và cú pháp khác được biết đến ls vẫn có thể được sử dụng.

Sau đó, người dùng có thể chỉ cần sử dụng l cho danh sách ngắn được sử dụng phổ biến nhất.

Một ví dụ khác về tập lệnh shell có thể được sử dụng làm phím tắt là in danh sách tất cả các tệp và thư mục trong một thư mục đã cho. 
```bash
#!/bin/sh

clear
ls -al
```
 Trong trường hợp này, tập lệnh shell sẽ bắt đầu với dòng bắt đầu bình thường là #! / Bin / sh.  Theo đó, đoạn script thực thi lệnh xóa để xóa đầu cuối của tất cả văn bản trước khi đi đến dòng tiếp theo. Dòng sau cung cấp chức năng chính của tập lệnh.  Lệnh ls -al liệt kê các tệp và thư mục trong thư mục mà tập lệnh đang được chạy. Các thuộc tính lệnh ls có thể được thay đổi để phản ánh nhu cầu của người dùng.

Lưu ý: Nếu việc triển khai không có lệnh rõ ràng, hãy thử sử dụng lệnh clr thay thế. 
```bash
#!/bin/sh

tail $(find. -iname *.sh)
```


### Batch jobs
Các câu lệnh Shell cho phép một số lệnh sẽ được nhập thủ công tại giao diện dòng lệnh được thực thi tự động và không phải chờ người dùng kích hoạt từng giai đoạn của chuỗi.  Ví dụ, trong một thư mục có ba tệp mã nguồn C, thay vì chạy thủ công bốn lệnh cần thiết để xây dựng chương trình cuối cùng từ chúng, thay vào đó, người ta có thể tạo tập lệnh shell C, ở đây có tên là build và giữ trong thư mục với chúng, mà sẽ tự động biên dịch chúng: 
```bash
#!/bin/csh
echo compiling...
cc -c foo.c
cc -c bar.c
cc -c qux.c
cc -o myprog foo.o bar.o qux.o
echo done.
```
 Câu lệnh sẽ cho phép người dùng lưu tệp đang được chỉnh sửa, tạm dừng trình chỉnh sửa và sau đó chỉ cần chạy ./build để tạo chương trình cập nhật, kiểm tra tệp và sau đó quay lại trình chỉnh sửa. Tuy nhiên, từ những năm 1980 trở đi, các kịch bản thuộc loại này đã được thay thế bằng các tiện ích như sản xuất chuyên dùng để xây dựng chương trình.

### Tổng quát hóa
Các công việc hàng loạt đơn giản không phải là bất thường đối với các tác vụ bị cô lập, nhưng sử dụng các vòng lặp shell, kiểm tra và các biến cung cấp sự linh hoạt hơn nhiều cho người dùng. Tập lệnh Bash (Unix shell) để chuyển đổi hình ảnh JPEG thành hình ảnh PNG, trong đó tên hình ảnh được cung cấp trên dòng lệnh Command có thể thông qua ký tự đại diện, thay vì từng được liệt kê trong tập lệnh, có thể được tạo bằng tệp này, thường được lưu trong tệp này một tập tin như `/home/''username''/bin/jpg2png` 
```bash
#!/bin/bash
for jpg; do                                  # use $jpg in place of each filename given, in turn
    png="${jpg%.jpg}.png"                    # construct the PNG version of the filename by replacing .jpg with .png
    echo converting "$jpg" ...               # output status info to the user running the script
    if convert "$jpg" jpg.to.png ; then      # use the convert program (common in Linux) to create the PNG in a temp file
        mv jpg.to.png "$png"                 # if it worked, rename the temporary PNG image to the correct name
    else                                     # ...otherwise complain and exit from the script
        echo 'jpg2png: error: failed output saved in "jpg.to.png".' >&2
        exit 1
    fi                                       # the end of the "if" test construct
done                                         # the end of the "for" loop
echo all conversions successful              # tell the user the good news
exit 0
```
 Lệnh jpg2png sau đó có thể được chạy trên toàn bộ thư mục chứa đầy hình ảnh JPEG chỉ với / home / *username* / bin / jpg2png * .jpg

### Độ chính xác
Một tính năng chính của các kịch bản shell là việc gọi trình thông dịch của chúng được xử lý như một tính năng hệ điều hành cốt lõi.  Vì vậy, thay vì trình bao của người dùng chỉ có thể thực thi các tập lệnh bằng ngôn ngữ của trình bao đó hoặc tập lệnh chỉ có lệnh phiên dịch của nó được xử lý chính xác nếu nó được chạy từ trình bao (cả hai đều là những hạn chế trong việc xử lý tập lệnh của trình bao Bourne ban đầu), shell script được thiết lập và thực thi bởi chính HĐH.  Một tập lệnh shell hiện đại không chỉ nằm trên cùng một lệnh với các lệnh hệ thống, mà là nhiều lệnh hệ thống thực sự là các tập lệnh shell (hay nói chung hơn là các tập lệnh, vì một số trong số chúng không được giải thích bởi shell, mà thay vào đó là Perl, Python hoặc một số ngôn ngữ khác). Điều này mở rộng để trả về mã thoát như các tiện ích hệ thống khác để biểu thị thành công hay thất bại và cho phép chúng được gọi là các thành phần của các chương trình lớn hơn bất kể các công cụ lớn hơn đó được triển khai như thế nào.

Giống như các lệnh hệ thống tiêu chuẩn, kịch bản shell cổ điển bỏ qua bất kỳ loại phần mở rộng tên tập tin trừ khi dự định sẽ được đọc vào một vỏ chạy thông qua một cơ chế đặc biệt cho mục đích này (chẳng hạn như sh 's ' ', hoặc csh'nguồn s). `'''.'''` 

### Lập trình
Nhiều shell hiện đại cũng cung cấp các tính năng khác nhau thường chỉ được tìm thấy trong các ngôn ngữ lập trình đa năng phức tạp hơn, chẳng hạn như cấu trúc luồng điều khiển, biến, nhận xét, mảng, chương trình con,... Với các loại tính năng có sẵn, có thể viết các ứng dụng hợp lý tinh vi như các tập lệnh shell. Tuy nhiên, chúng vẫn bị hạn chế bởi thực tế là hầu hết các ngôn ngữ shell đều có ít hoặc không hỗ trợ cho các hệ thống gõ dữ liệu, các lớp, luồng, toán phức tạp và các tính năng ngôn ngữ đầy đủ phổ biến khác, và nói chung cũng chậm hơn nhiều so với mã được biên dịch hoặc ngôn ngữ được dịch với tốc độ như một mục tiêu hiệu suất.

Các công cụ Unix tiêu chuẩn sed và awk cung cấp các khả năng bổ sung cho lập trình shell; Perl cũng có thể được nhúng trong các kịch bản shell như các ngôn ngữ kịch bản lệnh khác như Tcl. Perl và Tcl đi kèm với bộ công cụ đồ họa là tốt.

## Ngôn ngữ kịch bản khác
Nhiều ngôn ngữ kịch bản mạnh mẽ đã được giới thiệu cho các tác vụ quá lớn hoặc phức tạp để có thể xử lý thoải mái với các tập lệnh shell thông thường, nhưng với những ưu điểm của tập lệnh là mong muốn và chi phí phát triển của ngôn ngữ lập trình được biên dịch đầy đủ sẽ là bất lợi. Các chi tiết cụ thể của những gì tách biệt các ngôn ngữ kịch bản với các ngôn ngữ lập trình cấp cao là nguồn tranh luận thường xuyên, nhưng nói chung, ngôn ngữ kịch bản là một ngôn ngữ đòi hỏi người phiên dịch.

## Vòng đời
Các tập lệnh Shell thường đóng vai trò là giai đoạn ban đầu trong phát triển phần mềm và thường phải chuyển đổi sau này sang một triển khai cơ bản khác, phổ biến nhất là được chuyển đổi thành Perl, Python hoặc C. Chỉ thị trình thông dịch cho phép chi tiết triển khai được ẩn hoàn toàn bên trong tập lệnh, thay vì được hiển thị dưới dạng phần mở rộng tên tệp và cung cấp khả năng thực hiện lại liền mạch trong các ngôn ngữ khác nhau mà không ảnh hưởng đến người dùng cuối.

Mặc dù các tệp có phần mở rộng tệp ".sh" thường là một tập lệnh shell của một số loại, nhưng hầu hết các tập lệnh shell không có bất kỳ phần mở rộng tên tệp nào.

## Ưu điểm và nhược điểm
Có lẽ ưu điểm lớn nhất của việc viết một kịch bản shell là các lệnh và cú pháp hoàn toàn giống với các lệnh được nhập trực tiếp tại dòng lệnh.  Lập trình viên không phải chuyển sang một cú pháp hoàn toàn khác, như họ sẽ làm nếu tập lệnh được viết bằng một ngôn ngữ khác hoặc nếu một ngôn ngữ được biên dịch được sử dụng.

Thông thường, viết một kịch bản shell nhanh hơn nhiều so với viết mã tương đương trong các ngôn ngữ lập trình khác.  Nhiều ưu điểm bao gồm lựa chọn chương trình hoặc tập tin dễ dàng, bắt đầu nhanh và gỡ lỗi tương tác.  Một tập lệnh shell có thể được sử dụng để cung cấp một liên kết tuần tự và ra quyết định xung quanh các chương trình hiện có và đối với các tập lệnh có kích thước vừa phải, việc không có bước biên dịch là một lợi thế.  Chạy phiên dịch giúp dễ dàng viết mã gỡ lỗi vào tập lệnh và chạy lại để phát hiện và sửa lỗi.  Người dùng không phải là chuyên gia có thể sử dụng tập lệnh để điều chỉnh hành vi của các chương trình và tập lệnh shell cung cấp một số phạm vi giới hạn cho đa xử lý.

Mặt khác, shell scripting dễ bị lỗi tốn kém.  Lỗi đánh máy vô ý như rm -rf * / (thay vì rm -rf * /) dự định là văn hóa dân gian trong cộng đồng Unix; một không gian thừa duy nhất chuyển đổi lệnh từ một lệnh xóa mọi thứ trong thư mục con thành một lệnh xóa mọi thứ và cũng cố xóa mọi thứ trong thư mục gốc.  Các vấn đề tương tự có thể biến đổi cp và mv thành vũ khí nguy hiểm và việc sử dụng sai > chuyển hướng có thể xóa nội dung của tệp.  Điều này trở nên rắc rối hơn bởi thực tế là nhiều lệnh UNIX khác nhau về tên chỉ bằng một chữ cái: cp, cd, dd, df,...

Một nhược điểm đáng kể khác là tốc độ thực thi chậm và cần phải khởi chạy một quy trình mới cho hầu hết mọi lệnh shell được thực thi. Khi công việc của tập lệnh có thể được thực hiện bằng cách thiết lập một đường ống trong đó các lệnh bộ lọc hiệu quả thực hiện hầu hết công việc, sự chậm lại được giảm thiểu, nhưng một tập lệnh phức tạp thường chậm hơn một vài bậc so với chương trình được biên dịch thông thường thực hiện một tác vụ tương đương.

Ngoài ra còn có vấn đề tương thích giữa các nền tảng khác nhau. Larry Wall, người tạo ra Perl, nổi tiếng đã viết rằng "Dễ dàng chuyển một vỏ hơn là một kịch bản shell."

Tương tự, các tập lệnh phức tạp hơn có thể chạy vào các giới hạn của chính ngôn ngữ kịch bản lệnh shell; các giới hạn gây khó khăn cho việc viết mã chất lượng và các phần mở rộng của các shell khác nhau để cải thiện các vấn đề với ngôn ngữ shell gốc có thể làm cho vấn đề trở nên tồi tệ hơn.

Nhiều nhược điểm của việc sử dụng một số ngôn ngữ tập lệnh là do lỗi thiết kế trong cú pháp ngôn ngữ hoặc việc triển khai và không nhất thiết phải áp đặt bằng cách sử dụng dòng lệnh dựa trên văn bản; có một số shell sử dụng các ngôn ngữ lập trình shell khác hoặc thậm chí các ngôn ngữ chính thức như Scsh (sử dụng Scheme).

## Shell scripting trên các hệ điều hành khác
Các phần mềm tương tác như Cygwin, MKS Toolkit, Interix (có sẵn trong Microsoft Windows Services cho UNIX), Hamilton C shell, UWIN (AT & T Unix cho Windows) và các phần mềm khác cho phép các chương trình shell Unix chạy trên các máy chạy Windows NT và những người kế nhiệm của nó, với một số mất chức năng trên nhánh MS-DOS-Windows 95, cũng như các phiên bản MKS Toolkit trước đó cho OS / 2.  Ít nhất ba triển khai DCL cho các hệ điều hành Windows, ngoài XLNT, gói ngôn ngữ kịch bản sử dụng nhiều lần được sử dụng với shell lệnh, Windows Script Host và lập trình CGI cũng có sẵn cho các hệ thống này.  Mac OS X và tiếp theo cũng giống Unix.

Ngoài các công cụ đã nói ở trên, một số chức năng POSIX và OS / 2 có thể được sử dụng với các hệ thống con môi trường tương ứng của loạt hệ điều hành Windows NT cho đến Windows 2000.  Hệ thống con thứ ba, 16 bit thường được gọi là hệ thống con MS-DOS sử dụng Command.com được cung cấp cùng với các hệ điều hành này để chạy các tệp bó MS-DOS đã nói ở trên.

Bảng điều khiển thay thế 4NT, 4DOS, 4OS2, FreeDOS, NDOS của Peter Norton và GUI Take Command bổ sung chức năng cho các tệp bó cmd.exe, MS-DOS / Windows 95 kiểu Windows NT (chạy bởi Command.com), OS / Các cmd.exe và 4NT tương ứng tương tự như các shell mà chúng tăng cường và được tích hợp nhiều hơn với Windows Script Host, đi kèm với ba công cụ được cài đặt sẵn, VBScript, JScript và VBA và nhiều công cụ của bên thứ ba có thể được thêm vào, với Rexx, Perl, Python, Ruby và Tcl có các hàm được xác định trước trong 4NT và các chương trình liên quan.  PC DOS khá giống với MS-DOS, trong khi DR DOS thì khác.  Các phiên bản trước của Windows NT có thể chạy các phiên bản 4OS2 hiện đại của hệ thống con OS / 2.

Ngôn ngữ kịch bản, theo định nghĩa, có thể được mở rộng; ví dụ, hệ thống loại MS-DOS / Windows 95/98 và Windows NT cho phép các chương trình shell / batch gọi các công cụ như KixTart, QBasic, các triển khai BASIC, Rexx, Perl và Python, Windows Script Host và các công cụ được cài đặt của nó. Trên Unix và các hệ thống POSIX -compliant khác, awk và sed được sử dụng để mở rộng khả năng xử lý chuỗi và số của các tập lệnh shell. Tcl, Perl, Rexx và Python có các bộ công cụ đồ họa và có thể được sử dụng để mã hóa các chức năng và quy trình cho các tập lệnh shell gây ra tắc nghẽn tốc độ (C, Fortran, ngôn ngữ lắp ráp & c vẫn nhanh hơn nhiều) và để thêm chức năng không có trong trình bao ngôn ngữ như ổ cắm và các chức năng kết nối khác, xử lý văn bản nặng, làm việc với các số nếu tập lệnh gọi không có các khả năng đó, tự viết và tự sửa đổi mã, các kỹ thuật như đệ quy, truy cập bộ nhớ trực tiếp, các loại sắp xếp khác nhau và nhiều hơn, đó là khó khăn hoặc không thể trong kịch bản chính, và như vậy. Visual Basic cho Ứng dụng và VBScript có thể được sử dụng để kiểm soát và giao tiếp với những thứ như bảng tính, cơ sở dữ liệu, chương trình có thể viết được của tất cả các loại, phần mềm viễn thông, công cụ phát triển, công cụ đồ họa và phần mềm khác có thể được truy cập thông qua Mô hình Đối tượng Thành phần.

## Xem thêm

* Glue code
* Chỉ thị phiên dịch
* Biểu tượng Shebang (#!)
* Unix shell
* Windows PowerShell
* Máy chủ Windows Script

## Tham khảo


## Liên kết ngoài

* ''Giới thiệu về lập trình Shell'' của Greg Goebel 
* ''Hướng dẫn viết kịch bản shell UNIX / Linux'' của Steve Parker 
* ''Shell Scripting Primer'' (Apple) 
* ''Những điều cần chú ý khi viết kịch bản shell di động'' của Peter Seebach 
* Sách kịch bản Unix Shell miễn phí 
* Người mới bắt đầu / BashScripting, Ubuntu Linux