Hashbang thích hợp cho các tập lệnh Node.js


95

Tôi đang cố gắng tạo một tập lệnh cho node.js sẽ hoạt động trong nhiều môi trường. Riêng đối với tôi, tôi đang chuyển đổi qua lại giữa OS X và Ubuntu. Trước đây, Node được cài đặt dưới dạng node, nhưng trong phần sau, nó là nodejs. Ở đầu tập lệnh của tôi, tôi có thể có:

#!/usr/bin/env node

hoặc là

#!/usr/bin/env nodejs

Tôi muốn tập lệnh chạy dưới dạng tệp thực thi cho cả hai môi trường miễn là nút được cài đặt hơn là có nút này hoặc nút kia phải chỉ định lệnh ( ./script-name.jsso với node script-name.js).

Có cách nào để chỉ định một hashbang dự phòng hoặc một hashbang tương thích trong cả hai trường hợp cho node.js không?


bạn có thể tạo một tập lệnh shell của wrapper để gọi tập lệnh của mình, điều này sẽ cố gắng tìm ra nơi sống của nút và nó được gọi là gì.
Doon

4
Rất nhiều đề xuất trong câu trả lời này trên trang web Unix - unix.stackexchange.com/questions/65235/…
sargant

Tôi có một kịch bản nodejs rằng tôi đã thay đổi từ #!/usr/bin/nodeđến #!/usr/bin/nodejskhi tôi nâng cấp từ Ubuntu 12.04 đến 12.10. Và nó được gọi từ một trình bao bọc để kiểm tra cả hai. Để thảo luận về vụ #!/usr/bin/envhack, hãy xem câu hỏi nàycâu trả lời của tôi .
Keith Thompson

Có đề xuất TC39 trong Giai đoạn 3 được gọi là "Hashbang Grammar" nhằm mục đích độc lập các hashbang đã sử dụng: github.com/tc39/proposal-hashbang
M. Twarog

Câu trả lời:


151

Nếu tập lệnh của bạn dành cho các nhà phát triển Node sử dụng, bạn hoàn toàn chỉ nên sử dụng

#!/usr/bin/env node

và không cần cố gắng tương thích với những người chỉ cài đặt Node là nodejs.

Cơ sở lý luận:

  • Đó là điều mà những đứa trẻ tuyệt vời đang làm, và nếu bạn không làm điều đó, bạn cũng không thú vị. Các dự án nút chính như jshint , karma , bower , và thậm chí là npm chỉ đơn giản sử dụng #!/usr/bin/env nodelàm shebang cho các tập lệnh thực thi của chúng.
  • Bởi vì những đứa trẻ tuyệt vời đang làm điều đó, bất kỳ ai làm việc với Node trên Ubuntu đều thiết lập /usr/bin/nodemột liên kết tượng trưng nodejs. Có nhiều hướng dẫn về cách thực hiện điều này ở đây trên Stack Overflow và trên toàn bộ web. Thậm chí còn nodejs-legacycó gói có mục đích toàn bộ là tạo liên kết tượng trưng này cho bạn. Những người sử dụng Node biết cách khắc phục sự cố này trên Ubuntu, và họ phải làm thế nào nếu họ muốn sử dụng khá nhiều phần mềm từng được viết bằng Node.
  • Vấn đề dường như không còn tồn tại trên Ubuntu 14.04; Tôi vừa xóa Node và chạy một apt-get install nodejsvà nó được tạo /usr/bin/nodedưới dạng liên kết biểu tượng /etc/alternatives/node. Tôi nghi ngờ những người bị ảnh hưởng bởi vấn đề này là một thiểu số đang thu hẹp lại.

Ngay cả khi bạn đang nhắm mục tiêu đến những người mù chữ Node, bạn vẫn có thể muốn sử dụng #!/usr/bin/env node, có thể thêm nhu cầu có thể tạo liên kết biểu tượng thủ công hoặc cài đặt nodejs-legacygói vào tài liệu cài đặt của bạn nếu bạn thấy cần thiết. Lưu ý rằng nếu ai đó có nodejsnhưng không nodecó sẵn cố gắng chạy chương trình của bạn với shebang ở trên, họ sẽ thấy:

/ usr / bin / env: node: Không có tệp hoặc thư mục nào như vậy

Googling sẽ cung cấp cho họ bản sửa lỗi trong kết quả đầu tiên và nhiều lần trên trang đầu tiên.

Nếu bạn thực sự, thực sự muốn đảm bảo rằng người dùng có thể chạy phần mềm của bạn trên một hệ thống nodejscó sẵn nhưng nodekhông có (hoặc nodethực sự là chương trình Amateur Packet Radio Node ), thì bạn có thể sử dụng "hai dòng shebang" này. từ Unix & Linux Stack Exchange :

#!/bin/sh
':' //; exec "$(command -v nodejs || command -v node)" "$0" "$@"

console.log('Hello world!');

nhưng bạn có thực sự cần làm điều này khi hầu như không có ai khác trong thế giới Node không?


2
Nếu hỗ trợ cho nodejstệp thực thi được ưu tiên, bạn có thể thấy đẹp hơn một chút khi sử dụng shebang với #!/bin/sh//bin/false || exec "$(command -v nodejs || command -v node)" "$0".
lennartcl

2
Lưu ý rằng bạn không thể chuyển các đối số cho nút trên Linux , chẳng hạn như --experimental-modules, nếu bạn sử dụng envdòng shebang này . Có nhiều hack xung quanh, nhưng chúng xấu xí .
Dan Dascalescu
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.