Về Shebang, một cách độc lập hơn với hệ thống sẽ là sử dụng e. g. ‘#. /usr/bin/env bash'. Với điều này, tập lệnh cũng sẽ có thể sử dụng được trên FreeBSD, trong đó bash sẽ được cài đặt từ Cổng FreeBSD và sau đó có sẵn dưới dạng '/usr/local/bin/bash' hoặc một số hệ thống Linux [e. g. Debian] ở đâu là ‘/usr/bin/bash’. Thật không may, có một số hệ thống unixode khác xung quanh, trong đó 'env' không có trong '/usr/bin/' và vì vậy shebang cần được điều chỉnh
[Tôi , nhưng sau đó nhận ra điều này xứng đáng với bài đăng của riêng mình. ]
/usr/bin/env
shebang cung cấp một phương tiện cho tính di động của hệ thống. Nó có nhiều trường hợp sử dụng hợp lệ. Tuy nhiên, bạn không chỉ đạt được tính di động một cách kỳ diệu bằng cách chuyển sang một env
shebang. Có nhiều sự đánh đổi để xem xét
Lưu ý về cách thức nhị phân env
có thể không có trong /usr/bin
trên tất cả các nền tảng, gợi ý về một số sự đánh đổi này, nhưng còn nhiều điều nữa
Sự đánh đổi là mất khả năng dự đoán và độ tin cậy, hoặc chức năng, hoặc tăng khả năng bảo trì và quản lý
Hãy để tôi giải thích
Shebang /usr/bin/env hoạt động như thế nào
Khi được sử dụng trong Shebang, tệp nhị phân /usr/bin/env
sẽ sử dụng PATH
của môi trường hiện tại để tra cứu tệp nhị phân trình thông dịch cho tập lệnh, giống như cách trình bao tra cứu các lệnh
Ví dụ: hãy tưởng tượng bạn đã cài đặt bash v5 trên máy Mac của mình. Thủ công hoặc sử dụng brew
hoặc một số hệ thống quản lý gói khác
Điều này sẽ [thường] đặt nhị phân bash v5 tại
/usr/bin:/bin:/usr/sbin:/sbin
0. Thư mục /usr/bin:/bin:/usr/sbin:/sbin
1 là một lựa chọn phổ biến cho các công cụ dòng lệnh tùy chỉnh, bởi vì nó là một phần của PATH
mặc định cho shell tương tác trên macOS và không được bảo vệ bởi SIP/SSV. PATH
mặc định trên macOS cho shell tương tác là/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Một số cài đặt sẽ đặt tệp nhị phân ở một vị trí khác trong hệ thống tệp. Sau đó, bạn phải đặt trước thư mục chứa tệp nhị phân cho biến PATH
trong cấu hình trình bao của mình. Thứ tự của các thư mục trong PATH
rất quan trọng, bởi vì shell và env
sẽ dừng tìm kiếm khi chúng tìm thấy kết quả khớp đầu tiên. Nếu
/usr/bin:/bin:/usr/sbin:/sbin
1 xuất hiện sau /usr/bin:/bin:/usr/sbin:/sbin
8 trong PATH
thì nhị phân mới sẽ không được 'nhìn thấy' vì nhị phân cũ, cài đặt sẵn của /usr/bin/env
0 được tìm thấy trướcMột số cài đặt giải quyết vấn đề này bằng cách đặt một liên kết tượng trưng tới tệp nhị phân trong
/usr/bin:/bin:/usr/sbin:/sbin
1- PATH đến từ đâu
Khi bạn chạy một tập lệnh từ shell tương tác với shebang là /usr/bin/env
2, thì env
sẽ tìm thấy nhị phân bash v5 trước trong
/usr/bin:/bin:/usr/sbin:/sbin
1, vì vậy tập lệnh của bạn được diễn giải bằng bash v5. Đây có lẽ là những gì bạn đã hy vọng, khi bạn cài đặt bash v5 ngay từ đầuKhi bạn chạy cùng một tập lệnh trên một máy Mac khác [cùng một phiên bản macOS, nhưng nó không cài đặt bash v5] env
sẽ chọn /usr/bin/env
0. Tập lệnh của bạn sẽ hoạt động ngay cả khi máy Mac khác không có
/usr/bin:/bin:/usr/sbin:/sbin
0, vì vậy bạn đã có được tính di độngTuy nhiên, /usr/bin/env
0 là bash v3. 2, vì vậy tập lệnh của bạn có thể hoạt động khác đi. Nếu tập lệnh sử dụng các tính năng bash v5 không có trong bash v3 15 tuổi. 2, nó sẽ tạo ra lỗi. Vì bạn đã chủ động chọn cài đặt bash v5 trên máy Mac đầu tiên, nên có khả năng bạn cần một số tính năng bash v5 này, vì vậy có khả năng tập lệnh của bạn sẽ không thành công trên các máy Mac khác không cài đặt bash v5
Bạn đã mất khả năng dự đoán và độ tin cậy [phiên bản và tính năng nào khả dụng? Tập lệnh của tôi có chạy thành công không?] hoặc bạn mất chức năng [các tính năng được thêm vào bash v5 kể từ v3. 2]. Để duy trì độ tin cậy, bạn có thể hạn chế tập lệnh đối với các tính năng hoạt động trong cả hai phiên bản bash. Nhưng sau đó, việc sử dụng shebang env
không mang lại lợi thế nào cho bạn và bạn cũng có thể sử dụng /usr/bin/env
0 làm shebang
Một số giải pháp
Một giải pháp thay thế là sử dụng shebang
/usr/bin:/bin:/usr/sbin:/sbin
0 cho các tập lệnh sử dụng chức năng bash v5 và tiếp tục sử dụng /usr/bin/env
0 cho các tập lệnh cần chạy trên nhiều máy Mac, trong đó bạn chú ý chỉ sử dụng các tính năng có sẵn trong bash v3. 2. Bạn có được khả năng dự đoán và độ tin cậy, nhưng các tập lệnh bash v5 của bạn không thể chuyển sang các máy Mac khác. Chúng thậm chí có thể bị lỗi trên các máy Mac khác đã cài đặt bash v5, nếu tệp nhị phân bash v5 được cài đặt ở một vị trí khácKhi bạn sử dụng /usr/bin/env
3 cho tập lệnh bash v5, tập lệnh này sẽ chạy tốt trên tất cả các máy Mac đã cài đặt bash v5 và cấu hình PATH
đúng cách để tìm thấy tập lệnh đó. [Cấu hình và duy trì PATH
không tự xảy ra. ] Nhưng tập lệnh vẫn sẽ bị lỗi trên máy Mac mà không có bất kỳ bash v5 nào. Bạn có thể [và có lẽ nên] thêm kiểm tra phiên bản vào tập lệnh, nhưng hiện tại bạn đang tăng cường bảo trì mã
Khi bạn đang quản lý một nhóm máy Mac, bạn cũng có tùy chọn [hoặc trong trường hợp này, tôi muốn nói là nghĩa vụ] cài đặt bash v5 ở một vị trí và phiên bản nhất quán trên tất cả các máy Mac trong nhóm của bạn và định cấu hình trước PATH
thích hợp . Sau đó, bạn sẽ có được khả năng dự đoán và chức năng, nhưng nó đòi hỏi nhiều nỗ lực hơn trong việc triển khai và bảo trì
Điều này yêu cầu một MacAdmin có kinh nghiệm dày dặn và công cụ thích hợp, cả hai đều không miễn phí
Ghi chú. Có nhiều giải pháp mã nguồn mở tuyệt vời dành cho macOS trong lĩnh vực này, nhưng tôi coi chúng là 'miễn phí, miễn phí', vì vậy chúng đi kèm với yêu cầu kỹ năng cao hơn và/hoặc nỗ lực bảo trì cho quản trị viên. Và điều này không có nghĩa là tất cả các giải pháp thương mại đều 'dễ sử dụng'. Đó là sự đánh đổi tất cả các con đường đi xuống
Bối cảnh thay đổi PATH
Lưu ý rằng cho đến nay tôi vẫn nói về “_______ mặc định cho trình bao tương tác. ”
Biến PATH
có thể khác nhau tùy theo ngữ cảnh, ngay cả trên cùng một máy Mac với cùng một người dùng. Ví dụ: khi bạn chạy tập lệnh của mình bằng lệnh AppleScript env
0, thì ______17_______ trong ngữ cảnh đó không giống với ___17_______ trong trình bao tương tác của bạn. Nó sẽ là
/usr/bin:/bin:/usr/sbin:/sbin
Bạn có thể xác minh điều này bằng cách mở Trình chỉnh sửa tập lệnh và chạy chương trình env
3. Bối cảnh khác, chẳng hạn như tập lệnh trong gói cài đặt sẽ thấy các giá trị PATH
khác
- Đặt PATH trong Tập lệnh
Quan trọng nhất, PATH
trong các ngữ cảnh khác này, không chứa
/usr/bin:/bin:/usr/sbin:/sbin
1 hoặc bất kỳ phần bổ sung nào khác mà bạn đã thực hiện cho PATH
của mình trong tệp cấu hình trình bao. Một shebang /usr/bin/env
sẽ không 'thấy' nhị phân bash 5 mà bạn đã cài đặt trên hệ thống. Cùng một tập lệnh với cùng một người dùng trên cùng một máy tính, sẽ hoạt động khác khi chạy trong một ngữ cảnh khácCác giá trị PATH
khác nhau này là sự lựa chọn có chủ ý. Trong những bối cảnh này, đặc biệt là các tập lệnh gói cài đặt, độ tin cậy và khả năng dự đoán là cực kỳ quan trọng. Bạn không muốn các tệp nhị phân tùy chỉnh do người dùng và bên thứ ba cài đặt can thiệp vào việc tra cứu lệnh
Chú thích bên lề về Python
Với env
0 và env
1 và các trình thông dịch thời gian chạy khác, điều đó thậm chí còn khó khăn hơn. Có thể có nhiều phiên bản khác nhau được cài đặt và hành vi cũng như chức năng giữa các phiên bản khác nhau nhiều hơn. Máy Mac của tôi hiện có bốn tệp nhị phân Python 3 khác nhau, mỗi tệp có một phiên bản khác nhau và tôi thậm chí không phải là nhà phát triển Python toàn thời gian từ xa. Khi bạn gọi env
1 trên máy Mac không dành cho nhà phát triển, nó sẽ kích hoạt hộp thoại 'Bạn phải cài đặt Công cụ dòng lệnh dành cho nhà phát triển' khi Xcode chưa được cài đặt. [Các nhà phát triển dường như gặp khó khăn khi xem xét rằng có những máy Mac không cài đặt Xcode. ]
Với sự sụp đổ của python 2 trong macOS 12. 3, một số nhà phát triển đã phản ứng bằng cách thay đổi shebang trong tập lệnh python của họ từ env
3 thành env
4 mà không giải quyết được gì, khi tệp nhị phân biến mất mà không cần thay thế. Một số chuyển sang env
5, điều này có thể khiến mọi thứ trở nên tồi tệ hơn, bằng cách kích hoạt cài đặt Công cụ dành cho nhà phát triển hoặc chọn sai phiên bản nhị phân python3 ngẫu nhiên
- macOS Monterey 12. 3 loại bỏ Python 2 – Bộ sưu tập liên kết
Giải pháp đáng tin cậy duy nhất cho mớ hỗn độn env
0 là triển khai một phiên bản nhất quán của Python 3 ở một vị trí nhất quán. Bạn có thể thực hiện việc này bằng cách kết hợp khung và mô-đun python mà công cụ của bạn cần cùng với công cụ hoặc bằng cách triển khai và duy trì các khung và mô-đun Python bằng một hệ thống quản lý
Phối cảnh MacAdmin
Với tư cách là Quản trị viên Mac, tập lệnh của tôi không cần phải di chuyển sang các hệ thống khác ngoài macOS. Họ thường sử dụng các công cụ và truy cập các tệp và thư mục chỉ tồn tại trên macOS. Tuy nhiên, khả năng dự đoán và độ tin cậy là tối quan trọng. Tập lệnh cấu hình và cài đặt cần chạy đáng tin cậy trên hàng nghìn máy Mac trên nhiều phiên bản macOS [thậm chí cả các phiên bản trong tương lai] bất kể cài đặt gì khác
Với tư cách là Quản trị viên Mac, chúng tôi cũng [nên] có các công cụ và kinh nghiệm để triển khai và duy trì các tệp nhị phân ở các vị trí có thể dự đoán được. Nhưng sau đó, giống như mọi người, chúng tôi chỉ có thời gian hạn chế và thường cần ưu tiên phần mềm kinh doanh quan trọng hơn công cụ của riêng mình. Vì vậy, các tệp nhị phân thông dịch được cài đặt sẵn có ít 'ma sát' khi sử dụng, ngay cả khi chúng có thể bị giảm chức năng khi so sánh với phiên bản mới nhất hiện có ở nơi khác
Đây là lý do bash v3. 2 vẫn có mặt trên macOS 12. 3 và sẽ không bao giờ dễ dàng khi cuối cùng Apple quyết định loại bỏ nó. Rất nhiều công cụ và tập lệnh dựa trên /usr/bin/env
0
[Tôi không mong đợi việc gỡ bỏ sẽ sớm xảy ra, nhưng có giới hạn về thời gian Apple sẽ hoặc có thể giữ trình thông dịch này từ năm 2007 trên hệ thống. Chúng tôi nhận được cảnh báo đầu tiên khi Apple chuyển shell tương tác mặc định sang zsh ở Catalina. Sẽ có nhiều cảnh báo hơn…Tôi hy vọng. Với việc loại bỏ mã nhị phân Python 2, chúng tôi thấy rằng Apple có thể di chuyển nhanh chóng khi họ cảm thấy cần thiết. Họ thậm chí không đợi một bản phát hành macOS lớn. ]
Trong bối cảnh này, không có lợi ích gì khi sử dụng /usr/bin/env
. Sự đánh đổi ủng hộ shebang tuyệt đối rất mạnh
Tính di động đa nền tảng
Sau câu nói này, bạn có thể nghĩ rằng tôi khuyên bạn không nên sử dụng /usr/bin/env
shebangs luôn. Nhưng có những trường hợp sử dụng rất tốt. Sử dụng /usr/bin/env
shebangs là giải pháp cho quy trình công việc yêu cầu tính di động đa nền tảng
Khi tập lệnh của bạn cần chạy trên nhiều nền tảng, việc cài đặt các tệp nhị phân ở cùng một vị trí trong hệ thống tệp có thể không thực hiện được hoặc yêu cầu nỗ lực không hợp lý. Ví dụ:
/usr/bin:/bin:/usr/sbin:/sbin
8 và /usr/bin
được bảo vệ bởi SIP và Sealed System Volume trên macOS, vì vậy bạn không thể thêm công cụ của mình vào đó mà không ảnh hưởng đáng kể đến tính toàn vẹn và bảo mật của toàn bộ hệ thốngTrong những trường hợp này, việc sử dụng /usr/bin/env
shebang mang lại sự linh hoạt cần thiết, để tập lệnh của bạn có thể hoạt động trên nhiều nền tảng. Nhưng tính di động không đến một cách kỳ diệu từ việc chuyển đổi shebang
Các nền tảng đích cần cài đặt nhị phân và các phiên bản phải khớp. Vị trí cài đặt của tệp nhị phân phải có trong PATH
trong ngữ cảnh tập lệnh chạy trong. Để có được hành vi đáng tin cậy, các hệ thống bạn đang chuyển giữa cần phải được quản lý tốt, với thiết lập và cấu hình có thể dự đoán được của môi trường và nhị phân trình thông dịch
Khi các tập lệnh của bạn hoạt động 'dễ dàng' trên các hệ thống với env
shebang, đó là nhờ vào công việc của các nhà phát triển nền tảng và nhóm quản trị hệ thống/nhà phát triển của bạn để tạo và duy trì tính nhất quán này. Ngay cả khi bạn là nhà phát triển duy nhất và quản trị viên devops, duy trì tất cả các hệ thống, bạn phải thực hiện công việc này. Ngoài ra, các nhà phát triển nền tảng đã nỗ lực rất nhiều để đạt được phần lớn tính nhất quán này ngay từ đầu. Như người bình luận đã lưu ý, một số nền tảng thậm chí không đồng ý về vị trí của mã nhị phân env
Bạn có được tính di động với mức giá bảo trì tăng lên
Đánh đổi tất cả các con đường xuống
Ngoài ra, bạn có thể giữ cho tập lệnh đơn giản – giới hạn trong một tập hợp con các tính năng phổ biến trên các nền tảng và phiên bản – để sự khác biệt không ảnh hưởng. Sau đó, bạn đánh đổi độ tin cậy và tính di động với giá của chức năng
Đây thường là sự đánh đổi với Python [hạn chế sử dụng các tính năng của python đối với những tính năng phổ biến giữa các phiên bản] và một trong những lý do khiến Python 2 tồn tại quá lâu trên macOS
Sử dụng POSIX sh, thay vì bash hoặc zsh, là một tùy chọn khác để đạt được tính di động, nhưng điều đó có sự đánh đổi của riêng nó. Hầu hết những đánh đổi này sẽ nằm ở chức năng, nhưng cũng xem xét không phải tất cả các mô phỏng sh đều giống nhau và việc hỗ trợ nhiều trình giả lập khác nhau hoặc tập hợp con chung thực sự của chức năng, đòi hỏi nhiều nỗ lực hơn
Phần kết luận
Shebang với đường dẫn tuyệt đối có điểm mạnh và điểm yếu của chúng, cũng như shebang với /usr/bin/env
. Mỗi người có trường hợp sử dụng của họ và bạn phải hiểu sự đánh đổi khi sử dụng một trong hai. Không phải shebang env
hay shebang đường dẫn tuyệt đối nói chung là 'tốt hơn'. ' Một trong hai có thể khiến bạn gặp rắc rối khi sử dụng sai ngữ cảnh
Khi ai đó nói 'bạn nên sử dụng' hoặc 'một cách tốt hơn sẽ là', bạn luôn cần xem xét bối cảnh, trường hợp sử dụng của họ và những đánh đổi mà họ chấp nhận. Bạn cần hiểu các công cụ để sử dụng chúng hiệu quả