Lợi thế của shell script so với các ngôn ngữ lập trình được giải thích là gì? [đóng cửa]


15

(Tôi không chắc đây có phải là một câu hỏi thích hợp ở đây không)

Shell script, giống như những gì được viết trong bash, có thể làm nhiều thứ. Họ có thể gọi các chương trình Unix, dẫn đầu ra của chúng, chuyển hướng I / O từ / đến tệp, kiểm soát luồng, kiểm tra xem một tệp có tồn tại không, v.v.

Nhưng một ngôn ngữ lập trình hiện đại, ví dụ, pythonruby, cũng có thể làm những điều này. Và, họ (tôi nghĩ) dễ đọc và dễ bảo trì hơn.

bashthích áp dụng rộng rãi. Nhưng nhiều bản phân phối đã cài đặt pythontrình thông dịch, quá.

Vì vậy, lợi thế của shell một kịch bản là gì? Nếu tôi có thể viết python, rubyhoặc perl, nó có đáng để học bashkhông?


3
Nếu bạn làm việc nhiều với các hệ thống Unix, bạn nên học bash cũng như các shell Unix phổ biến khác.
Bernard

Câu trả lời:


30

Shell có các tính năng chuyên dụng để làm việc với các tệp và nhận dữ liệu từ chương trình này sang chương trình khác (giả sử rằng dữ liệu là văn bản). Đối với các tác vụ đó, tập lệnh shell có thể ít cồng kềnh hơn so với ngôn ngữ tập lệnh như Python.

Shell scripting cũng có lợi thế là các lệnh bạn sử dụng về cơ bản giống với các lệnh bạn sử dụng từ dòng lệnh - vì vậy nếu bạn có thể làm gì đó trong shell, bạn sẽ đi được hơn một nửa so với kịch bản hoạt động tương tự.

Ví dụ ở đây là một tập lệnh bash di chuyển tất cả các tệp PNG từ thư mục hiện tại sang một thư mục được chỉ định.

#!/usr/bin/sh
mv *.png $1

Đây là phiên bản Python.

#!/usr/bin/python
import sys, shutil, glob
for filename in glob.iglob("./*.png"):
    shutil.move(filename, sys.argv[1])

Bạn sẽ nhận thấy:

  • Tập lệnh bash dài bằng một phần ba so với Python nếu bạn đếm các dòng (không bao gồm dòng shebang) - thậm chí ít hơn theo số ký tự
  • Tập lệnh Python yêu cầu ba thư viện được nhập, trong khi mọi thứ bạn cần cho tác vụ này thực sự có sẵn trong bash
  • Các Python script đòi hỏi một vòng lặp rõ ràng để di chuyển các tập tin, trong khi đó là một phần của ngữ nghĩa của các mvlệnh trong bash
  • Tập lệnh bash có thể chạy nhanh hơn - có thể bạn sẽ gọi nó từ bash và bạn có thể sử dụng sourceđể chạy nó trong cùng một phiên bản của trình bao
  • glob.iglob("./*.png") chỉ là một câu nói miệng *.png

Nếu bạn muốn viết một thao tác đường ống cơ bản bằng Python, bạn sẽ phải kinh ngạc về độ dài. (Tất nhiên, một số thứ, như đường ống xuyên qua grep, có thể được thay thế bằng mã Python thay vì sử dụng chương trình bên ngoài, vì vậy bạn thường không cần phải sử dụng nhiều như vậy.)

Như một ví dụ, tôi đã từng phải viết một thói quen kiểm tra xem mỗi tên tệp trong một thư mục cụ thể là bao lâu. Nếu chúng dài hơn được hỗ trợ bởi một HĐH cụ thể, chúng phải được rút ngắn. Điều này có thể dẫn đến tên tệp trùng lặp mà tôi cần chỉnh sửa và vì chúng sẽ được liên kết từ một trang Web, nên các tên rút gọn cần phải ổn định, nghĩa là chúng phải được tạo theo cách mà cùng một tên tệp dài sẽ luôn dẫn đến cùng tên tập tin rút ngắn. Tôi đã làm điều này bằng cách tạo ra hex md5 của tên tệp dài và nối thêm bốn ký tự đầu tiên vào tên rút gọn (tên vẫn có thể va chạm, nhưng nó rất không ổn định, vì vậy tôi chỉ kiểm tra điều kiện đó và bảo lãnh nếu điều đó xảy ra) .

