ทำไม LD_LIBRARY_PATH ของฉันจึงไม่ได้เปิดใช้งานเทอร์มินัล


8

ฉันมีเชลล์สคริปต์เพื่อตั้งค่าตัวแปรสภาพแวดล้อมและเปิดโปรแกรมใด ๆ ที่ฉันส่งเป็นอาร์กิวเมนต์:

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

$@

เมื่อฉันใช้สิ่งนี้เพื่อโทรbashหามันใช้งานได้:

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

เมื่อฉันใช้มันเพื่อเรียกขั้ว ( xterm, aterm, ... ) ของฉันLD_LIBRARY_PATHได้รับการตั้งค่า:

kjfletch@flatbed:~$ echo $LD_LIBRARY_PATH

kjfletch@flatbed:~$ echo $TESTER

MY TEST VAR

ทำไมสิ่งนี้ถึงเกิดขึ้น ฉันจะหยุดสิ่งนี้ได้อย่างไร (ฉันใช้ Debian 5.0)

ปรับปรุง

เทอร์มินัลของฉันไม่ได้เรียก bash เป็นการล็อกอิน:

kjfletch@flatbed:~$ echo $0
bash

My LD_LIBRARY_PATHไม่แสดงในไฟล์ bash startup ใด ๆ (นอกเหนือจาก. bash_history และ ~ / .profile ไม่มีอยู่):

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

เป็นไฟล์เริ่มต้นใด ๆ ที่เรียกคำสั่ง "source" หรือ "." คำสั่งเพื่อนำสคริปต์เริ่มต้นอื่น ๆ ถ้าเป็นเช่นนั้นหนึ่งในนั้นอาจเป็นผู้ร้าย
Kevin Panko

ไม่ตอบคำถามของคุณ แต่สิ่งที่ดีจริงๆคือการกำจัดความจำเป็นในการ LD_LIBRARY_PATH (เหตุผล: 1 2 3 ) ตัวอย่างเช่นคุณสามารถแก้ไข /etc/ld.so.conf หรือรวบรวม libs ที่ผู้ใช้กำหนดเองที่คุณมีใน ~ / local ในแบบที่พวกเขารู้ว่าจะหาห้องสมุดของพวกเขาได้จากที่ใด
DevSolar

คำตอบ:


9

เทอร์มินัลไบนารีมีแนวโน้มที่setgidจะจัดกลุ่มutmpมากที่สุด Setuid และ setgid ไบนารีไม่ได้ตั้งค่าLD_LIBRARY_PATHด้วยเหตุผลด้านความปลอดภัย ดูld.so(8):

ไลบรารีที่แบ่งใช้ที่จำเป็นซึ่งโปรแกรมต้องการจะถูกค้นหาตามลำดับต่อไปนี้

  • การใช้ตัวแปรสภาพแวดล้อมLD_LIBRARY_PATH( LD_AOUT_LIBRARY_PATHสำหรับโปรแกรม a.out) ยกเว้นว่าไฟล์ที่เรียกทำงานได้นั้นเป็นไบนารี setuid / setgid ซึ่งในกรณีนี้มันจะถูกละเว้น

4

ในขั้ว (xterm, aterm ฯลฯ ) ตรวจสอบว่าเปลือกถูกเรียก: เปลือกเข้าสู่ระบบจะแสดง "ทุบตี" และเปลือกที่ไม่ได้เข้าสู่ระบบจะแสดง "ทุบตี" echo $0เมื่อคุณเรียก

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

เปลือกทุบตีล็อกอินจะอ่านสิ่งต่อไปนี้ตามลำดับ:

  1. / etc / รายละเอียด
  2. ~ / .bash_profile
  3. ~ / .bash_login
  4. ~ / .profile

ตรวจสอบว่ามีไฟล์ใด ๆ เหล่านี้อยู่หรือไม่และหากพวกเขารีเซ็ตตัวแปร คุณจะต้องติดตามไฟล์ใด ๆ ที่ไฟล์เหล่านี้มี

หาก bash ไม่ถูกเรียกใช้เป็นเชลล์การเข้าสู่ระบบจะยังคงอ่านไฟล์ด้านล่างหากพิจารณาว่าเป็นเชลล์แบบโต้ตอบ

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

วิธีง่ายๆในการพิจารณาประเภทของ bash shell ที่ถูกเรียกใช้คือการกำหนด. bash_profile และ. bashrc ของคุณและ echo "ล็อกอินเชลล์" และ "Interactive shell" ตามลำดับ

