Perintah env Linux: mengatur lingkungan untuk satu program

env adalah perintah GNU Coreutils yang digunakan untuk memeriksa variabel lingkungan atau untuk menjalankan perintah sambil menambahkan, mengubah, atau menghapus beberapa variabel lingkungan. Ini sangat berguna ketika Anda ingin memberikan lingkungan yang berbeda ke proses tertentu tanpa mengubah shell saat ini secara langsung.

Saat dijalankan tanpa argumen, ini mencetak lingkungan yang sedang dilewati, tetapi jika Anda hanya perlu melihatnya, printenv membuat maksudnya lebih jelas. Tujuan utama dari env adalah "menjalankan perintah dalam lingkungan yang dimodifikasi."

Apa itu perintah env?

Sebuah proses mewarisi seperangkat variabel lingkungan dari proses induknya. env membuat lingkungan baru berdasarkan set ini dengan menambahkan atau menghapus variabel dan kemudian mengeksekusi perintah yang ditentukan. Perubahan ini dapat diteruskan ke proses anak yang dijalankan dan anak-anaknya, tetapi lingkungan shell asli tetap tidak berubah.

Sintaks Dasar

env [opsi] [nama=nilai] ... [perintah [argumen] ...]

Jika tidak ada perintah yang ditentukan, ini mencetak lingkungan yang dihasilkan.

env
env | sort

Karena variabel lingkungan dapat menyertakan rahasia, jangan langsung memposting output lengkap di postingan, permintaan dukungan, atau log publik.

Mengatur variabel lingkungan untuk satu perintah

Untuk latihan, buat direktori baru dan simpan isi berikut sebagai start.sh. Skrip hanya menampilkan nilai contoh dan membedakan DEBUG kosong dari yang tidak ada; tidak menjalankan server.

#!/usr/bin/env bash
printf 'APP_ENV=%s\n' "${APP_ENV-tidak disetel}"
if [ "${DEBUG+x}" = x ]; then
  printf 'DEBUG ada: [%s]\n' "$DEBUG"
else
  printf '%s\n' 'DEBUG tidak ada'
fi

Jalankan chmod u+x start.sh lalu env APP_ENV=production ./start.sh; keluaran memuat APP_ENV=production. Buat names.txt berisi satu nama per baris sebelum mencoba env LC_ALL=C sort names.txt. LC_ALL=C mengalahkan kategori lokal dan LANG lain untuk pengurutan ini.

APP_ENV dan LC_ALL pada pemanggilan tersebut hanya berlaku untuk program anak. Shell induk tetap mempertahankan nilai sebelumnya. Jika APP_ENV semula tidak diekspor, pemeriksaan berikut tidak menampilkan nilai dan mengembalikan status gagal; jika sudah ada, nilai lamanya tetap terlihat.

printenv APP_ENV

Anda dapat menentukan beberapa variabel secara berurutan dari kiri ke kanan.

env HOST=127.0.0.1 PORT=8080 DEBUG=1 ./server

./server adalah placeholder untuk program Anda sendiri, bukan file yang dibuat oleh latihan. Jalankan hanya jika program dan perilakunya sudah Anda kenal; env tidak membuka port dengan sendirinya.

Perbandingan antara pernyataan penugasan di shell saat ini dan env

Dalam shell gaya POSIX, Anda dapat mengatur lingkungan untuk sebuah perintah dengan langsung menempatkannya di depan name=value.

LC_ALL=C sort names.txt
env LC_ALL=C sort names.txt

Dalam kasus sederhana, hasil dari kedua cara ini serupa. env berguna ketika Anda membutuhkan fitur tambahan seperti membersihkan lingkungan, menghapus variabel, mengubah direktori kerja, atau mencari interpreter skrip.

Menjalankan dengan lingkungan yang dibersihkan menggunakan -i

env -i /usr/bin/printenv

-i atau --ignore-environment mengabaikan lingkungan yang ada dan memulai dari yang kosong. Ini berguna untuk pengujian reproduksibilitas atau menemukan dependensi lingkungan yang tersembunyi, tetapi juga dapat menghapus PATH, HOME, locale, dan variabel terkait autentikasi.

Anda dapat secara eksplisit menambahkan kembali hanya variabel yang diperlukan untuk dijalankan.

env -i PATH=/usr/bin:/bin HOME="$HOME" LANG=C /usr/bin/env

Jika PATH hilang, perilaku pencarian bergantung pada sistem; jangan bergantung pada jalur implisit. Gunakan jalur absolut atau atur PATH secara eksplisit. HOME="$HOME" diperluas oleh shell pemanggil sebelum env berjalan. Lingkungan kosong juga bukan sandbox atau pembatas akses file dan jaringan.

Menghapus hanya variabel tertentu -u

env -u HTTP_PROXY curl https://example.com
env --unset=DEBUG ./start.sh

-u name atau --unset=name menghapus variabel dari lingkungan program anak. Contoh curl memerlukan curl dan akses jaringan; menghapus HTTP_PROXY saja tidak menonaktifkan semua proxy, karena curl dapat memakai variabel lain seperti https_proxy, HTTPS_PROXY atau ALL_PROXY.

Menetapkan variabel ke string kosong berbeda dengan menghapusnya.

env DEBUG= ./start.sh
env -u DEBUG ./start.sh

Tergantung pada program, "variabel ada tetapi nilainya kosong" dan "variabel tidak ada" dapat ditangani secara berbeda.

Menjalankan di direktori yang berbeda -C

env -C /srv/app ./start.sh
env --chdir=/srv/app APP_ENV=production ./start.sh

GNU env -C atau --chdir berpindah ke direktori yang ditentukan dan kemudian menjalankan perintah. Direktori kerja shell saat ini tidak berubah. Karena opsi ini adalah ekstensi GNU, periksa dukungan dalam skrip yang memerlukan portabilitas.

