Questo sembra un bug OS X accoppiato con un comportamento indefinito diverso in Ruby ed Emacs.
La causa principale è che quando si avvia Emacs da Finder, OS X sta passando la variabile di ambiente PATH
al processo due volte! Ho scritto un test case e l'ho inviato al bug reporter di Apple (id 19801095). Ecco il mio caso di test:
#!/bin/bash
mkdir -p /tmp/test.app/Contents/MacOS/
cat > /tmp/test.app/Contents/MacOS/test <<EOF
#!/usr/bin/env ruby
\$stdout.reopen('/tmp/test.app.log', "w")
ENV.each_pair {|k,v| puts "#{k}=#{v}" if k == 'PATH' }
EOF
chmod +x /tmp/test.app/Contents/MacOS/test
launchctl setenv PATH "Extra PATH"
open -W /tmp/test.app
cat /tmp/test.app.log
launchctl unsetenv PATH
Se lo salvi e lo esegui dal terminale, verrà stampato:
PATH=/usr/bin:/bin:/usr/sbin:/sbin
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
PATH=Extra PATH
Questo succede solo il 10.10. 10.9 stamperà solo un PATH
.
Quindi questa è la causa principale. Cosa sta realmente accadendo? Il link di Emacs utilizza uno script di avvio di Ruby in modo che possa spedire un file binario che funziona in modo ottimale su installazioni di OS X dal 10.6 al 10.10. Questo script di avvio modifica PATH
:
ENV['PATH'] += ':' + File.join(base_dir, "bin-#{arch_version}") +
':' + File.join(base_dir, "libexec-#{arch_version}")
Quindi ENV['PATH']
manipola solo l'istanza prima di PATH
nell'elenco. Quando Emacs viene lanciato, presta attenzione solo all'istanza ultima di PATH
. Quale è giusto? Bene, POSIX parla di questo caso nelle specifiche :
If more than one string in an environment of a process has the same name, the consequences are undefined.
Ciò significa che nessuno di questi programmi è tecnicamente sbagliato.
Ok, allora perché si comporta in modo diverso da Terminal? Questo perché qualcosa sta filtrando il duplicato PATH
s nell'ambiente quando stai eseguendo da Terminal. Sospetto che Bash. Ma potrebbe anche essere Terminal.app. Ad ogni modo, c'è solo un PATH
nell'ambiente e quindi il launcher e Emacs di Ruby comunicano correttamente.
Quindi qual è la soluzione allora? Penso che il launcher di Ruby debba cambiare per far fronte a questo, dal momento che sembra essere il comportamento predefinito in 10.10. È un peccato, perché è solo più cruft. Fortunatamente (come puoi vedere dallo script di test precedente), Ruby può arrivare a entrambi PATH
s in modo da poter filtrare tutto tranne l'ultima istanza che lo farebbe funzionare allo stesso modo di Emacs.
Modifica: Ora c'è un bug report sul progetto di build di Emacs
Modifica: ora è risolto. Le build notturne dopo l'11 febbraio e le versioni che iniziano con 24.5 dovrebbero funzionare (il 24.5 è attualmente un pretest, ma dovrebbe essere rilasciato a breve).