Ngôn ngữ kịch bản (tiếng Anh: scripting language hay script language) là ngôn ngữ lập trình được thiết kế để tự động hóa các tác vụ trong môi trường thời gian thực, cho phép thực hiện từng tác vụ qua người điều hành. Thông thường, ngôn ngữ kịch bản được diễn giải thay vì biên dịch.
Nguyên thủy, ngôn ngữ kịch bản chủ yếu thực hiện các tác vụ cơ bản hoặc gọi API, cho phép kết hợp chúng thành các chương trình phức tạp hơn. Các môi trường có thể được tự động hóa qua tập lệnh bao gồm phần mềm, trang web, shell hệ điều hành, hệ thống nhúng và cả trò chơi. Ngôn ngữ kịch bản có thể coi như ngôn ngữ chuyên dụng cho một môi trường, còn được gọi là ngôn ngữ mở rộng khi áp dụng trong ứng dụng. Đôi khi, chúng được xem như ngôn ngữ lập trình cấp cao vì hoạt động ở mức độ trừu tượng.
Thuật ngữ 'ngôn ngữ kịch bản' còn được dùng để chỉ các ngôn ngữ lập trình cấp cao đa dụng như Perl, PowerShell, Python và Tcl. Từ 'tập lệnh' thường chỉ các chương trình ngắn (vài nghìn dòng mã) viết bằng những ngôn ngữ này hoặc các ngôn ngữ chuyên dụng như sed và AWK. Một số ngôn ngữ này ban đầu phát triển cho một môi trường cụ thể rồi sau đó trở thành ngôn ngữ đa dụng. Ngược lại, nhiều ngôn ngữ đa dụng có phương ngữ được sử dụng làm ngôn ngữ kịch bản. Bài viết này sẽ tập trung vào các ngôn ngữ kịch bản trong ngữ cảnh hẹp cho môi trường cụ thể.
Phổ biến của các ngôn ngữ kịch bản trải dài từ những ngôn ngữ nhỏ, chuyên dụng đến các ngôn ngữ lập trình đa dụng được sử dụng để viết kịch bản. Ví dụ điển hình cho các ngôn ngữ kịch bản trong môi trường cụ thể bao gồm: Bash cho các hệ điều hành Unix; ECMAScript (JavaScript) cho trình duyệt; Visual Basic cho ứng dụng Microsoft Office. Lua là một ngôn ngữ thường được dùng như một ngôn ngữ mở rộng. Python cũng là ngôn ngữ đa dụng, thường được dùng như một ngôn ngữ mở rộng, trong khi ECMAScript chủ yếu được dùng cho trình duyệt nhưng cũng phục vụ cho mục đích chung. Các phương ngữ Lisp của Emacs và phương ngữ Visual Basic cho ứng dụng là ví dụ về phương ngữ ngôn ngữ kịch bản trong các ngôn ngữ đa dụng. Một số trò chơi, như Second Life và chuỗi mô phỏng Railroad của Trainz, đã mở rộng chức năng thông qua các phần mở rộng kịch bản (Linden Scripting Language và TrainzScript). Trong những trò chơi khác như Wesnoth, nhiều kịch bản do người dùng viết tạo nên sự đa dạng cho trò chơi.
Đặc điểm
Các ngôn ngữ kịch bản thường được thiết kế để dễ học và viết, thường dưới dạng các tệp mã nguồn ngắn hoặc thông qua tương tác trong môi trường REPL. Điều này thường đòi hỏi cú pháp và ngữ nghĩa đơn giản; thường thì một 'tập lệnh' (mã ngôn ngữ kịch bản) được thực thi liền mạch từ đầu đến cuối mà không có điểm nhập rõ ràng.
Ví dụ, mô tả Java như một ngôn ngữ kịch bản không phổ biến vì cú pháp phức tạp và quy tắc về các lớp chỉ có thể thực thi qua các ứng dụng máy chủ hoặc trình khởi chạy, không thể thực thi trực tiếp từ mã nguồn.
Một ngôn ngữ kịch bản thường được diễn giải từ mã nguồn hoặc mã byte. Ngược lại, môi trường phần mềm nơi các tập lệnh được viết thường sử dụng ngôn ngữ biên dịch và được phân phối dưới dạng mã máy.
Các ngôn ngữ kịch bản có thể được thiết kế để người dùng cuối có thể tham gia vào phát triển chương trình, cho phép họ viết các phần của chương trình bằng ngôn ngữ kịch bản. Thường thì, ngôn ngữ kịch bản sử dụng sự trừu tượng hóa để ẩn thông tin, giúp người dùng quản lý các loại biến, lưu trữ dữ liệu và quản lý bộ nhớ.
Các tập lệnh thường được tạo hoặc chỉnh sửa bởi người dùng thực hiện chúng, nhưng cũng thường được phân phối, đặc biệt là trong các trò chơi được viết bằng ngôn ngữ kịch bản.
Lịch sử
Những máy tính lớn đầu tiên (vào thập niên 1950) không có khả năng tương tác mà chủ yếu sử dụng xử lý hàng loạt. Ngôn ngữ kiểm soát công việc IBM (JCL) là nguyên mẫu cho việc kiểm soát xử lý hàng loạt.
Các shell tương tác đầu tiên được phát triển vào những năm 1960, cho phép hoạt động từ xa trên các hệ thống chia sẻ. Calvin Mooers được ghi nhận đã phát minh ra sự thay thế lệnh trong ngôn ngữ TRAC, cho phép nhúng các lệnh vào các tập lệnh. Multics đã gọi những chức năng này. Louis Pouzin đã viết một bộ xử lý cho các tập lệnh gọi là RUNCOM cho CTSS vào khoảng năm 1964. Stuart Madnick tại MIT đã phát triển một ngôn ngữ kịch bản cho CP/CMS của IBM vào năm 1966, ban đầu gọi là EXEC. Multics đã tích hợp một nhánh của CTSS RUNCOM, còn được gọi là RUNCOM. EXEC cuối cùng đã được thay thế bởi EXEC 2 và REXX.
Các ngôn ngữ như Tcl và Lua được thiết kế như các ngôn ngữ kịch bản có mục đích chung, có thể nhúng vào bất kỳ ứng dụng nào. Ngôn ngữ khác như Visual Basic for Applications (VBA) cung cấp sự tích hợp mạnh mẽ với hệ thống tự động hóa cơ bản. Việc nhúng các ngôn ngữ script đa mục đích như vậy thay vì phát triển ngôn ngữ mới cho mỗi ứng dụng giúp nhà phát triển tiết kiệm công sức khi không phải viết trình biên dịch từ đầu và cho phép người dùng áp dụng kỹ năng đã học từ những nơi khác.
Nhiều phần mềm hiện nay tích hợp các ngôn ngữ kịch bản khác nhau. Các trình duyệt web hiện đại thường cung cấp ngôn ngữ để phát triển các phần mở rộng cho chính chúng, cũng như các ngôn ngữ nhúng tiêu chuẩn để điều khiển trình duyệt, như JavaScript (một phương ngữ của ECMAScript) hoặc XUL.
Các loại
Viết kịch bản thường được so sánh với lập trình hệ thống, như trong phân đôi của Ousterhout hoặc khái niệm 'lập trình lớn và lập trình nhỏ'. Theo cách này, script được xem là mã keo, dùng để kết nối các thành phần phần mềm, và một ngôn ngữ dành riêng cho mục đích này được gọi là ngôn ngữ keo. Pipelines và shell scripting là những ví dụ điển hình cho ngôn ngữ keo, và Perl ban đầu được phát triển để thực hiện vai trò tương tự. Phát triển web có thể được xem là việc sử dụng ngôn ngữ keo, kết nối giữa cơ sở dữ liệu và máy chủ web. Tuy nhiên, nếu một lượng lớn logic được viết bằng script, thì nó thường được xem như một thành phần phần mềm độc lập hơn là 'keo'.
Ngôn ngữ keo đặc biệt hữu ích cho việc viết và duy trì:
- các lệnh tùy chỉnh cho một shell lệnh;
- các chương trình nhỏ hơn, hiệu quả hơn khi thực hiện trong một ngôn ngữ biên dịch;
- Các chương trình 'trình bao bọc' cho các tệp thực thi, như các tệp bó di chuyển hoặc thao tác các tệp và thực hiện các tác vụ khác với hệ điều hành trước hoặc sau khi chạy một ứng dụng như trình xử lý văn bản, bảng tính, cơ sở dữ liệu, trình biên dịch,...;
- các kịch bản có thể điều chỉnh;
- Phát triển nhanh chóng ứng dụng cuối cùng sẽ được thực hiện bằng ngôn ngữ khác, thường là ngôn ngữ đã biên dịch.
Ví dụ về các ngôn ngữ keo:
- AppleScript
- ColdFusion
- DCL
- Lisp có thể nhúng
- ecl
- Erlang
- JCL
- CoffeeScript
- Julia
- JScript và JavaScript
- Lua
- m4
- Pascal hiện đại
- Perl (5 và 6)
- PHP
- PowerShell
- Pure
- Python
- Rebol
- Red
- Rexx
- Ruby
- Scheme
- Tcl
- Các kịch bản Unix Shell (ksh, csh, , sh và các loại khác)
- VBScript
- Work Flow Language
- XSLT
Ngôn ngữ macro có khả năng tương tác với hệ điều hành hoặc các thành phần ứng dụng có thể hoạt động như ngôn ngữ keo. Chúng bao gồm Visual Basic for Applications, WordBasic, LotusScript, CorelScript, Hummingbird Basic, QuickScript, SaxBasic và WinWrap Basic. Các công cụ khác như AWK cũng được xem là ngôn ngữ keo, cùng với bất kỳ ngôn ngữ nào được triển khai bởi công cụ Windows Script Host (VBScript, JScript và VBA mặc định trong Windows và các công cụ bên thứ ba như Rexx, Perl, Tcl, Python, XSLT, Ruby, Pascal hiện đại, Delphi và C). Hầu hết các ứng dụng đều có thể truy cập và sử dụng các thành phần hệ điều hành thông qua các mô hình đối tượng hoặc các chức năng của chính chúng.
Các thiết bị khác như máy tính lập trình cũng có thể hỗ trợ ngôn ngữ keo; hệ điều hành của các thiết bị PDA như Windows CE có thể cung cấp các công cụ macro của bên thứ ba hoặc tích hợp các ứng dụng, bên cạnh việc triển khai các ngôn ngữ keo thông thường như Windows NT, MS-DOS và một số shell Unix, Rexx, Modern Pascal, PHP và Perl. Tùy thuộc vào phiên bản hệ điều hành, WSH và các công cụ script mặc định (VBScript và JScript) có sẵn.
Máy tính lập trình có thể được lập trình bằng ngôn ngữ keo theo ba cách khác nhau. Ví dụ, Texas TI-92, theo mặc định có thể lập trình bằng ngôn ngữ tập lệnh. Việc tích hợp ngôn ngữ kịch bản và keo dán Lua trong dòng máy tính TI-NSpire có thể được xem như là sự kế thừa cho điều này. Các ngôn ngữ lập trình cấp cao chính trên hầu hết các máy tính đồ họa (thường là các biến thể cơ bản, đôi khi là các dẫn xuất từ Lisp và các dẫn xuất khác của C) thường có khả năng kết dính các chức năng của máy tính với nhau như đồ thị, danh sách, ma trận,... Các phiên bản cơ bản được triển khai từ bên thứ ba có thể gần hơn với các biến thể được liệt kê trong bài viết này về ngôn ngữ keo và cố gắng triển khai Perl, Rexx hoặc các hệ điều hành khác nhau trên máy tính đồ họa TI và HP cũng được đề cập. Trình biên dịch C dựa trên PC cho một số máy TI và HP có thể được sử dụng cùng với các công cụ chuyển đổi giữa C và Perl, Rexx, AWK, cũng như giữa các tập lệnh shell sang Perl, Modern Pascal, VBScript và ngược lại để viết chương trình bằng ngôn ngữ keo nhằm thực hiện cuối cùng (dưới dạng chương trình đã biên dịch) trên máy tính.
Ngôn ngữ và điều khiển quy trình công việc
Nhiều ngôn ngữ kịch bản đã phát triển từ việc tự động hóa quản lý công việc, nhằm khởi động và điều khiển hành vi của các chương trình hệ thống. Có thể coi các shell là hậu duệ của JCL của IBM, hay Ngôn ngữ điều khiển công việc, được thiết kế cho mục đích này. Nhiều trình thông dịch trong số này cũng hoạt động như các trình thông dịch dòng lệnh như shell Unix hoặc COMMAND.COM của MS-DOS. Một số khác, như AppleScript, cho phép người dùng sử dụng lệnh gần giống tiếng Anh để viết các tập lệnh.
Lập trình kịch bản GUI
Với sự phát triển của giao diện người dùng đồ họa, một loại ngôn ngữ kịch bản đặc biệt đã xuất hiện để điều khiển máy tính. Các ngôn ngữ này tương tác với cửa sổ đồ họa, menu, nút, tương tự như hành động của người dùng. Chúng thực hiện điều này bằng cách mô phỏng các hành động của người dùng, thường được sử dụng để tự động hóa thao tác của người dùng. Những ngôn ngữ này cũng được gọi là 'macro' khi điều khiển thông qua việc mô phỏng nhấn phím hoặc nhấp chuột, cũng như chạm hoặc nhấn vào màn hình cảm ứng.
Về lý thuyết, các ngôn ngữ này có thể kiểm soát bất kỳ ứng dụng GUI nào; tuy nhiên, trong thực tế, việc sử dụng của chúng thường bị hạn chế do cần có sự hỗ trợ từ ứng dụng và hệ điều hành. Một số ngoại lệ tồn tại cho giới hạn này. Một số ngôn ngữ kịch bản GUI nhận dạng các đối tượng đồ họa từ pixel hiển thị trên màn hình. Những ngôn ngữ kịch bản GUI này không phụ thuộc vào sự hỗ trợ từ hệ điều hành hoặc ứng dụng.
Ngôn ngữ chuyên dụng cho ứng dụng
Ngôn ngữ chuyên dụng cho ứng dụng có thể được phân loại thành nhiều nhóm khác nhau, như ngôn ngữ ứng dụng độc lập (có thể thực thi) hoặc ngôn ngữ nội bộ (như PostScript, XML, GScript, được Adobe, Microsoft và Google triển khai). Những ngôn ngữ này được thiết kế để đáp ứng nhu cầu của người dùng. Tương tự, nhiều hệ thống trò chơi máy tính sử dụng ngôn ngữ kịch bản tùy chỉnh để điều khiển hành động của các nhân vật không phải người chơi. Các ngôn ngữ này thường được thiết kế cho một ứng dụng cụ thể; mặc dù có thể tương tự ngôn ngữ đa mục đích (như QuakeC, dựa trên C), nhưng chúng có tính năng đặc trưng riêng. Emacs Lisp, mặc dù là một biến thể của Lisp, có nhiều tính năng đặc biệt giúp mở rộng khả năng chỉnh sửa của Emacs. Ngôn ngữ kịch bản chuyên dụng cho ứng dụng có thể coi như một ngôn ngữ lập trình chuyên biệt cho một miền ứng dụng cụ thể.
Mở rộng / ngôn ngữ nhúng
Một số ngôn ngữ được thiết kế để thay thế ngôn ngữ kịch bản chuyên dụng cho ứng dụng, cho phép nhúng trong các chương trình. Lập trình viên sử dụng ngôn ngữ C hoặc các hệ thống khác có thể tích hợp 'hook' để ngôn ngữ kịch bản điều khiển ứng dụng. Những ngôn ngữ này về cơ bản tương đương với ngôn ngữ mở rộng dành riêng cho ứng dụng, nhưng cho phép người dùng chuyển kỹ năng từ ứng dụng này sang ứng dụng khác khi sử dụng ngôn ngữ 'chung'. Một cách tiếp cận khác là cung cấp thư viện (thường là thư viện C) để ngôn ngữ có mục đích chung kiểm soát ứng dụng mà không cần thay đổi ngôn ngữ cho miền cụ thể.
JavaScript bắt đầu như một ngôn ngữ kịch bản trong các trình duyệt web và vẫn chủ yếu như vậy; tuy nhiên, sự chuẩn hóa dưới dạng ECMAScript đã biến nó thành một ngôn ngữ nhúng có mục đích chung phổ biến. Cụ thể, SpiderMonkey của Mozilla được nhúng trong nhiều môi trường như Yahoo! Công cụ. Các ứng dụng khác nhúng các triển khai ECMAScript bao gồm sản phẩm của Adobe như Adobe Flash (ActionScript) và Adobe Acrobat (để tạo file PDF).
Tcl được phát triển như một ngôn ngữ mở rộng nhưng hiện nay được sử dụng phổ biến như một ngôn ngữ đa mục đích tương tự như Python, Perl và Ruby. Ngược lại, Rexx ban đầu được thiết kế như một ngôn ngữ điều khiển công việc, nhưng giờ đây cũng được áp dụng rộng rãi như một ngôn ngữ mở rộng và đa mục đích. Perl là một ngôn ngữ đa mục đích, nhưng có phương ngữ Oraperl (1990) bao gồm nhị phân Perl 4 tích hợp Giao diện cuộc gọi của Oracle. Tuy nhiên, phương ngữ này đã được thay thế bằng một thư viện (mô-đun Perl) có tên DBD::Oracle.
Các ứng dụng phức tạp và theo nhiệm vụ khác có thể tích hợp và hiển thị ngôn ngữ lập trình nhúng để giúp người dùng kiểm soát tốt hơn và cung cấp nhiều chức năng hơn so với giao diện người dùng hiện có, bất kể mức độ tinh vi của chúng. Ví dụ, công cụ tác giả Autodesk Maya 3D sử dụng ngôn ngữ kịch bản MEL, trong khi Blender sử dụng Python cho mục đích này.
Một số loại ứng dụng khác cần tính năng nhanh hơn hoặc chu trình điều chỉnh và chạy (như công cụ trò chơi) cũng áp dụng ngôn ngữ nhúng. Trong quá trình phát triển, điều này cho phép họ tạo ra các tính năng mẫu nhanh chóng và điều chỉnh một cách linh hoạt mà không yêu cầu người dùng có kiến thức sâu về hoạt động bên trong của ứng dụng hay phải xây dựng lại sau mỗi lần điều chỉnh (điều này có thể mất nhiều thời gian). Các ngôn ngữ kịch bản được sử dụng cho mục đích này bao gồm Lua, Python phổ biến, cũng như những ngôn ngữ ít được biết đến như AngelScript và Squirrel.
