Có nên sử dụng zsh thay vì bash scripts không? [đóng cửa]


25

Tôi có thể cho rằng đủ người đã zshcài đặt để chạy tập lệnh với

#!/usr/bin/env zsh

như shebang?

Hay điều này sẽ làm cho các tập lệnh của tôi không thể chạy được trên quá nhiều hệ thống?

Làm rõ: Tôi quan tâm đến các chương trình / tập lệnh mà người dùng cuối có thể muốn chạy (như trên Ubuntu, Debian, SUSE, Arch & c.)


4
Câu hỏi kỳ lạ. Mục tiêu của bạn là ai? Trong một số vòng kết nối nhất định (nhà phát triển web Ruby-on-Rails) zshcó thể phổ biến trong khi ở những nhóm khác (lĩnh vực ngân hàng) thì điều đó hầu như không nghe thấy. Tôi nghĩ bạn nên cung cấp thêm thông tin nếu bạn cần lời khuyên phù hợp về vấn đề này.
rahmu

Thế giới người dùng cuối linux.
Profpatsch

2
WRT "thế giới người dùng cuối linux chung", zsh là không chuẩn. Nó không được cài đặt theo mặc định (trên hầu hết hoặc tất cả các bản phát hành) hoặc được yêu cầu bởi bất cứ điều gì, vì vậy hầu hết mọi người sẽ không có nó.
goldilocks

3
Tôi chưa zshcài đặt trên bất kỳ hệ thống nào của mình và tôi sẽ không cài đặt nó cho một tập lệnh. Bạn thậm chí nên tránh bashism mặc dù bash thường có sẵn.
frostschutz

Câu trả lời:


29

Đối với tính di động, không. Mặc dù zshcó thể được biên dịch trên bất kỳ Unix hoặc Unix nào và thậm chí cả Windows thông qua Cygwin và được đóng gói cho hầu hết các lượt thích Unix và một số thương mại nguồn mở, nhưng nó thường không được bao gồm trong cài đặt mặc định.

bashở đầu bên kia được cài đặt trên các hệ thống GNU (như bashvỏ của dự án GNU) giống như phần lớn các hệ thống dựa trên Linux không nhúng và đôi khi trên các hệ thống không phải GNU như Apple OS / X. Trong khía cạnh thương mại Unix, shell Korn (biến thể AT & T, mặc dù nhiều hơn ksh88một) là tiêu chuẩn và cả hai bashzshđều nằm trong các gói tùy chọn. Trên BSDs, vỏ tương tác ưa thích thường là tcshkhi shđược dựa trên một trong hai vỏ Almquist hay pdkshbashhay zshcần phải được cài đặt như gói tùy chọn là tốt.

zshđược cài đặt theo mặc định trên Apple OS / X. Nó thậm chí đã từng /bin/shở đó. Nó có thể được tìm thấy theo mặc định trong một vài bản phân phối Linux như SysRescCD, Grml, Gobolinux và có thể là những bản khác, nhưng tôi không nghĩ bất kỳ bản phân phối chính nào.

Giống như bash, có câu hỏi về phiên bản đã cài đặt và do đó, các tính năng có sẵn. Chẳng hạn, không có gì lạ khi tìm thấy các hệ thống có bash3hoặc zsh3. Ngoài ra, không có gì đảm bảo rằng tập lệnh mà bạn viết bây giờ zsh5sẽ hoạt động với zsh6mặc dù bashchúng cố gắng duy trì khả năng tương thích ngược.

Đối với tập lệnh, quan điểm của tôi là: sử dụng cú pháp shell POSIX vì tất cả các Unice đều có ít nhất một shell được gọi sh(không nhất thiết phải có /bin) để có thể diễn giải cú pháp đó. Sau đó, bạn không phải lo lắng quá nhiều về tính di động. Và nếu cú ​​pháp đó không đủ cho nhu cầu của bạn, thì có lẽ bạn cần nhiều hơn một cái vỏ.

Sau đó, các tùy chọn của bạn là:

  • Perl có mặt ở khắp mọi nơi (mặc dù một lần nữa bạn có thể phải giới hạn bản thân trong bộ tính năng của các phiên bản cũ và không thể đưa ra các giả định về các mô-đun Perl được cài đặt theo mặc định)
  • Chỉ định trình thông dịch và phiên bản của nó (python 2.6 trở lên, zsh 4 trở lên, bash 4.2 trở lên ...), làm phụ thuộc cho tập lệnh của bạn, bằng cách xây dựng gói cho mọi hệ thống được nhắm mục tiêu chỉ định phụ thuộc hoặc bằng cách quy định nó trong tệp README được gửi cùng với tập lệnh của bạn hoặc được nhúng dưới dạng nhận xét ở đầu tập lệnh của bạn hoặc bằng cách thêm một vài dòng trong cú pháp Bourne ở đầu tập lệnh để kiểm tra tính khả dụng của trình thông dịch được yêu cầu và giải quyết lỗi rõ ràng khi không, như kịch bản này cần zsh 4.0 trở lên .
  • Gửi trình thông dịch cùng với tập lệnh của bạn (hãy cẩn thận với các hàm ý cấp phép) có nghĩa là bạn cũng cần một gói cho mỗi HĐH được nhắm mục tiêu. Một số trình thông dịch làm cho nó dễ dàng hơn bằng cách cung cấp một cách để đóng gói tập lệnh và trình thông dịch của nó trong một tệp thực thi duy nhất.
  • Viết nó bằng một ngôn ngữ biên dịch. Một lần nữa, một gói cho mỗi hệ thống được nhắm mục tiêu.