Tôi đã làm điều này trong bash vì nó là một phần của hệ thống xây dựng của chúng tôi đã được viết bằng bash. Đó chính xác là khó khăn để có được đúng như bạn có thể nghĩ. Sẽ mất ít thời gian hơn để viết bằng Python và có lẽ cũng sẽ rõ ràng hơn.

Tóm lại: các ngôn ngữ khác nhau được thiết kế cho các loại nhiệm vụ khác nhau; chọn ngôn ngữ có sẵn cho bạn phù hợp nhất với nhiệm vụ sắp tới.


Bạn không thể làm tương tự trong perl # / usr / bin / perl mv *.png $1(bình luận không giữ lại định dạng) nhưng với perl, bạn cũng có thể sử dụng các tính năng ngôn ngữ cấp cao hơn.
Poma

19

Các câu trả lời hiện tại cũng có giá trị, nhưng có một lý do mà chưa ai đề cập đến: bởi vì nó sẽ ở đó.

Mọi cài đặt * nix đã cho đều được thực hiện với một số gói tùy chọn có thể được tải hoặc không, và không phải tất cả các hệ thống sẽ có Python hoặc Perl hoặc Ruby. Nhưng nếu hệ thống dự kiến ​​sẽ có bất kỳ khả năng tương tác nào, nó sẽ có vỏ. Điều này có nghĩa là các kịch bản shell sẽ hoạt động trên các hệ thống từ máy chủ đến máy tính để bàn của lập trình viên đến máy tính để bàn máy khách mỏng cho các thiết bị nhúng, trên bất kỳ hệ thống nào hỗ trợ hệ thống tệp có thể ghi và dòng lệnh bash.

Đối với một người chỉ từng làm việc trong một môi trường máy chủ nhất quán, đây là điều có thể được coi là điều hiển nhiên và không quá quan trọng. Đối với một người làm việc trong một môi trường đa dạng hơn, điều này không nên bỏ qua.


9

Một phần đáng kể câu hỏi của bạn đã được trả lời ở đây:

Tại sao các ngôn ngữ script (ví dụ Perl, Python, Ruby) không phù hợp làm ngôn ngữ shell?

Đây là một đoạn trích từ câu trả lời của tôi cho câu hỏi đó :

Có một vài sự khác biệt mà tôi có thể nghĩ ra; chỉ cần suy nghĩ ở đây, không theo thứ tự cụ thể:

  1. Python & Co. được thiết kế để giỏi kịch bản. Bash & Co. được thiết kế để chỉ giỏi kịch bản, hoàn toàn không có sự thỏa hiệp. IOW: Python được thiết kế để giỏi cả về kịch bản và không kịch bản, Bash chỉ quan tâm đến việc viết kịch bản.

  2. Bash & Co. được gỡ bỏ, Python & Co. được gõ mạnh, có nghĩa là số 123, chuỗi 123và tệp 123khá khác nhau. Tuy nhiên, chúng không đượctĩnh , điều đó có nghĩa là chúng cần phải có các nghĩa đen khác nhau cho chúng, để tách chúng ra. Thí dụ:

    • Ruby: 123(số), Bash:123
    • Ruby: '123'(chuỗi), Bash:123
    • Ruby: /123/(regrec), Bash:123
    • Ruby: File.open('123')(tập tin), Bash:123
    • Ruby: IO.open('123')(mô tả tập tin), Bash:123
    • Ruby: URI.parse('123')(URI), Bash:123
    • Ruby: `123`(mệnh lệnh), Bash:123
  3. Python & Co được thiết kế để mở rộng quy mô lên tới 10000, 100000, thậm chí có 1000000 chương trình dòng, Bash & Co được thiết kế để mở rộng xuống đến 10 nhân vật chương trình.

  4. Trong Bash & Co., các tệp, thư mục, mô tả tệp, các quy trình đều là các đối tượng hạng nhất, trong Python, chỉ các đối tượng Python là hạng nhất, nếu bạn muốn thao tác các tệp, thư mục, v.v., bạn phải bọc chúng trong một Đối tượng Python trước.

  5. Lập trình Shell về cơ bản là lập trình dataflow. Không ai nhận ra rằng, ngay cả những người viết vỏ sò, nhưng hóa ra vỏ sò khá tốt về điều đó, và các ngôn ngữ có mục đích chung không quá nhiều. Trong thế giới lập trình có mục đích chung, dataflow dường như chủ yếu được xem như một mô hình tương tranh, không nhiều như một mô hình lập trình.

