2016-10-11 16 views
5

Nếu, khi tôi chạy tập lệnh, tôi sử dụng LD_PRELOAD để chỉ định thư viện để tải trước, tôi thấy rằng thư viện trên thực tế được tải trước chỉ khi tập lệnh có dòng shebang. Ví dụ, đưa ra kịch bản này:Tại sao LD_PRELOAD không có hiệu lực với các tập lệnh không có shebang?

# Not a shebang 
echo Hello 

và lệnh này:

LD_PRELOAD=/path/to/preload_me.so ./script.sh 

kịch bản chạy mà không có thư viện được nạp ở tất cả, mà tôi có thể giám sát thông qua các hiệu ứng (phi) khởi tạo của nó mã.

Mặt khác, nếu tôi thêm một dòng công việc:

#!/bin/sh 
echo Hello 

... sau đó thư viện nạp khi tôi chạy kịch bản thông qua cùng một lệnh. Nó không có vẻ quan trọng chính xác mà thông dịch viên được chỉ định; chắc chắn tôi cũng có thể sử dụng /bin/bash hoặc bất kỳ vỏ nào khác sh -gia đình mà tôi đã thử.

Tại sao có sự khác biệt và có cách nào để đảm bảo rằng một thư viện nhất định được tải trước trước một lệnh shell đơn giản nhất định, không phụ thuộc vào lệnh?

(Phỏng theo another question mà tác giả chống lại câu hỏi được diễn đạt bằng những thuật ngữ này.)

Trả lời

6

(Phỏng theo câu trả lời của tôi cho câu hỏi khác được tham chiếu.)

Nó là điều cần thiết để hiểu rằng LD_PRELOAD biến không có có ý nghĩa đặc biệt đối với hệ điều hành hoặc hệ vỏ. Nó có ý nghĩa và hiệu quả - nếu nó có tất cả - chỉ kết hợp với trình liên kết động. Nếu liên kết động không được tương tác, thì LD_PRELOAD chỉ là một biến khác trong môi trường. Tương tự, nếu trình liên kết động không nhận ra biến đó (như trên OS X chẳng hạn). Cũng cần phải hiểu rằng khi thực hiện lệnh có tên tương ứng với một tệp không có định dạng thực thi nhưng có chứa một dòng shebang, trình thông dịch được chỉ định được thực thi, ngay cả khi nó là chính shell. Nếu thông dịch viên là nhị phân ELF, tham gia vào trình liên kết động. Mặt khác, nếu không có dòng shebang thì bash thực thi nội dung của tệp trong môi trường vỏ bọc con, không yêu cầu liên kết đến trình liên kết động; thay vào đó, vỏ chỉ dĩa. Các loại vỏ khác có thể hoặc có thể không giống nhau.

Cũng rất quan trọng để nhận ra rằng các định dạng thực thi khác với ELF tồn tại. Bạn không thể chạy vào một nhị phân như vậy trên một hệ thống dựa trên ELF hiện đại, nhưng bạn không nên loại trừ khả năng.

Dòng dưới cùng: không có cách nào để đảm bảo rằng thư viện động đã cho sẽ được tải sẵn trong không gian quá trình của lệnh shell tùy ý được thực thi qua bash hoặc một trình bao khác do người dùng chọn. Nếu bạn yêu cầu một thư viện được cài đặt sẵn cho bất kỳ hoặc mọi lệnh tùy ý thì bạn cần phải kiểm soát môi trường thực thi nghiêm ngặt hơn, có thể bằng cách cung cấp một trình bao tùy chỉnh và cũng có thể là một trình liên kết động tùy chỉnh và ngăn không cho người khác sử dụng.

+2

Đây là một câu trả lời hay, nhưng tôi nghĩ bạn nên làm rõ rằng nó áp dụng cụ thể cho 'bash' (và có lẽ các shell khác.)' Dash' dường như không làm điều này, ví dụ. (Nó thực thi kịch bản, nhưng quá trình tải trước có hiệu lực.) Tất cả Posix nói là "trình bao sẽ thực hiện một lệnh tương đương với việc có một trình bao được gọi ra với tên đường dẫn xuất phát từ tìm kiếm như toán hạng đầu tiên của nó," có thể áp dụng cho cả hai hành vi. (Kiểm tra nhanh trên hệ thống của tôi: zsh preloads, ksh không. Đi con số.) – rici

+0

@rici, câu trả lời rõ ràng nói rằng * 'bash' * forks thay vì exec'ing một quá trình shell mới, nhưng tôi vẫn có thêm làm rõ. –

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