"Zsh-man" nói "không", tôi tự hào về bạn! ^^ Tính di động ftw! (với tất cả sự cẩn thận của nó ...). +1.
Olivier Dulac

9

Không, bạn không thể. Những gì được đảm bảo có sẵn /bin/sh, về cơ bản là vỏ Bourne ban đầu. Hầu như tất cả (lưu ý các cài đặt Linux "gần như"!) Sẽ có bash, nhưng trên các hệ thống * BSD thì rất hiếm (sự thuyết phục BSD có những hiểu lầm nghiêm trọng về mã GPL, như bash). Tôi không biết shell tiêu chuẩn là gì trên Mac, nhưng một lần nữa, có những hiểu lầm về GPL. Tương tự cho Solaris.

zsh là một vỏ thích hợp, nó không có trong cài đặt mặc định của Fedora (và tôi không tin rằng nó là mặc định cho bất kỳ phân phối chính nào).


6
Chắc chắn không phải là Bourne Shell ban đầu, mà là vỏ Posix trên các hệ thống tuân thủ Posix, trên nhiều hệ thống là / bin / sh, nhưng không nhất thiết phải như vậy (Trên Solaris <= phiên bản 10 này là / usr / xpg4 / bin / sh)
Giám sát

Chà, cài đặt mặc định của Wikipedia không thực sự quan trọng. Điều quan trọng là nếu nó được cài đặt ở tất cả.
Profpatsch

@Profpatsch, sau đó cài đặt mặc định rất phù hợp (có lẽ phân phối đã xác định những gì mọi người thực sự sử dụng).
vonbrand

2
@StephaneChazelas, "thích hợp" như trong "ít người dùng sử dụng nó" / "vài cài đặt có nó". Nó có thể là vỏ tốt nhất kể từ bánh mì cắt lát, nhưng nếu chỉ một phần nhỏ sử dụng nó, bạn không thể tin rằng nó sẽ được cài đặt ở mọi nơi.
vonbrand

1
Lưu ý rằng nếu bạn cho rằng phần lớn các triển khai Linux hiện nay được nhúng (nghĩ rằng android, máy in, bộ định tuyến, TV, bóng đèn ...), thì phần lớn các hệ thống dựa trên Linux khôngbash(mặc dù các hệ thống đó có thể không phải là chính nhắm mục tiêu mà OP có trong đầu cho câu hỏi của anh ấy)
Stéphane Chazelas

2

Tôi nghĩ rằng nó thực sự phụ thuộc vào các tính năng bổ sung zsh bạn đang sử dụng và ở đâu. Nếu bạn dự định phân phối tập lệnh của mình trên các hệ thống và người dùng khác nhau, tôi sẽ đề nghị sử dụng bash hoặc thậm chí sh .

Đồng thời nếu tập lệnh của bạn được thiết kế để được thực thi trên toàn tổ chức của bạn và bạn có quy ước có zsh trên máy của mình (ví dụ như AMI cơ bản tương tự) và tác vụ của bạn có lợi ích rõ ràng từ các tiện ích mở rộng như bộ chọn tệp nâng cao hoặc các nội dung khác từ http: / /www.rayninfo.co.uk/tips/zshtips.html Tôi sẽ nói đi trước!


1

Như đã nêu, bashthường có sẵn trong cài đặt mặc định cho nhiều bản phát hành. Kịch bản của bạn sẽ không đạt được cơ sở người dùng lớn nhất bằng cách dựa vào zsh.

Một câu hỏi quan trọng cần trả lời trước khi thiết kế tập lệnh của bạn là " Tại sao nó lại được thực thi trong tập lệnh nào? "

Các shell khác nhau sử dụng cú pháp khác nhau hoặc cung cấp các hàm shell bổ sung có thể không được các shell khác hỗ trợ. Để viết một tập lệnh cho "thế giới người dùng cuối linux chung", hãy xác định xem tập lệnh của bạn có sử dụng bất kỳ cú pháp hoặc hàm shell nào dựa trên một môi trường shell cụ thể hay không.

Ví dụ: bashshell hỗ trợ các bản mở rộng nhất định không được hỗ trợ bởi dashshell Bourne hoặc bất kỳ /bin/shđiểm nào trên hệ thống của người dùng.

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Feb 19  2014 /bin/sh -> dash

Hãy thử thực hiện echo {1..10}với /bin/shso với /bin/bashvà bạn sẽ nhận được kết quả rất khác nhau.

Điều tương tự cũng xảy ra zsh, trong khi hỗ trợ hầu hết bashcú pháp, cung cấp mở rộng bổ sung và cú pháp không được bashshell hỗ trợ . Xem bảng này so sánh vỏ cho các ví dụ cụ thể.