Contoh tersebut mengasumsikan /srv/app ada dan berisi start.sh yang dapat dijalankan. Untuk latihan lokal, ganti direktori itu dengan jalur absolut direktori uji Anda. Jika perpindahan gagal, program tidak dijalankan.

Opsi yang sering digunakan

Opsi Deskripsi
-i, --ignore-environment Memulai dengan lingkungan bersih mengabaikan lingkungan yang ada.
-u name, --unset=name Menghapus variabel yang ditentukan dari lingkungan.
-C directory, --chdir=directory Berpindah ke direktori yang ditentukan sebelum menjalankan perintah.
-S string, --split-string=string Memisahkan string menjadi beberapa argumen. Utamanya digunakan untuk melewatkan beberapa argumen dalam shebang.
-0, --null Saat mencetak lingkungan, memisahkan entri dengan karakter NUL alih-alih baris baru.

Opsi yang didukung mungkin berbeda tergantung pada versi Coreutils. Silakan periksa baik env --help distribusi Anda maupun manual resmi.

Menggunakan /usr/bin/env di baris pertama skrip

Dalam shebang skrip, Anda dapat menggunakan interpreter yang ditemukan melalui PATH.

#!/usr/bin/env python3
print("Halo dari Python")

Simpan sebagai hello.py dengan baris baru LF. Pada Linux yang mendukung shebang dan memiliki python3 di PATH, jalankan chmod u+x hello.py lalu ./hello.py; hasilnya Halo dari Python. Menjalankan python3 hello.py langsung juga berfungsi, tetapi tidak menguji pencarian interpreter melalui shebang.

Ini nyaman digunakan di lingkungan pengembangan di mana interpreter mungkin diinstal di jalur yang berbeda pada sistem yang berbeda. Namun, karena ia mengeksekusi program pertama yang ditemukan di PATH saat ini, untuk layanan sistem di mana keamanan dan kemampuan reproduksi penting, jalur absolut yang diverifikasi mungkin lebih tepat.

Meneruskan beberapa argumen interpreter

Di lingkungan di mana GNU Coreutils mendukung -S, string shebang dapat dipisahkan menjadi beberapa argumen.

#!/usr/bin/env -S python3 -I
import sys
print(sys.flags.isolated)

Simpan contoh kedua sebagai isolated.py, beri izin eksekusi dan jalankan ./isolated.py. Hasil yang diharapkan adalah 1. Opsi Python -I mengaktifkan mode terisolasi, termasuk mengabaikan variabel PYTHON* dan direktori paket pengguna; ini tidak sama dengan mengosongkan seluruh lingkungan proses.

-S tidak didukung oleh env di semua sistem operasi. Periksa sistem distribusi target, dan jika portabilitas tinggi diperlukan, pertimbangkan untuk menangani argumen interpreter di dalam skrip.

Perbedaan antara variabel shell dan variabel lingkungan

Hanya karena Anda membuat variabel di shell tidak berarti variabel tersebut otomatis diteruskan ke proses anak.

(
unset LOCAL_ONLY
LOCAL_ONLY=value
printenv LOCAL_ONLY

export LOCAL_ONLY
printenv LOCAL_ONLY
)

Hanya variabel yang export yang disertakan dalam lingkungan program yang baru dijalankan. env beroperasi berdasarkan lingkungan yang diteruskan kepadanya, bukan seluruh variabel shell saat ini.

Contoh di atas memakai subshell agar pengaturan terminal tetap terjaga. Pemeriksaan pertama tidak mencetak nilai; setelah export, pemeriksaan kedua mencetak value.

Perbandingan antara env dan printenv

Kategori env printenv
Tujuan Utama Menjalankan perintah dalam lingkungan yang dimodifikasi Memeriksa nilai dari variabel lingkungan
Cetak seluruh lingkungan Mungkin jika perintah dihilangkan Mungkin jika nama variabel dihilangkan
Periksa variabel tertentu Karena tidak ada format khusus, filter diperlukan. Langsung ditanyakan seperti printenv HOME.
Tambahkan atau hapus variabel Didukung. Tidak didukung.
Jalankan perintah Didukung. Tidak didukung.

Tindakan pencegahan untuk keamanan dan operasi

  • Jangan mencatat seluruh lingkungan termasuk token, kata sandi, dan jalur kunci pribadi.
  • Anda harus mempertimbangkan kemungkinan mengekspose rahasia ke riwayat shell atau informasi proses jika Anda menulis nilai rahasia langsung di env NAME=VALUE command.
  • Menggunakan env -i dapat menghasilkan perilaku yang berbeda karena jalur sertifikat, lokal, dan variabel proxy mungkin hilang.
  • /usr/bin/env di shebang dipengaruhi oleh PATH, jadi pastikan Anda dapat mempercayai eksekutor dan lingkungan.
  • Untuk lingkungan layanan, gunakan fungsi pengaturan lingkungan eksplisit dari manajer layanan kapan pun memungkinkan.

Pertanyaan yang Sering Diajukan

Apakah variabel yang disetel dengan env tetap ada di terminal saat ini?

Tidak. env NAME=VALUE command hanya mengubah lingkungan untuk perintah yang dijalankan dan tidak memodifikasi variabel shell induk.

Apa perbedaan antara env dan export?

export menandai variabel shell saat ini agar diteruskan ke proses anak yang dijalankan kemudian. env cocok untuk menyiapkan lingkungan untuk eksekusi perintah tunggal.

Perintah tidak dapat ditemukan di env -i.

Ini mungkin karena PATH yang ada juga telah dihapus. Gunakan path absolut dari executable atau atur secara eksplisit PATH yang diperlukan.

Artikel terkait dan dokumentasi resmi