เมื่อคุณทราบชนิดของเชลล์ที่ถูกเรียกใช้คุณจะมีตัวเลือกในการเพิ่มสคริปต์ของคุณไปยังไฟล์. bashrc หรือ. bash_profile ในโฮมไดเร็กตอรี่ของคุณ หรือคุณสามารถปิดใช้งานการรีเซ็ต LD_LIBRARY_PATH

โปรดทราบว่าหาก. bashrc หรือ. bash_profile ของคุณได้รับการปกป้องโดยการป้องกันเช่นเดียวกับด้านล่างคุณอาจต้องเรียกสคริปต์ของคุณนอก:

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

fi

โดยปกติแล้วการ์ดดังกล่าวจะถูกวางไว้เพื่อป้องกันไม่ให้สคริปต์มีที่มาหลายครั้งในเซสชัน

แก้ไข:หากพิสูจน์ให้เห็นว่า tedius ติดตามตำแหน่งที่ตัวแปรถูกรีเซ็ตและคุณสามารถเข้าถึง / etc / profile หรือ /etc/bash.bashrc ได้เช่นกันคุณสามารถเพิ่ม "set -x" ใกล้กับด้านบนของ สคริปต์เพื่อดูคำสั่งทั้งหมดที่ได้รับการดำเนินการ เอาต์พุตจะค่อนข้างละเอียดดังนั้นอันดับแรกให้ทำ "set -x" ในเชลล์ของคุณและรันคำสั่งสองสามคำสั่งเพื่อให้คุณรู้ว่าจะต้องทำอะไร


+1 ขอบคุณสำหรับข้อมูล ฉันได้อัปเดต OP ของฉันตามคำตอบของคุณ
kjfletch

คุณเห็นลักษณะการทำงานเดียวกันหรือไม่หากคุณป้อน bash shell ใหม่ในเทอร์มินัลเดียวกันโดยพิมพ์ bash แม้ว่าคุณจะต้องตรวจสอบไฟล์ที่ถูกเรียกจากภายใน /etc/bash.bashrc และ / etc / profile หนึ่งในนั้นอาจยกเลิกการตั้งค่าตัวแปร อีกวิธีหนึ่งคือใช้set -xตัวเลือกการดีบั๊กเพื่อรับดัมพ์ของทุกสิ่งที่ทำเสร็จตั้งแต่เวลาที่เชลล์สร้างขึ้น

set -xการถ่ายโอนข้อมูลที่ทำให้ไม่มีการอ้างอิงถึง LD_LIBRARY_PATH Phantom ไม่ได้ตั้งค่า
kjfletch

4

bash จะใช้สคริปต์เริ่มต้นที่แตกต่างกันขึ้นอยู่กับว่าจะเริ่มต้นอย่างไร มีเจ็ดวิธีที่แตกต่างในการเริ่มต้น แต่ที่สำคัญที่สุดคือเชลล์การเข้าสู่ระบบกับเชลล์แบบโต้ตอบที่ไม่ใช่การเข้าสู่ระบบ

ตรวจสอบคู่มือทุบตีสำหรับรายละเอียดเพิ่มเติม ฉันสงสัยว่า / etc / profile หรือ ~ / .bash_profile กำลังทำบางสิ่งเพื่อรีเซ็ตตัวแปร LD_LIBRARY_PATH


แก้ไข: ฉันคิดว่าคุณได้ทำทุกอย่างตามสมควรแล้วเพื่อแสดงว่า bash ไม่มีสคริปต์เริ่มต้นที่ไม่ได้ LD_LIBRARY_PATH ถึงเวลาที่จะนำปืนใหญ่ออกมา

คำสั่งต่อไปนี้จะแสดงสภาพแวดล้อมทั้งหมดเมื่อแต่ละกระบวนการเริ่มต้นจาก bash ถึง xterm และสิ่งอื่น ๆ ที่เกี่ยวข้อง - คุณอาจได้รับเอาต์พุตจำนวนมากดังนั้นการบันทึกผลลัพธ์ไปยังไฟล์จึงเป็นความคิดที่ดี .

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

ตอนนี้ไฟล์strace_output.txtจะแสดงการเรียกระบบแต่ละครั้งโดยสคริปต์ของคุณและกระบวนการลูกทั้งหมดและคุณจะเห็นว่ากระบวนการใดเป็นกระบวนการสุดท้ายที่มี LD_LIBRARY_PATH ก่อนที่จะถูกลบออก


