Mengapa 'yang' memberikan hasil yang salah?

0

Saya mengeksekusi di shell Ubuntu 12,04 perintah berikut:

sudo bash -c "echo $PATH; which python"

yang menampilkan sesuatu seperti

/home/me/env/develop/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
/usr/bin/python

dan perintah berikut

ls /home/me/env/develop/bin

displys (amont others)

python

Menurut manhalaman whichperintah mencari executable yang diberikan di semua jalur yang didefinisikan dalam PATH. The manhalaman tidak ketat menentukan 'pesanan' dari pencarian, namun biasanya ia pergi dari awal sampai akhir PATHvariabel lingkungan.

Sekarang, path /home/me/env/develop/binberisi python executable (mode diatur dengan benar, bukan tautan simbolik), yang juga merupakan path pertama di PATH. Tetapi whichperintah menampilkan lokasi yang sama sekali berbeda!

Mengapa demikian? Saya melakukan sesuatu yang bodoh? Apakah ini secara ajaib ada hubungannya sudo? Apakah ini bug?

Alex
sumber
gunakan bash builtin typesebagai gantiwhich
glenn jackman

Jawaban:

2

Itu bukan bug. $PATHdalam tanda kutip ganda akan diperluas oleh shell Anda bash -cbahkan sebelum melihatnya.

Ini artinya, Anda akan benar-benar menjalankan:

sudo bash -c "echo /home/me/env/develop/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games; which python"

Tes kecil:

$ foo="hello"
$ sudo bash -c "echo $foo"
hello

Untuk sampai ke akar masalah Anda, jalankan:

sudo bash -c 'echo $PATH; which python'

Ini tidak akan diperluas $PATHsebelumnya.

Solusi untuk masalah jalur Anda adalah dengan menetapkan jalur di Anda .bashrcalih-alih .bash_profile— itu adalah jika saya berasumsi jalur Anda ditetapkan dengan benar di sana — sehingga itu dimuat bahkan untuk shell non-login (seperti pada bash -c). Atau Anda jalankan bash -lcagar menjalankan shell login sebagai gantinya, yang akan memuat .bash_profile.

slhck
sumber