Perché il mio LD_LIBRARY_PATH ottiene un terminale di avvio non impostato?


8

Ho uno script di shell per impostare alcune variabili di ambiente e avviare qualsiasi programma che invio come argomento:

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

$@

Quando uso questo per chiamare bashad esempio funziona:

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

Quando lo uso per chiamare un terminale ( xterm, aterm, ...) il mio LD_LIBRARY_PATHottiene non impostato:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Perché succede? Come posso fermarlo? (Sto eseguendo Debian 5.0)

Aggiornare

Il mio terminale non chiama bash come login:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHnon compare in nessuno dei file di avvio di bash (a parte .bash_history e ~ / .profile non esistono.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 

Qualcuno di quei file di avvio chiama il comando "source" o "." comando per inserire altri script di avvio? In tal caso, uno di quelli potrebbe essere il colpevole.
Kevin Panko,

Non risponde alla tua domanda, ma la cosa davvero buona sarebbe sbarazzarti della necessità di LD_LIBRARY_PATH (motivi: 1 2 3 ). Ad esempio, potresti modificare /etc/ld.so.conf o compilare qualsiasi libreria definita dall'utente che hai in ~ / local in modo che sappiano dove trovare le loro librerie (vedi i link che ho fornito).
DevSolar,

Risposte:


9

È molto probabile che il binario terminale si setgidraggruppi utmp. Setuid e setgid binaries non impostati LD_LIBRARY_PATHper motivi di sicurezza; vedi ld.so(8):

Le librerie condivise necessarie richieste dal programma vengono ricercate nel seguente ordine

  • Utilizzo della variabile d'ambiente LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHper i programmi a.out). Tranne se l'eseguibile è un binario setuid / setgid, nel qual caso viene ignorato.

4

Nel terminale (xterm, aterm ecc.), Controlla come è stata invocata la shell: una shell di login mostrerà "-bash" e una shell non di login mostrerà "bash" quando chiami echo $0.

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

Una shell bash di login leggerà quanto segue nell'ordine:

  1. / Etc / profile
  2. ~ / .Bash_profile
  3. ~ / .Bash_login
  4. ~ / .Profile

Controllare se esiste uno di questi file e se ripristinano la variabile. Dovrai anche seguire tutti i file che questi file includono.

Se bash non viene invocato come shell di login, leggerà comunque i file seguenti se si determina che è una shell interattiva.

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

Un modo semplice per determinare il tipo di shell bash invocato è quello di definire rispettivamente il tuo .bash_profile e .bashrc ed echo "Login shell" e "Interactive shell".

Una volta che conosci il tipo di shell che viene invocato, hai la possibilità di aggiungere il tuo script al file .bashrc o .bash_profile nella tua home directory. In alternativa, è possibile disabilitare il ripristino di LD_LIBRARY_PATH.

Nota che se il tuo .bashrc o .bash_profile è protetto da una guardia simile a quella qui sotto, potresti dover chiamare il tuo script al di fuori di esso:

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

fi

Tali protezioni vengono normalmente posizionate per impedire che uno script venga fornito più volte in una sessione.

Modifica: se sta dimostrando tedio rintracciare dove viene ripristinata la variabile e hai accesso a / etc / profile o /etc/bash.bashrc, ad esempio, puoi aggiungere temporaneamente "set -x" nella parte superiore del script per vedere tutti i comandi che vengono eseguiti. L'output sarà piuttosto dettagliato, quindi prima fai un "set -x" nella tua shell ed esegui alcuni comandi in modo da sapere cosa aspettarti.


+1 Grazie per le informazioni. Ho aggiornato il mio PO in risposta alla tua risposta.
kjfletch,

Vedi lo stesso comportamento se inserisci una nuova shell bash sullo stesso terminale digitando bash? A proposito, dovrai anche controllare i file che vengono chiamati all'interno di /etc/bash.bashrc e / etc / profile - uno di questi potrebbe disinserire la variabile. In alternativa, utilizzare l' set -xopzione di debug per ottenere un dump di tutto ciò che viene fatto dal momento in cui viene creata la shell.

Il set -xdump non fa riferimento a LD_LIBRARY_PATH. Fantasma non impostato.
kjfletch,

4

bash utilizzerà diversi script di avvio a seconda di come è stato avviato. Esistono sette modi diversi per avviarlo, ma i più importanti sono shell di accesso e shell interattive non di accesso.

Controlla il manuale di bash per maggiori dettagli. Sospetto che il profilo / etc / o il file ~ / .bash_profile stiano facendo qualcosa per ripristinare la variabile LD_LIBRARY_PATH.


Modifica: penso che tu abbia fatto tutto il possibile per dimostrare che bash non ha alcuno script di avvio che disinserisce LD_LIBRARY_PATH. È tempo di mettere in evidenza i grandi cannoni.

Il seguente comando visualizzerà l'intero ambiente all'avvio di ogni processo, da bash a xterm e qualsiasi altra cosa sia coinvolta: probabilmente otterrai una grande quantità di output, quindi salvare l'output in un file è una buona idea .

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

Ora, il file strace_output.txt mostrerà ogni chiamata di sistema effettuata dal tuo script e ogni processo figlio, e sarai in grado di vedere quale processo è stato l'ultimo ad avere LD_LIBRARY_PATH prima che venisse rimosso.


2

(Questa domanda è molto vecchia, ma ho riscontrato lo stesso problema e sto documentando la soluzione per la posteriorità :)

Ho avuto questo problema con lo schermo GNU (il terminale multiplexer), ma può anche accadere con un terminale normale. Teddy aveva ragione nel mio caso, lo schermo ha impostato la guida.

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

La mia soluzione era salvare LD_LIBRARY_PATH prima dell'esecuzione e ripristinarlo in seguito. Quindi ho creato un wrapper ~ / bin / screen (metti ~ / bin su PATH), con i seguenti contenuti:

#!/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 "$@"

e poi lo ha reso eseguibile con chmod +x ~/bin/screen. Potrebbe essere necessario aprire una nuova shell per farlo ritirare il wrapper.

Quindi ho aggiunto quanto segue a ~ / .bashrc. Ricorda che ~ / .bashrc viene fornito ogni volta che avvii bash, a differenza di ~ / .bash_profile che viene fornito solo al momento dell'accesso (di solito all'avvio o quando accedi tramite 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

Ora screen (o aterm, xterm, ... basta sostituirlo sopra) dovrebbe conservare $ LD_LIBRARY_PATH come desiderato.


Puoi anche ripristinare LD_LIBRARY_PATHin .screenrc(invece di .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"seguito daunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp

0

Sembra che tu abbia un file .bashrc (o equivalente) nella tua home directory che definisce questa variabile. Non conosco molti più dettagli però.

Modifica Ok, dato che avviare bash funziona, suppongo che non sia .bashrc. Ma forse qualche altro file di configurazione che viene eseguito allo stesso modo, quando si avvia xterm o aterm.


Questo era il mio pensiero originale. Dopo molte ricerche non c'è nulla da trovare. Ho il vantaggio di avere un $ HOME molto pulito (NUOVO).
kjfletch,

0

La maggior parte dei sistemi a finestre ricreano il processo di accesso quando avviano una finestra terminale, principalmente perché la finestra terminale diventa figlia del gestore delle finestre e non della shell di avvio.

Quindi, inseriscilo nel tuo .bash_profile o .bashrc se vuoi che venga visualizzato in una nuova finestra.

Un'altra alternativa è usare xterm (ad esempio) un argomento per eseguire uno script di avvio. Non uscire alla fine di quello script ....


Dovrò ricorrere a questo, credo. Probabilmente sorgente le mie variabili d'ambiente sia in .xinitrc in modo che il mio gestore di finestre le abbia, sia in .bashrc in modo che le finestre del mio terminale le abbiano.
kjfletch,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.