Dlaczego mój LD_LIBRARY_PATH dostaje rozłączony terminal uruchamiający?

8

Mam skrypt powłoki, aby skonfigurować niektóre zmienne środowiskowe i uruchomić dowolny program, który wysyłam jako argument:

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

$@

Kiedy używam tego, aby bashna przykład zadzwonić , działa:

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

Kiedy używam go nazwać terminal ( xterm, aterm...) My LD_LIBRARY_PATHdostaje rozbrojony:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

Dlaczego to się dzieje? Jak mogę to zatrzymać? (Używam Debian 5.0)

Aktualizacja

Mój terminal nie nazywa się bash jako login:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHnie pojawia się w żadnym z plików startowych bash (oprócz .bash_history i ~ / .profile nie istnieje.):

kjfletch@flatbed:~$ grep "LD" ~/.bash*
kjfletch@flatbed:~$ grep "LD" /etc/bash.bashrc 
kjfletch@flatbed:~$ grep "LD" /etc/profile 
kjfletch
źródło
Czy którykolwiek z tych plików startowych wywołuje polecenie „source” lub „.” polecenie, aby wprowadzić inne skrypty uruchamiania? Jeśli tak, przyczyną może być jeden z nich.
Kevin Panko
Nie odpowiada na twoje pytanie, ale naprawdę dobrą rzeczą byłoby pozbyć się potrzeby LD_LIBRARY_PATH (przyczyny: 1 2 3 ). Możesz na przykład edytować plik /etc/ld.so.conf lub skompilować dowolne biblioteki zdefiniowane przez użytkownika w ~ / local w taki sposób, aby wiedziały, gdzie znaleźć swoje biblioteki (zobacz linki, które podałem).
DevSolar,

Odpowiedzi:

9

Binarny terminal najprawdopodobniej setgidzostanie zgrupowany utmp. Pliki binarne Setuid i setgid są rozbrojone LD_LIBRARY_PATHze względów bezpieczeństwa; patrz ld.so(8):

Niezbędne biblioteki współdzielone potrzebne przez program są wyszukiwane w następującej kolejności

  • Korzystanie ze zmiennej środowiskowej LD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHdla programów a.out). Z wyjątkiem sytuacji, gdy plik wykonywalny jest plikiem binarnym setuid / setgid, w którym to przypadku jest ignorowany.
Miś
źródło
4

Sprawdź w terminalu (xterm, aterm itp.), W jaki sposób została wywołana powłoka: powłoka logowania wyświetli „-bash”, a powłoka nie zalogowana wyświetli „bash”, gdy zadzwonisz echo $0.

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

Powłoka bash logowania będzie czytać w następującej kolejności:

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

Sprawdź, czy któryś z tych plików istnieje i czy zresetują zmienną. Będziesz także musiał śledzić wszystkie pliki, które zawierają te pliki.

Jeśli bash nie zostanie wywołany jako powłoka logowania, nadal będzie czytał poniższe pliki, jeśli zostanie określony jako powłoka interaktywna.

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

Prostym sposobem na określenie rodzaju wywoływanej powłoki bash jest zdefiniowanie pliku .bash_profile i .bashrc oraz odtworzenie echa odpowiednio „Powłoki logowania” i „Powłoki interaktywnej”.

Po poznaniu rodzaju wywoływanej powłoki masz możliwość dodania skryptu do pliku .bashrc lub .bash_profile w katalogu domowym. Alternatywnie możesz wyłączyć resetowanie LD_LIBRARY_PATH.

Zauważ, że jeśli Twój .bashrc lub .bash_profile jest chroniony przez ochronę podobną do poniższej, być może będziesz musiał wywołać skrypt poza nim:

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

fi

Tacy strażnicy są zwykle umieszczani, aby zapobiec wielokrotnemu pozyskiwaniu skryptu podczas sesji.

Edycja: Jeśli udowodnisz, że śledzenie miejsca, w którym zmienna jest resetowana, i masz na przykład dostęp do / etc / profile lub /etc/bash.bashrc, możesz tymczasowo dodać „set -x” u góry skrypt, aby zobaczyć wszystkie polecenia, które zostaną wykonane. Wyjście będzie dość szczegółowe, więc najpierw wykonaj „set -x” w swojej powłoce i uruchom kilka poleceń, abyś wiedział, czego się spodziewać.


