Khi tôi sử dụng shebang #!/usr/bin/env python
để chạy tập lệnh, làm thế nào để hệ thống biết python
nên sử dụng tập lệnh nào ? Nếu tôi tìm một python
đường dẫn bin trong các biến môi trường, tôi không tìm thấy gì.
env | grep -i python
Khi tôi sử dụng shebang #!/usr/bin/env python
để chạy tập lệnh, làm thế nào để hệ thống biết python
nên sử dụng tập lệnh nào ? Nếu tôi tìm một python
đường dẫn bin trong các biến môi trường, tôi không tìm thấy gì.
env | grep -i python
Câu trả lời:
Shebang mong muốn một đường dẫn đầy đủ đến trình thông dịch sẽ sử dụng nên cú pháp sau sẽ không chính xác:
#!python
Đặt đường dẫn đầy đủ như thế này có thể hoạt động:
#!/usr/local/bin/python
nhưng sẽ không di động như trăn có thể được cài đặt trong /bin
, /opt/python/bin
hoặc bất cứ nơi nào vị trí khác.
Sử dụng env
#!/usr/bin/env python
là một phương thức cho phép một cách di động để chỉ định cho HĐH một đường dẫn đầy đủ tương đương với đường dẫn python
đầu tiên được đặt trong PATH
.
Dòng shebang (từ bang sharp sharp bang, tức là #!
) được xử lý bởi kernel. Nhân không muốn biết về các biến môi trường như PATH
. Vì vậy, tên trên dòng shebang phải là một đường dẫn tuyệt đối đến một tệp thực thi. Bạn cũng có thể chỉ định một đối số bổ sung để chuyển đến thực thi đó trước tên tập lệnh (với các hạn chế phụ thuộc hệ thống mà tôi sẽ không đi vào đây). Ví dụ: đối với tập lệnh Python, bạn có thể chỉ định
#!/usr/bin/python
trên dòng đầu tiên và khi bạn thực thi tập lệnh, nhân trên thực tế sẽ thực thi /usr/bin/python /path/to/script
. Nhưng điều đó không thuận tiện: bạn cần chỉ định đường dẫn đầy đủ của lệnh. Điều gì nếu bạn có python
trong /usr/bin
một số máy và /usr/local/bin
trên những người khác? Hoặc bạn muốn thiết lập của bạn PATH
để /home/joe/opt/python-2.5/bin
để sử dụng một phiên bản cụ thể của Python? Vì kernel sẽ không PATH
tìm kiếm cho bạn, nên ý tưởng là làm cho kernel chạy một lệnh mà lần lượt tìm kiếm trình thông dịch mong muốn trong PATH
:
#!/fixed/path/to/path-lookup-command python
Điều đó path-lookup-command
phải lấy tên của một tệp thực thi làm đối số và tra cứu nó PATH
và thực thi nó: kernel sẽ chạy /fixed/path/to/path-lookup-command python /path/to/script
. Khi nó xảy ra, env
lệnh làm điều đó. Mục đích chính của nó là để chạy một lệnh với một môi trường khác, nhưng vì nó tìm kiếm tên lệnh trong $PATH
đó, nó hoàn hảo cho mục đích của chúng tôi ở đây.
Mặc dù đây không phải là chính thức đảm bảo, hệ thống Unix lịch sử cung cấp env
trong /usr/bin
và các hệ thống hiện đại đã giữ vị trí đó một cách chính xác vì việc sử dụng rộng rãi #!/usr/bin/env
. Vì vậy, trong thực tế, cách để xác định rằng tập lệnh phải được thực thi bởi trình thông dịch Python yêu thích của người dùng là
#!/usr/bin/env python
env
và which
? kể từ đó cũng sẽ có được khả năng thực thi đủ điều kiện nhất từ môi trường PATH của tôi.
which
tìm thấy tệp thực thi và in đường dẫn của nó. env
tìm chương trình được chỉ định bởi đối số đầu tiên và thực thi nó, truyền cho nó các đối số còn lại.
env
là một phiên bản eval về which
cơ bản.
Phải, nên chạy:
env | grep PATH
$ PATH của bạn là một danh sách các thư mục. Unix sẽ đi qua danh sách các thư mục đó, theo thứ tự, cho đến khi tìm thấy "python".
Bạn có thể xem thư mục nào nó tìm thấy bằng lệnh 'which':
which python
sys.path
giữa một env $ env python3
( ['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/.local/lib/python3.4/site-packages', '/usr/lib/python3.4/site-packages', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
) và ./env/bin/python3
(['', '/home/user/test', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/home/user/test/env3/lib/python3.4/site-packages']
) được kích hoạt .