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 foo
có 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 node
lệnh không được cài đặt trong /usr/bin
.
Một giải pháp phổ biến là sử dụng env
lệ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 env
lệ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ó env
sẽ tìm kiếm $PATH
lệnh. Vì vậy, nếu node
được cài đặt trong /usr/local/bin/node
và bạn có /usr/local/bin
trong đó $PATH
, env
lệnh sẽ gọi /usr/local/bin/node foo
.
Mục đích chính của env
lệ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 env
lệ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 node
lệnh $PATH
hoặ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 node
chí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
node
lệ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/env
thủ 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/nodejs
giữa Ubuntu 12.04 và 12.10. Thủ #!/usr/bin/env
thuậ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ử nodejs
và sau đó thử node
và 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 đề nodejs
vs. 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, nodejs
gói cài đặt /usr/bin/nodejs
dướ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-legacy
gói được cung cấp node
dướ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