Các tập lệnh sẽ được thực thi bởi một trình thông dịch thường có một dòng shebang ở trên cùng để cho hệ điều hành biết cách thực thi chúng.
Nếu bạn có một tập lệnh được đặt tên foocó dòng đầu tiên #!/bin/sh, hệ thống sẽ đọc dòng đầu tiên đó và thực thi tương đương với /bin/sh foo. Do đó, hầu hết các trình thông dịch được thiết lập để chấp nhận tên của một tệp kịch bản như một đối số dòng lệnh.
Tên thông dịch viên theo sau #!phải là một đường dẫn đầy đủ; hệ điều hành sẽ không tìm kiếm của bạn $PATHđể tìm thông dịch viên.
Nếu bạn có một tập lệnh được thực thi bởi node, cách rõ ràng để viết dòng đầu tiên là:
#!/usr/bin/node
nhưng điều đó không hoạt động nếu nodelệnh không được cài đặt trong /usr/bin.
Một giải pháp phổ biến là sử dụng envlệnh (không thực sự dành cho mục đích này):
#!/usr/bin/env node
Nếu tập lệnh của bạn được gọi foo, hệ điều hành sẽ hoạt động tương đương với
/usr/bin/env node foo
Các envlệnh thực thi lệnh khác có tên được đưa ra trên dòng lệnh của nó, đi qua bất kỳ đối số sau đây để lệnh đó. Lý do nó được sử dụng ở đây là nó envsẽ tìm kiếm $PATHlệnh. Vì vậy, nếu nodeđược cài đặt trong /usr/local/bin/nodevà bạn có /usr/local/bintrong đó $PATH, envlệnh sẽ gọi /usr/local/bin/node foo.
Mục đích chính của envlệnh là thực hiện một lệnh khác với môi trường đã sửa đổi, thêm hoặc bớt các biến môi trường đã chỉ định trước khi chạy lệnh. Nhưng không có đối số bổ sung, nó chỉ thực hiện lệnh với một môi trường không thay đổi, đó là tất cả những gì bạn cần trong trường hợp này.
Có một số hạn chế đối với cách tiếp cận này. Hầu hết các hệ thống giống Unix hiện đại đều có /usr/bin/env, nhưng tôi đã làm việc trên các hệ thống cũ hơn nơi envlệnh được cài đặt trong một thư mục khác. Có thể có những hạn chế về các đối số bổ sung mà bạn có thể vượt qua bằng cách sử dụng cơ chế này. Nếu người dùng không có thư mục chứa nodelệnh $PATHhoặc có một số lệnh khác được gọi node, thì nó có thể gọi sai lệnh hoặc hoàn toàn không hoạt động.
Các cách tiếp cận khác là:
- Sử dụng một
#!dòng chỉ định đường dẫn đầy đủ đến nodechính lệnh đó, cập nhật tập lệnh nếu cần cho các hệ thống khác nhau; hoặc là
- Gọi
nodelệnh với tập lệnh của bạn làm đối số.
Xem thêm câu hỏi này (và câu trả lời của tôi ) để thảo luận thêm về #!/usr/bin/envthủ thuật.
Ngẫu nhiên, trên hệ thống của tôi (Linux Mint 17.2), nó được cài đặt dưới dạng /usr/bin/nodejs. Theo ghi chú của tôi, nó đã thay đổi từ /usr/bin/nodeđến /usr/bin/nodejsgiữa Ubuntu 12.04 và 12.10. Thủ #!/usr/bin/envthuật sẽ không giúp được gì (trừ khi bạn thiết lập một liên kết biểu tượng hoặc một cái gì đó tương tự).
CẬP NHẬT: Một bình luận của mtraceur nói (đã định dạng lại):
Cách giải quyết cho vấn đề nodejs vs node là bắt đầu tệp với sáu dòng sau:
#!/bin/sh -
':' /*-
test1=$(nodejs --version 2>&1) && exec nodejs "$0" "$@"
test2=$(node --version 2>&1) && exec node "$0" "$@"
exec printf '%s\n' "$test1" "$test2" 1>&2
*/
Điều này đầu tiên sẽ thử nodejsvà sau đó thử nodevà chỉ in thông báo lỗi nếu cả hai đều không được tìm thấy. Lời giải thích nằm ngoài phạm vi của những nhận xét này, tôi chỉ để nó ở đây trong trường hợp nó giúp bất kỳ ai giải quyết vấn đề vì câu trả lời này đã đưa ra vấn đề.
Tôi đã không sử dụng NodeJS gần đây. Hy vọng của tôi là vấn đề nodejsvs. nodeđã được giải quyết trong những năm kể từ lần đầu tiên tôi đăng câu trả lời này. Trên Ubuntu 18.04, nodejsgói cài đặt /usr/bin/nodejsdưới dạng liên kết biểu tượng tới /usr/bin/node. Trên một số hệ điều hành trước đó (Ubuntu hoặc Linux Mint, tôi không chắc là cái nào), có một nodejs-legacygói được cung cấp nodedưới dạng liên kết tượng trưng nodejs. Không đảm bảo rằng tôi có tất cả các chi tiết đúng.
node