Trong OSX Yosemite, tại sao tôi có thể đặt nhiều biến môi trường cho ứng dụng GUI, nhưng không thể đặt biến PATH cụ thể


16

Sau khi tôi đã sắp xếp các vấn đề về OSX 'PATH cho đến phiên bản Mavericks, các vấn đề sẽ quay trở lại ở Yosemite !!!

Vì vậy, tôi muốn bắt chước launch.conftính năng cũ trong bản phát hành Yosemite Mac OSX 10.10 mới, để có sẵn biến môi trường PATH trong các ứng dụng GUI như Carbon Emacs hoặc RStudio . Tôi đã sử dụng ý tưởng tuyệt vời của ursa stackoverflow để thiết lập một tập lệnh shell để cấu hình các biến môi trường thông qua launchctl. (Xem câu trả lời stackoverflow của anh ấy ở đây .) Điều này hoạt động với hầu hết các biến môi trường, nhưng không phải cho biến PATH .

1. Tôi đã làm gì?

Đầu tiên tôi viết /etc/environment.rckịch bản trông như sau:

launchctl setenv PATH /Users/halloleo/bin:/usr/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
launchctl setenv JAVA_HOME /usr/local/jdk1.7
launchctl setenv ENVIRONMENT_RC "yes"

Sau đó, tôi đã tạo ra các bảng cho launchd(danh sách này và các tập lệnh được đề cập khác trong phần phụ lục bên dưới). Sau đó, tôi kích hoạt chúng với

$ sudo launchctrl load ...

Sau đó, tôi đã vô hiệu hóa path_helpertiện ích trong /etc/hồ sơ tập tin shell init để nó không ghi đè environment.rccài đặt. Và cuối cùng tôi khởi động lại máy.

2. Hiệu quả là gì?

Khi tôi khởi động Terminal, các biến môi trường mới JAVA_HOMEENVIRONMENT_RCđược đặt theo environment.rc, nhưng PATH được đặt thành

/ usr / bin: / bin

Để đảm bảo, không có bashtệp init nào cản trở tôi viết một đoạn script python nhỏ (trong phần phụ lục) để hiển thị các biến trong môi trường hiện tại và tôi thực hiện điều này trực tiếp bằng cách nhấp đúp vào trình bao bọc Platypus . Một lần nữa các biến mới được đặt, trong khi PATH có mặc định hệ thống.

Vậy tại sao tôi có thể đặt các biến khác, nhưng không phải là biến PATH? Và làm thế nào tôi có thể giải quyết điều này một cách thống nhất ?

Cập nhật:

Tình huống rất khó hiểu: Shell ( bashít nhất) trong Terminal hoặc Emacs sẽ chọn PATH mà bạn đã đặt qua launchctl, nhưng các ứng dụng GUI khác sẽ không làm như vậy. Ví dụ: tập lệnh python tối thiểu được đề cập trực tiếp được gọi qua Platypus sẽ không hiển thị tùy chỉnh của bạn con đường. Và ngay cả bản thân Emacs cũng không biết đúng PATH: Bạn nhận thấy điều này, ví dụ như khi bạn ban hành lệnh Emacs M-x ispell-buffer; công cụ unix ispellmà emacs cố gắng gọi sẽ không được tìm thấy nếu nó chỉ nằm trên đường dẫn tùy chỉnh của bạn.


ruột thừa

net.halloleo.environment.plist, tập tin cấu hình launchd trong /Library/LaunchDaemons/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

net.halloleo.environment-user.plist, tập tin cấu hình launchd trong /Library/LaunchAgents/:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>KeepAlive</key>
    <false/>
    <key>Label</key>
    <string>net.halloleo.environment-user</string>
    <key>ProgramArguments</key>
    <array>
        <string>/bin/sh</string>
        <string>/etc/environment.rc</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>WatchPaths</key>
    <array>
        <string>/etc/environment.rc</string>
    </array>
</dict>
</plist>

/etc/profile, tệp khởi động bash đã sửa đổi:

# System-wide .profile for sh(1)

# if [ -x /usr/libexec/path_helper ]; then
#   eval `/usr/libexec/path_helper -s`
# fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

show_environ.py, tập lệnh hiển thị tất cả các biến môi trường:

import os
print (os.environ)

Câu trả lời:


3

PATH trong Yosemite có thể và nên được đặt trong tệp / etc / path. Chỉ cần thêm đường dẫn của bạn vào cuối tập tin này:

/usr/bin
/bin
/your/custom/path

/ etc / script script trong bài viết gốc cung cấp hỗ trợ cho biến PATH trong các ứng dụng GUI (được thử nghiệm với Emacs).


5
Điều này chỉ hoạt động cho các shell mà gọi /usr/libexec/path_helpertrong quá trình khởi tạo của chúng. Các ứng dụng GUI không nhận được PATH theo /etc/paths- và tôi đã hỏi cụ thể về các ứng dụng GUI.
halloleo

Tôi đã cập nhật câu trả lời và / etc / script môi trường trong bài viết gốc
ursa

Đây là hai câu trả lời mà bạn đang đưa ra - cũng là OP nói / etc / môi trường không hoạt động
user151019

@mark (1) sau khi câu hỏi này được đưa ra, tôi đã cập nhật / etc / môi trường và bây giờ nó hỗ trợ PATH. (2) câu trả lời ở đây là sử dụng / etc / path
ursa

2
@mark Có, và đó chính xác là quan điểm, vấn đề và câu hỏi của tôi: Làm cách nào tôi có thể tự đặt biến môi trường PATH của ứng dụng GUI khi được khởi chạy thông qua Finder? Tuy nhiên, không có giải pháp chung thực sự nào cho điều này trong tầm nhìn ...
halloleo

2

Điều này làm tôi bối rối trong một thời gian dài (tốt, vài giờ qua). Cuối cùng, tôi đã gặp phải báo cáo lỗi này, có vẻ như mô tả chính xác vấn đề của tôi (tôi không chắc điều gì mở rộng liên quan đến vấn đề của bạn, nhưng dường như có một lỗi trong Yosemite / launchd kết hợp với PATH và các tập lệnh như vậy như con trăn:

http://www.openradar.me/18945659

Giải pháp có vẻ là bắt đầu một kịch bản shell và sau đó khởi động python. Không thực sự là những gì tôi thích, nhưng nó là như vậy ....


Cảm ơn các liên kết đến báo cáo lỗi. Tốt cho đến bây giờ nó là một lỗi thực sự. Tôi tìm thấy một ly hợp khác xung quanh nó; Tôi sẽ đăng nó ở đây.
halloleo

1

Vấn đề là launchd sẽ nối thêm một biến PATH khác thay vì thay thế một biến trong môi trường. Hầu hết các chương trình sử dụng getenvluôn trả về lần xuất hiện đầu tiên của biến, shell thay vì lặp qua tất cả các biến môi trường và nhập chúng dưới dạng biến cục bộ, do đó ghi đè lên các thể hiện trước với biến cuối cùng.

Đây rõ ràng là một lỗi trong launchd, các biến môi trường được truyền cho một chương trình nên là duy nhất.


1
Câu trả lời nền mát mẻ! Tôi đoán theer không phải là cách thực sự xung quanh nó trong vỏ, hoặc là có?
halloleo

@halloleo Bạn có thể khởi chạy lệnh khi sh -c 'YOUR ORIGINAL COMMAND'chuyển nó qua shell, chọn PATHtập hợp trong launchd.
StenSoft
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.