Sou um grande fã da interface POSIX, mas realmente acho o Bash nojento. Eu prefiro muito mais Ruby! Já que preciso modificar meus arquivos de configuração do shell de vez em quando mexendo com eles de PATH
maneiras desagradáveis, prefiro cuidar disso com uma linguagem elegante e divertida de programar.
Como a propagação de ambiente entre ambientes shell é unilateral, pensei em uma boa solução na qual poderia usar Ruby para realizar toda a lógica de modificação da PATH
variável, enquanto ainda captura os resultados em meu .bashrc
script de configuração. Ao definir a função setpath() { $(ruby ~/.pathconfig.rb SET); }
no meu .bashrc
, posso configurar PATH
exatamente como preciso em qualquer ponto. Ao armazenar o original PATH
em um ambiente var ao mesmo tempo, posso facilmente retornar o PATH
estado original com um único comando. Brilhante!
Ruby é realmente conveniente para isso porque você pode organizar bem as entradas de caminho na ordem que desejar e, em seguida, usar truques legais como o |
operador de união para fundir perfeitamente com o existente PATH
. Além disso, coisas como classificar e executar operações complexas em coleções não são complicadas com Ruby; você pode implementar facilmente diretivas funcionais ou baseadas em regras para decidir o seu PATH
.
Ah, e a única razão pela qual uso o nome engraçado VANILLA_PATH
é porque simplesmente pensei que reduziria a probabilidade de conflito com outros nomes de variáveis; você nunca sabe quem está modificando o ambiente junto com seu script bacana.
#!/usr/bin/env ruby
#
# PATH management via Ruby
#
# The following two functions accompany this script and
# shoudl be defined in ~/.bashrc, ~/.profile, or ~/.bash_profile:
#
# setpath() { $(ruby ~/.pathconfig.rb SET); }
# resetpath() { $(ruby ~/.pathconfig.rb UNSET); }
#
abort unless ARGV.first
if ARGV.first == 'SET'
HOME = ENV['HOME']
additions = [
# Ensure binstubs have priority within a local Bundler project, and reduce use of `bundle exec`
'./.bundle/bin',
# NPM - Node.js package manager
'/usr/local/share/npm/bin',
"#{HOME}/usr/local/share/npm/bin"
]
# Sort the path entries using Ruby's comparison operator, to achieve ideal precedence
newpath = ENV['PATH'].split(':').uniq.sort! {|a, b| b.length <=> a.length }
# Prepend additions to PATH, and remove duplicates with Set#union
newpath = (additions | newpath).join ':'
oldpath = ENV['PATH']
else
newpath = ENV['VANILLA_PATH']
oldpath = nil
end
puts "export PATH=#{newpath};"
puts "export VANILLA_PATH=#{oldpath}"