Mengapa LD_LIBRARY_PATH saya mendapatkan terminal peluncuran yang belum disetel?

8

Saya memiliki skrip shell untuk mengatur beberapa variabel lingkungan dan meluncurkan program apa pun yang saya kirim sebagai argumen:

export PATH=$HOME/local/bin:$PATH
export LD_LIBRARY_PATH=$HOME/local/lib:$LD_LIBRARY_PATH
export TESTER="MY TEST VAR"

$@

Ketika saya menggunakan ini untuk memanggil bashmisalnya itu berfungsi:

kjfletch@flatbed:~$ envrun.sh bash
kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH
/home/kjfletch/local/lib:
kjfletch@flatbed:~$ echo $TESTER
MY TEST VAR

Ketika saya menggunakannya untuk memanggil terminal ( xterm, aterm, ...) saya LD_LIBRARY_PATHmendapat unset:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Mengapa ini terjadi? Bagaimana saya bisa menghentikan ini? (Saya menjalankan Debian 5.0)

Memperbarui

Terminal saya tidak memanggil bash sebagai login:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHtidak muncul di salah satu file startup bash (selain dari .bash_history dan ~ / .profile tidak ada.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
sumber
Apakah ada file startup yang memanggil perintah "sumber" atau "." perintah untuk membawa skrip startup lain? Jika demikian, salah satunya mungkin pelakunya.
Kevin Panko
Tidak menjawab pertanyaan Anda, tetapi hal yang sangat bagus adalah menyingkirkan kebutuhan akan LD_LIBRARY_PATH (alasan: 1 2 3 ). Anda bisa, misalnya, mengedit /etc/ld.so.conf, atau mengkompilasi apa pun lib yang ditentukan pengguna yang Anda miliki di ~ / lokal dengan cara yang mereka tahu di mana menemukan perpustakaan mereka (lihat tautan yang saya berikan).
DevSolar

Jawaban:

9

Biner terminal kemungkinan besar setgiduntuk dikelompokkan utmp. Binari Setuid dan setgid tidak disetel LD_LIBRARY_PATHuntuk alasan keamanan; lihat ld.so(8):

Pustaka bersama yang diperlukan yang dibutuhkan oleh program dicari dalam urutan berikut

  • Menggunakan variabel lingkungan LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHuntuk program a.out). Kecuali jika executable adalah biner setuid / setgid, dalam hal ini diabaikan.
Teddy
sumber
4

Di terminal (xterm, aterm dll), periksa bagaimana shell dipanggil: Shell login akan menampilkan "-bash" dan shell non-login akan menampilkan "bash" saat Anda menelepon echo $0.

$ echo $0
-bash
$ bash
$ echo $0
bash

Shell bash login akan membaca secara berurutan:

  1. / etc / profile
  2. ~ / .bash_profile
  3. ~ / .bash_login
  4. ~ /. profil

Periksa apakah ada file-file ini, dan apakah mereka mereset variabel. Anda juga harus mengikuti file apa pun yang termasuk dalam file ini.

Jika bash tidak dipanggil sebagai shell login, ia masih akan membaca file di bawah ini jika ditentukan sebagai shell interaktif.

  1. /etc/bash.bashrc
  2. ~ / .bashrc

Cara sederhana untuk menentukan jenis bash shell yang dipanggil adalah dengan menentukan .bash_profile dan .bashrc Anda, dan gema masing-masing "shell masuk" dan "shell interaktif".

Setelah Anda mengetahui jenis shell yang dipanggil, Anda memiliki opsi untuk menambahkan skrip Anda ke file .bashrc atau .bash_profile di direktori home Anda. Atau, Anda dapat menonaktifkan setel ulang LD_LIBRARY_PATH.

Perhatikan bahwa jika .bashrc atau .bash_profile Anda dilindungi oleh penjaga yang mirip dengan yang di bawah ini, Anda mungkin harus memanggil skrip Anda di luarnya:

if [ "X$BASH_SOURCED" != "XYES" ]; then
        export BASH_SOURCED=YES

fi

Penjaga seperti itu biasanya ditempatkan untuk mencegah agar skrip tidak bersumber beberapa kali dalam satu sesi.

Sunting: Jika terbukti membosankan untuk melacak di mana variabel sedang direset, dan Anda memiliki akses ke / etc / profile atau /etc/bash.bashrc misalnya, Anda dapat menambahkan sementara "set -x" di dekat bagian atas skrip untuk melihat semua perintah yang dijalankan. Outputnya akan sangat verbose, jadi pertama-tama lakukan "set -x" di shell Anda dan jalankan beberapa perintah sehingga Anda tahu apa yang diharapkan.


sumber
+1 Terima kasih atas informasinya. Saya telah memperbarui OP saya sebagai jawaban atas jawaban Anda.
kjfletch
Apakah Anda melihat perilaku yang sama jika Anda memasukkan bash shell baru di terminal yang sama dengan mengetikkan bash? Btw, Anda juga perlu memeriksa file yang dipanggil dari dalam /etc/bash.bashrc dan / etc / profile - salah satunya mungkin menghapus variabel. Atau, gunakan set -xopsi debug untuk mendapatkan dump dari semua yang dilakukan dari saat shell dibuat.
The set -xDump tidak membuat referensi ke LD_LIBRARY_PATH. Phantom tidak disetel.
kjfletch
4

