Skrip yang akan dieksekusi oleh penerjemah biasanya memiliki baris shebang di bagian atas untuk memberi tahu OS cara menjalankannya.
Jika Anda memiliki skrip bernama foo
yang baris pertamanya adalah #!/bin/sh
, sistem akan membaca baris pertama itu dan menjalankan yang setara dengan /bin/sh foo
. Karena itu, sebagian besar penerjemah diatur untuk menerima nama file skrip sebagai argumen baris perintah.
Nama juru bahasa setelah #!
harus jalur lengkap; OS tidak akan mencari Anda $PATH
untuk menemukan juru bahasa.
Jika Anda memiliki skrip untuk dieksekusi node
, cara yang jelas untuk menulis baris pertama adalah:
#!/usr/bin/node
tetapi itu tidak berfungsi jika node
perintah tidak diinstal di /usr/bin
.
Sebuah solusi umum adalah dengan menggunakan env
perintah (yang tidak benar-benar dimaksudkan untuk tujuan ini):
#!/usr/bin/env node
Jika skrip Anda dipanggil foo
, OS akan melakukan hal yang sama dengan
/usr/bin/env node foo
The env
perintah mengeksekusi perintah lain yang namanya diberikan pada baris perintah, melewati argumen berikut untuk perintah itu. Alasan digunakan di sini adalah untuk env
mencari $PATH
perintah. Jadi jika node
dipasang di /usr/local/bin/node
, dan Anda memiliki /usr/local/bin
di Anda $PATH
, yang env
perintah akan memanggil/usr/local/bin/node foo
.
Tujuan utama dari env
perintah ini adalah untuk menjalankan perintah lain dengan lingkungan yang dimodifikasi, menambahkan atau menghapus variabel lingkungan yang ditentukan sebelum menjalankan perintah. Tetapi tanpa argumen tambahan, itu hanya menjalankan perintah dengan lingkungan yang tidak berubah, yang Anda butuhkan dalam kasus ini.
Ada beberapa kelemahan dari pendekatan ini. Sebagian besar sistem mirip Unix modern memilikinya /usr/bin/env
, tetapi saya bekerja pada sistem yang lebih lama tempat env
perintah dipasang di direktori yang berbeda. Mungkin ada batasan pada argumen tambahan yang dapat Anda berikan menggunakan mekanisme ini. Jika pengguna tidak memiliki direktori yang berisi node
perintah di $PATH
, atau memiliki beberapa perintah berbeda yang dipanggil node
, maka ia dapat menjalankan perintah yang salah atau tidak berfungsi sama sekali.
Pendekatan lainnya adalah:
- Gunakan
#!
garis yang menentukan jalur lengkap kenode
perintah itu sendiri, memperbarui skrip sesuai kebutuhan untuk sistem yang berbeda; atau
- Panggil
node
perintah dengan skrip Anda sebagai argumen.
Lihat juga pertanyaan ini (dan jawaban saya ) untuk diskusi lebih lanjut tentang #!/usr/bin/env
triknya.
Kebetulan, di sistem saya (Linux Mint 17.2), itu diinstal sebagai /usr/bin/nodejs
. Menurut catatan saya, itu berubah dari /usr/bin/node
ke /usr/bin/nodejs
antara Ubuntu 12.04 dan 12.10. The #!/usr/bin/env
trick tidak akan membantu dengan itu (kecuali jika Anda menyiapkan symlink atau yang serupa).
UPDATE: Komentar oleh mtraceur mengatakan (diformat ulang):
Solusi untuk masalah nodejs vs node adalah memulai file dengan enam baris berikut:
#!/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
*/
Ini pertama-tama akan mencoba nodejs
dan kemudian mencoba node
, dan hanya mencetak pesan kesalahan jika keduanya tidak ditemukan. Penjelasan berada di luar cakupan komentar ini, saya hanya meninggalkannya di sini jika itu membantu siapa pun mengatasi masalah karena jawaban ini memunculkan masalah.
Saya belum pernah menggunakan NodeJS belakangan ini. Harapan saya adalah bahwa masalah nodejs
vs. node
telah diselesaikan selama bertahun-tahun sejak saya pertama kali memposting jawaban ini. Di Ubuntu 18.04, nodejs
paket diinstal /usr/bin/nodejs
sebagai symlink ke /usr/bin/node
. Pada beberapa OS sebelumnya (Ubuntu atau Linux Mint, saya tidak yakin yang mana), ada nodejs-legacy
paket yang disediakan node
sebagai symlink nodejs
. Tidak ada jaminan bahwa saya memiliki semua detail dengan benar.
node