Di OSX Yosemite, mengapa saya bisa mengatur banyak variabel lingkungan untuk aplikasi GUI, tetapi tidak dapat mengatur PATH variabel tertentu

16

Setelah saya menyelesaikan masalah PATH OSX hingga rilis Mavericks, masalahnya kembali di Yosemite !!!

Jadi saya ingin meniru launch.conffitur lama di rilis Yosemite Mac OSX 10.10 baru, untuk memiliki variabel lingkungan PATH dalam aplikasi GUI seperti Carbon Emacs atau RStudio tersedia. Saya menggunakan ide hebat dari stackoverflow ursa pengguna untuk mengatur skrip shell yang mengkonfigurasi variabel lingkungan melalui launchctl. (Lihat jawaban stackoverflow-nya di sini .) Ini berfungsi untuk sebagian besar variabel lingkungan, tetapi tidak untuk variabel PATH .

1. Apa yang telah saya lakukan?

Pertama saya menulis /etc/environment.rcskrip yang terlihat seperti:

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"

Kemudian saya membuat daftar untuk launchd(daftar ini dan skrip lain yang disebutkan dalam lampiran di bawah). Lalu saya mengaktifkannya dengan

$ sudo launchctrl load ...

Kemudian saya menonaktifkan path_helperutilitas di /etc/profil file init shell , sehingga tidak menimpa environment.rcpengaturan. Dan akhirnya saya me-restart mesin.

2. Apa efeknya?

Ketika saya memulai Terminal, variabel lingkungan baru JAVA_HOMEdan ENVIRONMENT_RCdiatur sesuai dengan environment.rc, tetapi PATH diatur ke

/ usr / bin: / bin

Untuk memastikan, tidak ada bashfile init yang menghalangi saya menulis skrip python kecil sebagai gantinya (dalam lampiran juga) untuk menunjukkan variabel-variabel di lingkungan saat ini dan saya menjalankan ini secara langsung dengan mengklik ganda bungkus Platypus . Sekali lagi variabel baru ditetapkan, sementara PATH memiliki sistem default.

Jadi mengapa saya bisa mengatur variabel lain, tetapi tidak variabel PATH? Dan bagaimana saya bisa menyelesaikan ini secara terpadu ?

Memperbarui:

Situasinya sangat membingungkan: Shell ( bashsetidaknya) di Terminal atau Emacs akan mengambil PATH yang Anda atur launchctl, tetapi aplikasi GUI lain tidak akan melakukannya., Mis. Skrip python minimal yang disebut langsung yang dipanggil melalui Platypus tidak akan menampilkan kustom Anda jalan. Dan bahkan Emacs sendiri tidak tahu PATH yang benar: Anda melihat ini misalnya ketika Anda mengeluarkan perintah Emacs M-x ispell-buffer; alat unix ispellyang coba dipanggil emacs tidak akan ditemukan jika hanya di jalur kustom Anda.


Lampiran

net.halloleo.environment.plist, file konfigurasi launchd di /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, file konfigurasi launchd di /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, file permulaan pesta modifikasi:

# 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, skrip yang menampilkan semua variabel lingkungan:

import os
print (os.environ)
halo
sumber

Jawaban:

3

PATH di Yosemite dapat dan harus diatur dalam file / etc / paths. Cukup tambahkan jalur Anda ke akhir file ini:

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

/ etc / environment script dalam postingan asli menyediakan dukungan untuk variabel PATH dalam aplikasi GUI (diuji dengan Emacs).

ursa
sumber
5
Ini hanya berfungsi untuk shell yang memanggil /usr/libexec/path_helperselama proses inisialisasi mereka. Aplikasi GUI tidak mendapatkan PATH menurut /etc/paths- dan saya bertanya secara khusus tentang aplikasi GUI.
halloleo
Saya telah memperbarui skrip jawaban dan / etc / environment di pos asli
ursa
Ini adalah dua jawaban yang mana yang Anda berikan - juga OP mengatakan / etc / environment tidak berfungsi
user151019
@mark (1) setelah pertanyaan ini muncul, saya telah memperbarui / etc / environment, dan sekarang sudah mendukung PATH. (2) jawabannya di sini adalah menggunakan / etc / paths
ursa
2
@mark Ya, dan itulah titik, masalah, dan pertanyaan saya: Bagaimana saya bisa mengatur sendiri variabel lingkungan PATH dari aplikasi GUI saat diluncurkan melalui Finder? Namun, tidak ada solusi umum nyata untuk ini yang terlihat ...
halloleo
2

Ini membingungkan saya untuk waktu yang lama (yah, beberapa jam terakhir). Pada akhirnya saya menemukan laporan bug ini, yang sepertinya menggambarkan dengan tepat masalah saya (saya tidak yakin sampai sejauh mana itu terkait dengan masalah Anda, tetapi tampaknya ada bug di Yosemite / launchd dalam kombinasi dengan PATH dan skrip seperti sebagai python:

http://www.openradar.me/18945659

Solusinya tampaknya memulai skrip shell yang kemudian memulai python. Tidak benar-benar apa yang saya suka, tapi memang seperti itu ....

Claude
sumber
Terima kasih atas tautannya ke laporan bug. Bagus untuk sekarang ini adalah bug nyata. Saya menemukan kopling lain di sekitarnya; Saya akan mempostingnya di sini.
halloleo
1

Masalahnya adalah launchd menambahkan variabel PATH yang lain alih-alih menggantikan yang ada di lingkungan. Sebagian besar program menggunakan getenvyang selalu mengembalikan kemunculan pertama dari suatu variabel, sebaliknya shell mengulangi semua variabel lingkungan dan mengimpornya sebagai variabel lokal sehingga menimpa contoh sebelumnya dengan yang terakhir.

Ini jelas bug di launchd, variabel lingkungan yang diteruskan ke program harus unik.

StenSoft
sumber
1
Jawaban latar belakang keren! Saya kira theer tidak nyata jalan di shell, atau ada?
halloleo
@ halloleo Anda dapat meluncurkan perintah sh -c 'YOUR ORIGINAL COMMAND'yang melewati shell, memilih PATHset di launchd.
StenSoft