Tôi có cảm giác rằng cố gắng giải quyết những điểm này bằng cách kết hợp các tính năng hoặc DSL vào một ngôn ngữ lập trình đa dụng không hoạt động. Ít nhất, tôi vẫn chưa thấy một triển khai thuyết phục của nó. Có RuSH (Ruby shell), cố gắng triển khai shell trong Ruby, có vội vàng, đó là DSL bên trong để lập trình shell trong Ruby, có Hotwire, đó là shell Python, nhưng IMO không ai trong số đó thậm chí đóng để cạnh tranh với Bash, Zsh, cá và bạn bè.


Liên kết bị hỏng: Câu hỏi này (và câu trả lời) mà bạn đề cập đến bây giờ ở đâu? Hay tất cả những gì hữu ích được sao chép ở đây?
Sói

1
@Wolf: Rõ ràng, nó đã bị xóa vì lạc đề, sau gần ba năm. Thật không may.
Jörg W Mittag

1
Dưới đây là một phiên bản lưu trữ của câu hỏi đó: web.archive.org/web/20140528035940/http://stackoverflow.com/...
waldyrious

1

Tôi muốn nói rằng một kịch bản shell có lợi thế trong các tình huống mà bạn chỉ muốn thực hiện một tác vụ tự động siêu đơn giản. Ví dụ, nếu bạn muốn viết một tập lệnh sao lưu một thư mục từ máy chủ này sang máy chủ khác mỗi ngày vào lúc 5:00, thì việc sử dụng ngôn ngữ lập trình nhiệm vụ nặng nề là quá mức cần thiết.

Mặt khác, nếu tác vụ lập trình của bạn có nhu cầu nhiều hơn về cấu trúc điều khiển (if / then / other), cấu trúc lặp (lặp), I / O cơ sở dữ liệu, thì có lẽ phù hợp hơn với khả năng cao hơn ngôn ngữ lập trình hơn một kịch bản shell.

Tôi nghĩ rằng một quy tắc tốt là:

automatingSimpleTask ? shellScript() : programmingLanguage();

2
Không nên là shellScript() if automatingSimpleTask else programmingLanguage() lol.
gahooa

1
@gahooa haha ​​cho thấy phía nào của hàng rào tôi đang ở!
CFL_Jeff

1

Mặc dù bạn có thể khởi chạy các chương trình từ python / ruby ​​/ bất kỳ chương trình nào, nhưng nó lại khác nhau. Bạn có thể cần sử dụng API để khởi chạy một cái gì đó - ví dụ: fork (). Trong một kịch bản shell, các chương trình hoạt động giống như các chức năng trong ngôn ngữ lập trình thông thường và có thể được thực thi, xử lý, v.v. với nỗ lực tối thiểu. Luồng dữ liệu rất rõ ràng bằng cách sử dụng đường ống quá.


0

Nếu bạn hoàn toàn tự do chọn ngôn ngữ lập trình bạn sử dụng cho một số tác vụ nhất định, bạn có thể gần như hoàn toàn tránh học bash và thực hiện mọi tác vụ lập trình tập lệnh với Perl, Python hoặc Ruby. Điều này đôi khi có thể dẫn đến một giải pháp dài dòng hơn, đặc biệt là trong trường hợp khi bạn chỉ cần một tập lệnh gọi một chuỗi các công cụ Unix khác, nhưng trong những trường hợp phức tạp hơn, bạn đã đúng, những ngôn ngữ tập lệnh hiện đại này cung cấp cho bạn nhiều khả năng hơn để viết mã có thể duy trì tốt hơn (họ cũng cung cấp cho bạn nhiều khả năng hơn để viết mã bị xáo trộn, nhưng đó là lựa chọn của bạn).

