Bagaimana menjalankan program di lingkungan yang bersih di bash?

Jawaban:

127

Anda dapat melakukan ini dengan env:

env -i your_command

Bertentangan dengan komentar di bawah ini, ini benar - benar membersihkan lingkungan, tetapi tidak mencegah your_commandpengaturan variabel baru. Secara khusus, menjalankan shell akan menyebabkannya /etc/profileberjalan, dan shell mungkin memiliki beberapa pengaturan bawaan juga.

Anda dapat memeriksanya dengan:

env -i env

yaitu menghapus lingkungan dan kemudian mencetaknya. Output akan kosong.

am
sumber
4
Itu tidak sepenuhnya membersihkan lingkungan: echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shcetakan /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
l0b0
2
Namun, sepertinya ini adalah yang terdekat yang bisa Anda dapatkan - Sepertinya variabel suka PATH, PWDdan SHLVLdisetel secara otomatis oleh Bash. +1.
l0b0
3
@ I0b0: Lihat hasil edit saya.
ams
3
Variabel PATH dalam skrip komentator pertama tidak di lingkungan dan karenanya bukan variabel lingkungan. Bash rupanya menetapkan variabel shell regulernya sendiri yang disebut PATH jika tidak ada yang diekspor untuknya: env -i bash --norc -c "declare -p PATH"memberi declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.". Perhatikan "x" untuk diekspor (dan karena itu bagian dari lingkungan) jika Anda mengekspor sendiri: env -i bash --norc -c "export PATH; declare -p PATH"memberikandeclare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile
34

Lingkungan "bersih" bashmungkin ada bersama

$ env -i bash --noprofile --norc
  • The env -iperintah mengeksekusi perintah yang diberikan untuk itu pada baris perintah tanpa mentransfer setiap variabel lingkungan diekspor dari lingkungan shell lama ke lingkungan dari program dieksekusi.

  • The --noprofilepilihan berhenti bashdari membaca seluruh sistem atau shell inisialisasi pribadi skrip yang seharusnya dapat membaca untuk login shell.

  • The --norcpilihan berhenti bashdari membaca shell script inisialisasi pribadi yang seharusnya dapat dibaca untuk shell interaktif.

Kusalananda
sumber
Env saya tidak mengenali opsi itu.
Paulo Carvalho
@PauloCarvalho Sistem Anda tidak mendukung env -i? Sistem apa yang Anda pakai?
Kusalananda
Maaf, ini bekerja di shell. Saya mencoba memasukkannya ke dalam skrip dan entah bagaimana kesalahan itu terjadi.
Paulo Carvalho
@ PauloCarvalho Maaf, saya tidak bisa melihat perintah apa yang Anda ketikkan atau kesalahan apa yang Anda dapatkan.
Kusalananda
Hebat - hanya apa yang saya cari. envuntuk membersihkan lingkungan saya, dan --noprofileuntuk menghindari sumber / etc / profil dan teman-teman, dan --norcuntuk menghindari sumber ~ / .bashrc dan teman-teman.
Felipe Alvarez
28

env -i somecommandmenjalankan perintah di lingkungan kosong, seperti yang telah disebutkan oleh ams .

Banyak program bergantung pada beberapa variabel lingkungan penting, jadi Anda mungkin ingin mempertahankannya:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

Atau, Anda bisa masuk ke lingkungan waktu masuk yang kecil.

ssh localhost somecommand
Gilles
sumber
1
Bekerja ketika menjalankan perintah pada cmdline. Bagaimana saya menempatkan ini di shebang ?, sepertinya tidak berfungsi !
balki
Aneh, saya envtidak mendukung --pembatasan dan melakukan env -i FOO=bar -- envupaya untuk menjalankan perintah bernama --.
antak
@antak Itu seharusnya env -i -- FOO=bar env, sebenarnya. Salahku. Bukan berarti --itu berguna karena apa yang mengikutinya tidak dimulai dengan -.
Gilles
Tidak menyadari Anda selalu bisa ssh ke localhost, itu agak aneh. Apa gunanya kasing di sana.
Edgar Aroutiounian
@ EdgarAroutiounian Anda dapat SSH ke localhost jika menjalankan server SSH. Mengapa programmer harus melalui upaya melarangnya?
Gilles
4

Meskipun jawaban yang diterima benar, yang biasanya ingin Anda lakukan adalah:

env -i bash -l -c "printenv; and any other commands"

Ini memberi Anda bash kosong tapi fungsional (sama seperti yang Anda dapatkan saat masuk dalam mode non-interaktif). Ini misalnya mengatur bahasa, zona waktu, HOME, dll.

Marcin Raczkowski
sumber
Itu tidak bekerja karena env -imembersihkan HOME, yang berarti bash -ltidak dapat menemukan .bash_profiledll Anda . Jika Anda ingin shell seperti yang Anda dapatkan pada login baru, Anda perlu tipuan ekstra untuk ditetapkan HOMEterlebih dahulu.
Elliott Slaughter
Lihat jawaban ini: unix.stackexchange.com/a/451389/157340
Elliott Slaughter
1

Masalah dengan kebanyakan jawaban di sini adalah bahwa env -iClears HOME, sehingga bahkan jika Anda menjalankan bash -ldi dalam, itu akan tidak membaca Anda .bash_profiledll Jika apa yang Anda cari adalah shell yang bertindak sebagai jika Anda baru saja melakukan login segar, Anda Saya ingin ini sebagai gantinya:

env -i HOME="$HOME" bash -l -c 'your_command'

Contoh:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123
Elliott Slaughter
sumber
1
Perhatikan bahwa bashshell login akan berjalan .bash_loginatau .bash_profile. Untuk mendapatkan lingkungan yang bersih, gunakan --noprofile, atau atur HOMEke direktori yang tidak memiliki file-file itu. Saya kira itu tergantung pada apa yang Anda maksud dengan "bersih".
Kusalananda
1
Ya, jika Anda ingin shell dengan harfiah tidak ada di dalamnya, cukup ikuti jawaban asli dan melakukan env -i bash -c .... Jawaban ini khusus ketika Anda ingin shell yang sepertinya Anda baru saja melakukan login baru di mesin.
Elliott Slaughter
0

Untuk menjawab komentar balki (dan menjawab pertanyaan saya sendiri dalam proses :-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."
Coroos
sumber
Ketika saya mencoba ini di baris shebang saya di CentOS 7.6, saya mendapatkan kesalahan ini dari env:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ
Jika saya mengubah skrip untuk menggunakan argumen panjang --ignore-environmentmaka saya mendapatkan ini:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
ScottJ