2

(คำถามนี้เก่ามาก แต่ฉันเพิ่งพบปัญหาเดียวกันและกำลังบันทึกวิธีแก้ปัญหาสำหรับคนหลัง :)

ฉันเคยมีปัญหานี้กับหน้าจอ GNU (เทอร์มินัลมัลติเพล็กเซอร์) แต่ก็สามารถเกิดขึ้นได้ด้วยเทอร์มินัลปกติ เท็ดดี้ถูกต้องในกรณีของฉันหน้าจอได้ตั้งค่าแนะนำ

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

โซลูชันของฉันคือบันทึก LD_LIBRARY_PATH ก่อนที่จะดำเนินการและกู้คืนในภายหลัง ดังนั้นฉันจึงสร้าง wrapper ~ / bin / screen (ใส่ ~ / bin บน PATH) โดยมีเนื้อหาดังต่อไปนี้:

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

chmod +x ~/bin/screenและทำแล้วมันปฏิบัติการด้วย คุณอาจต้องเปิดเปลือกใหม่เพื่อให้มันไปหยิบเสื้อคลุม

จากนั้นฉันเพิ่มสิ่งต่อไปนี้ลงใน ~ / .bashrc จำไว้ว่า ~ / .bashrc จะได้รับแหล่งข้อมูลทุกครั้งที่คุณเริ่มทุบตีซึ่งแตกต่างจาก ~ / .bash_profile ซึ่งจะได้รับที่มาจากการเข้าสู่ระบบเท่านั้น (โดยปกติเมื่อเริ่มต้นหรือเมื่อคุณเข้าสู่ระบบด้วย 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

ตอนนี้หน้าจอ (หรือ aterm, xterm, ... เพียงแค่แทนที่ด้านบน) ควรรักษา $ LD_LIBRARY_PATH ตามที่ต้องการ


คุณยังสามารถกู้คืนLD_LIBRARY_PATHใน.screenrc(แทน.bashrc): setenv LD_LIBRARY_PATH "$PRESERVE_LD_LIBRARY_PATH"ตามด้วยunsetenv PRESERVE_LD_LIBRARY_PATH
nandhp

0

ดูเหมือนว่าคุณมีไฟล์. bashrc (หรือเทียบเท่า) บางไฟล์ในโฮมไดเร็กตอรี่ของคุณซึ่งกำหนดตัวแปรนี้ ฉันไม่ทราบรายละเอียดมากนัก

แก้ไขตกลงตั้งแต่เริ่มใช้งาน bash ฉันคาดเดาไม่ได้ว่าเป็น. bashrc แต่อาจมีไฟล์การกำหนดค่าอื่น ๆ ที่เกิดขึ้นที่จะถูกดำเนินการในลักษณะเดียวกันเมื่อคุณเริ่ม xterm หรือ aterm


นี่คือความคิดดั้งเดิมของฉัน หลังจากค้นหามากไม่มีอะไรที่จะพบ ฉันได้รับประโยชน์จากการมีบ้านที่สะอาด (ใหม่) $
kjfletch

0

ระบบหน้าต่างส่วนใหญ่จะสร้างกระบวนการเข้าสู่ระบบใหม่เมื่อเปิดหน้าต่างเทอร์มินัลเนื่องจากหน้าต่างเทอร์มินัลกลายเป็นลูกของตัวจัดการหน้าต่างไม่ใช่ตัวเรียกใช้เชลล์

ดังนั้นวางไว้ใน. bash_profile หรือ. bashrc ของคุณหากคุณต้องการให้มันแสดงในหน้าต่างใหม่

อีกทางเลือกหนึ่งคือส่ง xterm (ตัวอย่าง) อาร์กิวเมนต์เพื่อเรียกใช้สคริปต์เริ่มต้น อย่าออกในตอนท้ายของสคริปต์นั้น ....


ฉันจะต้องใช้วิธีนี้ฉันคิดว่า ฉันอาจจะหาแหล่งที่มาของตัวแปรสภาพแวดล้อมของฉันทั้งใน. xinitrc ดังนั้นตัวจัดการหน้าต่างของฉันจึงมีและใน. bashrc เพื่อให้หน้าต่างเทอร์มินัลของฉันมี
kjfletch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.