Bạn có thể mở rộng cơ sở người dùng tiềm năng của mình ra ngoài bashbằng cách tuân thủ các tập lệnh hoạt động khi được gọi với #!/bin/sh -u. Tuy nhiên, điều này dẫn đến một câu hỏi quan trọng khác để đặt ra: " Cái gì đang được hy sinh để đổi lấy tính di động lớn hơn? "

Xác định xem sự khác biệt liên quan đến mối quan tâm bảo mật, chức năng, hiệu quả hoặc bất cứ điều gì khác mà bạn cảm thấy là ưu tiên cho tập lệnh của bạn có đáng để hy sinh hay không. Bạn có thể không muốn sử dụng rộng rãi tập lệnh với lỗ hổng bảo mật đã biết chỉ vì nó hoạt động trong nhiều môi trường hơn.

Vì vậy, nhiều tập lệnh được viết để bashhỗ trợ cho các tập lệnh này được sử dụng làm tiêu chí khi so sánh các shell lệnh . Nhiều người sẽ có thể chạy tập lệnh của bạn hơn nếu nó dựa vào zshhoặc bất kỳ cú pháp nào khác dành riêng cho môi trường shell.

Ngoài ra, hãy nhớ rằng cuối cùng bạn không có quyền kiểm soát cách người dùng thực thi tập lệnh (cũng hữu ích để gỡ lỗi các tập lệnh trong các trình bao khác nhau ):

Hãy nhớ rằng nếu bạn sử dụng trình bao để đọc tập lệnh shell (tập lệnh sh sh tên tập), thay vì thực thi trực tiếp (tập tin ./scriptname,), trình bao sẽ coi tất cả các nhận xét khi bắt đầu tập lệnh shell là nhận xét. Cụ thể, nhận xét chỉ định trình thông dịch sẽ sử dụng khi thực thi tập lệnh (Số #! / Bin / sh -u -) sẽ bị bỏ qua, cũng như tất cả các tùy chọn được liệt kê bên cạnh trình thông dịch đó.

Vì vậy, điều tốt nhất bạn có thể làm về việc này là làm cho các tập lệnh của bạn có thể di động, miễn là không có sự hy sinh lớn cho cách thức hoạt động của nó.

Bạn cũng có thể thấy các quy ước mã hóa Bash - Stack Overflow .


1
"Những gì đang được hy sinh" ... hãy nhìn vào autoconf. Họ đã nhắm mục tiêu / bin / sh như trong "Original Bourne Shell" vì tất cả các shell đều hỗ trợ bộ tính năng (nhỏ) đó. Và họ đau khổ vì nó rất nhiều.
Jürgen A. Erhard

1

Điều duy nhất bạn gần như có thể đảm bảo là có một /bin/sh. Đó có thể là một vỏ liên kết tĩnh thực sự hoặc nó có thể là một liên kết đến một vỏ khác. Lớp vỏ khác thường phát hiện ra rằng nó được gọi là sh và sẽ chạy trong chế độ tương thích.

Chú ý gần như trong câu đầu tiên.

Mọi unix như hệ thống tôi từng làm việc đều có nó. Nhiều người trong số họ cũng đã cài đặt bash (nhưng không phải tất cả trong số họ. Ví dụ, bash nó không được cài đặt theo mặc định trên một số BSD. Một số tàu phân phối Linux với DASH , vỏ thay thế Debian Almquist.

Những gì bạn có thể đảm bảo là hướng dẫn cài đặt của bạn. Bạn có thể thêm một dòng vào tệp README cần zsh. Nếu bạn xây dựng một gói thì bạn có thể đánh dấu zsh là một sự phụ thuộc. Bạn có thể kiểm tra nó bằng các công cụ autoconf / automake. Bạn có thể kiểm tra xem zsh có được tìm thấy trong tập lệnh cài đặt hay không (bắt đầu bằng / bin / sh và thử xác định vị trí zsh, nếu tìm thấy tiếp tục. Nếu không hiển thị lỗi. Ví dụ: "Cảnh báo: ZSH chưa được cài đặt. Vui lòng đọc tệp hướng dẫn cài đặt! ".)

Tôi chắc chắn tôi đã quên một vài lựa chọn. Nhưng những điểm chính là:

  • Bạn có thể đảm bảo không có gì cho đến khi bạn kiểm tra nó.
  • Bạn gần như được đảm bảo rằng / bin / sh có mặt và bạn có thể thực hiện một số kiểm tra với điều đó.

POSIX yêu cầu / bin / sh, AFAIU. Giống như nó đòi hỏi một vài tiện ích hợp lý khác. Kiểm tra các điều kiện cần thiết của autoconfiscation.
vonbrand

@vonbrand. POSIX không yêu cầu /bin/sh. Nó đòi hỏi một shmôi trường trong môi trường chính xác (không phải là môi trường mặc định) hoạt động như chỉ định. /bin/shcó thể không phải là vỏ POSIX. Ví dụ, trên Solaris 10 trở về trước, nó vẫn là vỏ Bourne và tiêu chuẩn shđã có /usr/xpg4/bin.
Stéphane Chazelas
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.