bash akan menggunakan skrip start-up yang berbeda tergantung pada bagaimana permulaannya. Ada tujuh cara berbeda untuk memulainya, tetapi yang paling penting adalah shell login versus shell interaktif non-login.

Lihat manual bash untuk detail lebih lanjut. Saya menduga / etc / profile atau ~ / .bash_profile sedang melakukan sesuatu untuk mengatur ulang variabel LD_LIBRARY_PATH.


Sunting: Saya pikir Anda telah melakukan semua yang dapat Anda lakukan untuk menunjukkan bahwa bash tidak memiliki skrip startup yang menghapus LD_LIBRARY_PATH. Sudah waktunya untuk mengeluarkan senjata besar.

Perintah berikut akan menampilkan seluruh lingkungan saat setiap proses dimulai, dari bash ke xterm, dan hal lain yang terjadi - Anda mungkin akan mendapatkan sejumlah besar output, jadi menyimpan output ke file adalah ide yang bagus .

strace -v -f -e trace=process -o strace_output.txt envrun.sh xterm

Sekarang, file strace_output.txt akan menampilkan setiap panggilan sistem yang dibuat oleh skrip Anda dan setiap proses anak, dan Anda akan dapat melihat proses mana yang terakhir memiliki LD_LIBRARY_PATH sebelum dihapus.

Kevin Panko
sumber
2

(Pertanyaan ini sudah sangat lama, tetapi saya hanya mengalami masalah yang sama, dan saya mendokumentasikan solusi untuk posterioritas :)

Saya punya masalah dengan layar GNU (terminal multiplexer), tetapi bisa juga terjadi dengan terminal biasa. Teddy benar dalam kasus saya, layar memiliki setguid set.

$ ls -l /usr/bin/screen
-rwxr-sr-x 1 root 84 361016 Mar 30  2011 /usr/bin/screen
      ^

Solusi saya adalah menyimpan LD_LIBRARY_PATH sebelum eksekusi, dan mengembalikannya sesudahnya. Jadi saya membuat pembungkus ~ / nampan / layar (menaruh ~ / nampan di PATH), dengan konten berikut:

#!/bin/bash

# somehow, screen resets LD_LIBRARY_PATH.
# save it here, and restore it in .bashrc
export PRESERVE_LD_LIBRARY_PATH="$LD_LIBRARY_PATH"
/usr/bin/screen "$@"

dan kemudian membuatnya dapat dieksekusi dengan chmod +x ~/bin/screen. Anda mungkin harus membuka cangkang baru agar dapat mengambil bungkusnya.

Kemudian saya menambahkan yang berikut ke ~ / .bashrc. Ingat ~ / .bashrc bersumber setiap kali Anda memulai bash, tidak seperti ~ / .bash_profile yang hanya bersumber saat login (biasanya saat startup, atau ketika Anda login lebih dari ssh).

if [[ "$PRESERVE_LD_LIBRARY_PATH" != "" ]]; then
    export LD_LIBRARY_PATH="$PRESERVE_LD_LIBRARY_PATH"
    #echo "restored LD_LIBRARY_PATH"
    export -n PRESERVE_LD_LIBRARY_PATH
fi

Sekarang layar (atau aterm, xterm, ... ganti saja di atas) harus menyimpan $ LD_LIBRARY_PATH seperti yang diinginkan.

jdm
sumber
Anda juga dapat mengembalikan LD_LIBRARY_PATHdalam .screenrc(bukan .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"diikuti olehunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Sepertinya Anda memiliki beberapa file .bashrc (atau yang setara) di direktori home Anda yang mendefinisikan variabel ini. Saya tidak tahu lebih detail.

Sunting Ok, sejak mulai bash berfungsi, saya rasa bukan .bashrc. Tetapi mungkin beberapa file konfigurasi lain yang kebetulan dijalankan dengan cara yang sama, ketika Anda memulai xterm atau aterm.

Gnoupi
sumber
Ini adalah pemikiran asli saya. Setelah banyak pencarian, tidak ada yang dapat ditemukan. Saya mendapat manfaat memiliki $ HOME yang sangat bersih (BARU).
kjfletch
0

Sebagian besar sistem pembuatan jendela membuat ulang proses login ketika mereka meluncurkan jendela terminal, terutama karena jendela terminal menjadi anak manajer windowing bukan shell peluncuran.

Jadi, letakkan di .bash_profile atau .bashrc Anda jika Anda ingin itu muncul di jendela baru.

Alternatif lain adalah dengan memberikan xterm (misalnya) argumen untuk menjalankan skrip startup. Jangan keluar di akhir skrip itu ....

kmarsh
sumber
Saya harus menggunakan ini saya pikir. Saya mungkin akan sumber variabel lingkungan saya di kedua .xinitrc sehingga manajer jendela saya memilikinya, dan dalam .bashrc sehingga windows terminal saya akan memilikinya.
kjfletch