źródło
+1 dzięki za informację. Zaktualizowałem OP w odpowiedzi na twoją odpowiedź.
kjfletch
Czy widzisz to samo, jeśli wpiszesz nową powłokę bash na tym samym terminalu, wpisując bash? Przy okazji musisz także sprawdzić pliki, które są wywoływane z /etc/bash.bashrc i / etc / profile - jeden z nich może rozbroić zmienną. Alternatywnie, użyj set -xopcji debugowania, aby uzyskać zrzut wszystkiego, co zostanie zrobione od momentu utworzenia powłoki.
set -xZrzutu nie zawiera żadnego odniesienia do LD_LIBRARY_PATH. Phantom rozbrojony.
kjfletch
4

bash użyje różnych skryptów startowych w zależności od tego, jak się uruchomi. Istnieje siedem różnych sposobów jego uruchomienia, ale najważniejsze są powłoki logowania w przeciwieństwie do powłok interaktywnych niezalogowanych.

Sprawdź podręcznik bash więcej szczegółów. Podejrzewam, że / etc / profile lub ~ / .bash_profile robi coś, aby zresetować zmienną LD_LIBRARY_PATH.


Edycja: Myślę, że zrobiłeś wszystko, co w twojej mocy, aby pokazać, że bash nie ma żadnego skryptu startowego, który rozbroiłby LD_LIBRARY_PATH. Czas wydobyć wielkie działa.

Następujące polecenie wyświetli całe środowisko podczas uruchamiania każdego procesu, od bash do xterm i wszystkiego innego, co się z tym wiąże - prawdopodobnie otrzymasz dużą ilość danych wyjściowych, więc zapisanie danych wyjściowych do pliku jest dobrym pomysłem .

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

Teraz plik strace_output.txt pokaże każde wywołanie systemowe wykonane przez skrypt i każdy proces potomny, a będziesz mógł zobaczyć, który proces był ostatnim, który miał LD_LIBRARY_PATH przed jego usunięciem.

Kevin Panko
źródło
2

(To pytanie jest bardzo stare, ale właśnie napotkałem ten sam problem i dokumentuję rozwiązanie dla późniejszego życia :)

Miałem ten problem z ekranem GNU (multiplekser terminali), ale równie dobrze może się to zdarzyć ze zwykłym terminalem. Teddy miał rację w moim przypadku, ekran ustawił setguid set.

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

Moim rozwiązaniem było zapisanie LD_LIBRARY_PATH przed wykonaniem, a następnie przywrócenie go. Więc stworzyłem wrapper ~ / bin / screen (umieść ~ / bin na PATH), z następującą zawartością:

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

a następnie uczynił go wykonywalnym za pomocą chmod +x ~/bin/screen. Być może będziesz musiał otworzyć nową powłokę, aby pobrać opakowanie.

Następnie dodałem następujące do ~ / .bashrc. Pamiętaj, że ~ / .bashrc jest pozyskiwany za każdym razem, gdy zaczynasz bash, w przeciwieństwie do ~ / .bash_profile, który jest pozyskiwany tylko przy logowaniu (zwykle podczas uruchamiania lub podczas logowania przez 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

Teraz screen (lub aterm, xterm, ... wystarczy zastąpić go powyżej) powinien zachować $ LD_LIBRARY_PATH zgodnie z potrzebami.

jdm
źródło
Możesz także przywrócić LD_LIBRARY_PATHw .screenrc(zamiast .bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"następnieunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp
0

Wygląda na to, że masz jakiś plik .bashrc (lub równoważny) w swoim katalogu domowym, który definiuje tę zmienną. Nie znam jednak dużo więcej szczegółów.

Edytuj Ok, ponieważ uruchamianie basha działa, domyślam się, że nie .bashrc. Ale może jakiś inny plik konfiguracyjny, który jest uruchamiany w ten sam sposób, kiedy uruchamiasz xterm lub aterm.

Gnoupi
źródło
To była moja pierwotna myśl. Po wielu poszukiwaniach nic nie można znaleźć. Mam tę zaletę, że mam bardzo czysty (NOWY) $ HOME.
kjfletch
0

Większość systemów okienkowych odtwarza proces logowania po uruchomieniu okna terminala, głównie dlatego, że okno terminala staje się dzieckiem menedżera okien, a nie powłoki uruchamiającej.

Więc umieść go w swoim .bash_profile lub .bashrc, jeśli chcesz, aby pojawił się w nowym oknie.

Inną alternatywą jest przekazanie xtermowi (na przykład) argumentu do uruchomienia skryptu uruchamiania. Nie wychodź na końcu tego skryptu ...

kmarsh
źródło
Myślę, że będę musiał się do tego odwołać. Prawdopodobnie będę źródłować moje zmienne środowiskowe zarówno w .xinitrc, aby mój menedżer okien je miał, jak i w .bashrc, aby okna terminali je miały.
kjfletch