mantém duplicados fora de $ PATH na origem [duplicada]

21

Eu tenho o seguinte código que é source -d pelo meu .shellrc

PATH="${PATH}:${HOME}/perl5/bin"
PATH="${PATH}:${HOME}/.bin"
export PATH

mas, se eu fizer alterações em outro código e, em seguida, source esse arquivo, meu caminho continuará a ficar cada vez mais longo em cada origem, sempre anexando-as quando elas já estiverem lá. O que posso fazer para evitar isso?

    
por xenoterracide 18.12.2010 / 12:30

4 respostas

11
add_to_PATH () {
  for d; do
    d=$({ cd -- "$d" && { pwd -P || pwd; } } 2>/dev/null)  # canonicalize symbolic links
    if [ -z "$d" ]; then continue; fi  # skip nonexistent directory
    case ":$PATH:" in
      *":$d:"*) :;;
      *) PATH=$PATH:$d;;
    esac
  done
}
add_to_PATH ~/perl5/bin ~/.bin

A linha para canonização de links simbólicos é opcional. Se você removê-lo, remova também a próxima linha (se quiser manter diretórios inexistentes) ou altere-a para

if ! [ -d "$d" ]; then continue; fi

Observe que o método de canonização de links simbólicos apenas garante a unicidade entre os diretórios que foram adicionados por essa função. Ele também não lida com casos de borda como um diretório NFS montado em dois locais ou uma montagem de ligação do Linux.

    
por 18.12.2010 / 15:32
3

Você poderia fazer um teste em torno do comando "acrescentar este diretório ao caminho", que verificaria se foo já está no caminho antes de adicioná-lo, mas não lhe custaria muito.

Primeiro, o teste em si seria caro comparado a acrescentar um elemento duplicado. Em segundo lugar, um elemento redundante mais adiante no caminho não tem efeito sobre o que é executado quando você executa um determinado comando porque o primeiro executável correspondente no caminho ainda será aquele executado. Finalmente, a maioria das shells armazena em cache as ocorrências do caminho anterior em uma tabela de hash, então, da segunda vez que você executa my_command , o caminho nem é pesquisado.

Sobre a única coisa que não anexar entradas redundantes fará com que você tenha um caminho mais bonito, mas a maioria dos caminhos é bem feia para começar. Se este objetivo estético é realmente importante para você, diga-nos qual shell você está usando e posso conjurar uma função para "anexar este caminho apenas se ele não estiver presente".

    
por 18.12.2010 / 14:11
1

Eu uso essas funções que são originadas de um script de inicialização pelo fink no os x (então o crédito vai para os desenvolvedores do fink). Eles funcionam muito bem e eu posso re-source meu .bash_profile sempre que eu quiser. Não me pergunte como eles funcionam ... Eu só sei que eles fazem:)

# define append_path and prepend_path to add directory paths, e.g. PATH, MANPATH
# add to end of path
append_path()
{
  if ! eval test -z "\"\${$1##*:$2:*}\"" -o -z "\"\${$1%%*:$2}\"" -o -z "\"\${$1##$2:*}\"" -o -z "\"\${$1##$2}\"" ; then
    eval "$1=\$$1:$2"
  fi
}

# add to front of path
prepend_path()
{
  if ! eval test -z "\"\${$1##*:$2:*}\"" -o -z "\"\${$1%%*:$2}\"" -o -z "\"\${$1##$2:*}\"" -o -z "\"\${$1##$2}\"" ; then
    eval "$1=$2:\$$1"
  fi
}

Eu posso usá-los assim para acrescentar ou preceder a $PATH ou $MANPATH (eles trabalharão com qualquer variável formatada como $PATH ):

prepend_path PATH $macPortsDir/sbin
prepend_path MANPATH $macPortsDir/man
    
por 18.12.2010 / 21:46
0

Uma coisa que você pode fazer é usar uma variável de ambiente como um protetor. Então defina o env como __<your script>__path_added .

No seu script, você pode apenas testar se isso foi definido antes de adicionar o caminho. Um pouco como você faria com um protetor de cabeçalho C.

    
por 18.12.2010 / 18:00