2009-07-24 46 views
20

Có thể thay đổi các biến môi trường của quy trình hiện tại không?Thay đổi LD_LIBRARY_PATH của môi trường quy trình hiện tại

Cụ thể hơn trong một kịch bản python Tôi muốn thay đổi LD_LIBRARY_PATH để về nhập khẩu của một module 'x' mà phụ thuộc vào một số xyz.so, xyz.so được lấy từ con đường cho tôi trong LD_LIBRARY_PATH

là có cách nào khác để tự động thay đổi đường dẫn từ nơi thư viện được tải?

Sửa: Tôi nghĩ rằng tôi cần phải đề cập đến mà tôi đã cố gắng điều như os.environ [ "LD_LIBRARY_PATH"] = mypath os.putenv ('LD_LIBRARY_PATH', mypath)

nhưng những sửa đổi env. cho sinh ra tiểu quá trình, không phải là quá trình hiện tại, và mô-đun tải không xem xét LD_LIBRARY_PATH mới

Edit2, vì vậy câu hỏi là chúng ta có thể thay đổi môi trường hoặc một cái gì đó để thư viện loader nhìn thấy nó và tải từ đó?

+0

Đó không phải là một bản sao của http://stackoverflow.com/questions/856116/changing-ldlibrarypath-at-runtime -cho-ctypes? Bạn không thực sự hỏi làm thế nào để thay đổi môi trường, nhưng thay vì làm thế nào để thay đổi nơi python tải thư viện từ. –

+0

ok! tôi sẽ nói điều này là trùng lặp, nhưng không có nó không phải là abt python nó về thay đổi môi trường, ví dụ trong ứng dụng ac tải một lib động A, chúng ta có thể thay đổi môi trường sao cho A được tải từ đường dẫn của chúng ta lựa chọn –

Trả lời

32

Lý do

os.environ["LD_LIBRARY_PATH"] = ... 

không hoạt động rất đơn giản: môi trường này điều khiển biến hành vi của các bộ nạp động (ld-linux.so.2 trên Linux, Solaris ld.so.1 trên), nhưng bộ nạp chỉ nhìn LD_LIBRARY_PATH một lần tại quá trình khởi động . Thay đổi giá trị của LD_LIBRARY_PATH trong quy trình hiện tại sau điểm đó không có hiệu lực (giống như câu trả lời cho câu hỏi this nói).

Bạn có một số tùy chọn:

A. Nếu bạn biết rằng bạn sẽ cần xyz.so từ /some/path, và kiểm soát việc thực hiện các script python từ đầu, sau đó chỉ cần đặt LD_LIBRARY_PATH theo ý thích của bạn (sau khi kiểm tra xem nó chưa được thiết lập) và tự thực hiện lại. Đây là những gì Java thực hiện.

B. Bạn có thể nhập /some/path/xyz.so qua đường dẫn tuyệt đối trước khi nhập x.so. Khi bạn nhập x.so, trình tải sẽ phát hiện ra rằng nó đã tải xyz.so và sẽ sử dụng mô-đun đã tải thay vì tìm kiếm lại.

C. Nếu bạn tự xây dựng x.so, bạn có thể thêm -Wl,-rpath=/some/path vào dòng liên kết và sau đó nhập x.so sẽ khiến trình tải tìm kiếm mô-đun phụ thuộc trong /some/path.

+0

B, trông giống như một tùy chọn tôi có thể sử dụng –

+0

Tùy chọn B sẽ được thực hiện như thế nào? Tôi nghĩ rằng OP ngụ ý rằng '/ some/path/xyz.so' là một thư viện chia sẻ mà một mô-đun Python phụ thuộc vào; 'xyz.so' không chứa một mô-đun Python. Tôi có một tình huống tương tự và không biết cách nào để nhập thư viện theo cách bạn mô tả. –

+2

@JasonR Tùy chọn B có thể được triển khai bằng cách sử dụng 'import dl; dl.open ("/ some/path/xyz.so") ' –

-4

tốt, các biến môi trường được lưu trữ trong os.environ từ điển, vì vậy nếu bạn muốn thay đổi, bạn có thể làm

os.environ["PATH"] = "/usr/bin" 
+0

Và tôi nghĩ rằng bạn phải chắc chắn rằng bạn đặt os.environ ["LD_LIBRARY_PATH"] * trước * lệnh nhập cho mô-đun x. – ThomasH

+0

xem chỉnh sửa, tôi đã thử điều này và điều này không hoạt động –

+0

Đặt LD_LIBRARY_PATH theo cách như vậy không ảnh hưởng đến quy trình hiện tại, như tôi đã giải thích trong câu trả lời của tôi. –

0

Theo kinh nghiệm của tôi cố gắng để thay đổi cách nạp làm việc cho một Python chạy rất khó khăn; có lẽ phụ thuộc vào hệ điều hành/phiên bản; có thể không hoạt động. Một công việc xung quanh có thể giúp trong một số trường hợp là khởi chạy một tiến trình con thay đổi tham số môi trường bằng cách sử dụng một kịch bản lệnh shell và sau đó khởi chạy một Python mới bằng cách sử dụng trình bao.

8

Dựa trên câu trả lời từ Employed Nga, đây là những gì làm việc cho tôi

oracle_libs = os.environ['ORACLE_HOME']+"/lib/" 
rerun = True 

if not 'LD_LIBRARY_PATH' in os.environ: 
    os.environ['LD_LIBRARY_PATH'] = ":"+oracle_libs 
elif not oracle_libs in os.environ.get('LD_LIBRARY_PATH'): 
    os.environ['LD_LIBRARY_PATH'] += ":"+oracle_libs 
else: 
    rerun = False 

if rerun: 
    os.execve(os.path.realpath(__file__), sys.argv, os.environ) 
+1

Bí quyết thực hiện là * chính xác * những gì tôi cần, và nó hoạt động, có một upvote! –

Các vấn đề liên quan