Mặt khác, thường thì chúng tôi không được tự do chọn ngôn ngữ mà chúng tôi thích nhất, bởi vì chúng tôi phải làm việc với mã kế thừa hoặc mã được viết bởi một người biết bash nhưng không biết một trong những ngôn ngữ kịch bản mà bạn đặt tên.


0

Shell scripting một ngôn ngữ lập trình được giải thích. Dưới đây là một vài lý do tại sao tôi chọn viết các tập lệnh bằng bash thay vì perl hoặc python hoặc một số ngôn ngữ kịch bản lệnh khác:

Hoạt động ở mọi nơi : Thông dịch viên phức tạp hơn có thể không phải lúc nào cũng có sẵn, chẳng hạn như trong khi khởi động hệ thống hoặc trên các hệ thống nhúng. Bash có sẵn ngay cả trong busybox.

Hoạt động trên dòng lệnh : Nếu bạn thành thạo về kịch bản shell, bạn có thể sử dụng các kỹ năng đó để thực hiện những điều phức tạp trong các tập lệnh ad-hoc ngay trên dòng lệnh. Tôi sử dụng kỹ năng này hàng ngày như một sysadmin.

Dễ dàng hơn để viết các chương trình gọi các chương trình khác: Nếu những gì bạn đang cố gắng kết hợp nhiều chương trình hiện có với nhau theo những cách thú vị, thì có thể đơn giản hơn để thực hiện trong tập lệnh shell so với ngôn ngữ cấp cao hơn.

Nếu chương trình là 30 dòng hoặc ít hơn, tôi thường sẽ viết nó bằng cách sử dụng kịch bản shell. Nếu có bất kỳ thao tác phức tạp hoặc phức tạp hoặc phân tích nào để xử lý, tôi sẽ thực hiện bằng python hoặc perl.


-1

Bạn nên xem qua coffeescript. Lời của họ:

Bên dưới tất cả những dấu ngoặc nhọn và dấu chấm phẩy vụng về đó, JavaScript luôn có một mô hình đối tượng tuyệt đẹp ở trung tâm của nó. CoffeeScript là một nỗ lực để phơi bày những phần hay của JavaScript một cách đơn giản.

Nguyên tắc vàng của CoffeeScript là: "Đó chỉ là JavaScript".

Chà ... đây là câu trả lời siêu mới bắt đầu.

Là người mới bắt đầu học tự động trong 6 tháng qua và nếm thử một chút C, C ++, Javascript và nhiều Bashscript hơn trong những ngày qua ... Tôi có thể nói với bạn:

Các kịch bản Shell, giống như các tập lệnh được viết bằng bash, có thể làm nhiều việc. Họ có thể gọi các chương trình Unix, dẫn đầu ra của chúng, chuyển hướng I / O từ / đến tệp, kiểm soát luồng, kiểm tra xem một tệp có tồn tại không, v.v.

và không phải là đơn giản tuyệt vời này! ? vòng lặp và biến? ồ

trăn và ruby, cũng có thể làm những điều này. Và, họ (tôi nghĩ) dễ đọc và dễ bảo trì hơn.

Xin vui lòng, cho tôi biết nơi bạn nhìn thấy điều này? Tôi đã viết bashscript bằng gedit ngay cả bằng geany và tôi có thể định dạng, (tab?) Và tôi đọc mã của mình với tốc độ ánh sáng bằng cách sử dụng bashscript so với các ngôn ngữ khác.

Liệu ngôn ngữ này có các công cụ khác để giữ trật tự? Tôi biết hướng đối tượng tiết kiệm rất nhiều mã, nhưng ... mọi người nói bashscript cũng là OO! Ôi 2! Đó là quan điểm của tôi ở đây. Sẽ:

lợi thế của shell a script

là trong câu hỏi này: Làm thế nào để làm những gì bashdamnt Breath này có thể làm trong perl hoặc phyton hoặc ruby? Dễ thôi?

( bashdamnt Breath = xdotool )


WTF đang diễn ra ở đây? Nó giống như một câu trả lời Doge ..
naught 101
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.