Configurando a variável PATH em / etc / environment vs .profile

58

Onde é o local preferido para definir o ambiente PATH?

~/.profileou /etc/environment?

Qual é o caso quando PATHé definido nos dois lugares? O resultado final é uma concatenação de ambos os valores definidos nesses dois lugares?

pkaramol
fonte
A última atribuição a PATH prevalece, é claro. A maioria dos scripts o define explicitamente no início do script.
AlexP
3
Veja help.ubuntu.com/community/… .
edwinksl

Respostas:

71

Resumo:

  • Se você deseja adicionar um caminho (por exemplo /your/additional/path) à sua PATHvariável apenas para o usuário atual e não para todos os usuários do seu computador, você normalmente o coloca no final de ~/.profileum desses dois exemplos:

    PATH="/your/additional/path:$PATH"
    PATH="$PATH:/your/additional/path"
    

    Observe que as prioridades do caminho estão descendo da esquerda para a direita, portanto o primeiro caminho tem a prioridade mais alta. Se você adicionar seu caminho à esquerda de $PATH, ele terá a maior prioridade e os executáveis ​​nesse local substituirão todos os outros. Se você adicionar seu caminho à direita, ele terá a menor prioridade e os executáveis ​​de outros locais serão preferidos.

  • No entanto, se você precisar definir essa variável de ambiente para todos os usuários, ainda não recomendaria tocar, /etc/environmentmas criar um arquivo com o nome do arquivo terminado .shem /etc/profile.d/. O /etc/profilescript e todos os scripts inseridos /etc/profile.dsão o equivalente global do pessoal de cada usuário ~/.profilee são executados como scripts shell regulares por todos os shells durante sua inicialização.


Mais detalhes:

  • /etc/environmenté um arquivo de configuração em todo o sistema, o que significa que é usado por todos os usuários. Ele pertence a ele root, portanto, você precisa ser um usuário administrador e usá sudo-lo para modificá-lo.

  • ~/.profileé um dos scripts de inicialização do shell pessoal do seu usuário. Todo usuário tem um e pode editar seu arquivo sem afetar os outros.

  • /etc/profilee /etc/profile.d/*.shsão os scripts de inicialização global equivalentes a ~/.profilecada usuário. Os scripts globais são executados antes dos scripts específicos do usuário; e o main /etc/profileexecuta todos os *.shscripts /etc/profile.d/antes de sair.


  • O /etc/environmentarquivo normalmente contém apenas esta linha:

    PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"
    

    Ele define a PATHvariável para todos os usuários no sistema para esse valor padrão, que não deve ser alterado de maneira importante. Pelo menos você não deve remover qualquer um dos caminhos importantes, como /bin, /sbin, /usr/bine /usr/sbina partir dele.

    Este arquivo é lido como um dos primeiros arquivos de configuração por todos os shell de todos os usuários. Observe que não é um script de shell . É apenas um arquivo de configuração que é analisado de alguma forma e que pode conter apenas atribuições de variáveis ​​de ambiente!

  • O ~/.profilearquivo pode conter muitas coisas; por padrão, ele contém, entre outras coisas, uma verificação da existência de um ~/bindiretório e a adiciona à PATHvariável existente do usuário , desta forma (em versões mais antigas do Ubuntu anteriores ao 16.04 - o que inclui incondicionalmente - e no 18.04 , que também adiciona "~ / .local / bin"):

    # set PATH so it includes user's private bin if it exists
    if [ -d "$HOME/bin" ] ; then
        PATH="$HOME/bin:$PATH"
    fi
    

    Você vê que o valor antigo de PATHé reutilizado aqui e o novo caminho é anexado apenas ao início, em vez de sobrescrever tudo. Quando você deseja adicionar novos caminhos manualmente, também deve sempre manter o $PATHvalor antigo em algum lugar da nova string.

    Esse script de inicialização é lido apenas pelos shells do usuário ao qual ele pertence, mas há outra condição:

    # ~/.profile: executed by the command interpreter for login shells.
    # This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
    # exists.
    

    Portanto, se você usar o shell Bash padrão, verifique se não possui um ~/.bash_profileou ~/.bash_loginse deseja que as alterações ~/.profiletenham um efeito para o usuário.


Para um entendimento completo sobre variáveis ​​de ambiente, consulte: https://help.ubuntu.com/community/EnvironmentVariables


Pergunta relacionada: diferença entre o arquivo bash.bashrc e / etc / environment

Byte Commander
fonte
2
Hoje em dia ~/.profilenão verifica a existência de ~/bin, mas simplesmente tem a seguinte linha:PATH="$HOME/bin:$HOME/.local/bin:$PATH"
Gunnar Hjalmarsson
11
@GunnarHjalmarsson Defina "hoje em dia", por favor? Estou executando o 16.04 e é assim que parece.
Byte Commander
2
/etc/skel/.profileno 16.04 tem a linha que eu mencionei. Aparentemente, você criou seu usuário em uma versão anterior.
Gunnar Hjalmarsson
11
@GunnarHjalmarsson Obrigado pela informação - até cerca de cinco minutos atrás , eu pensei que o padrão ~/.profileainda tinha isso também, mas você está certo - /etc/skel/.profilenão o possui no meu sistema 16.04 atualizado (e uma conta de usuário criada ao instalar o 16.04 no outra máquina não a possui .profile).
Eliah Kagan
2
"... executado como scripts shell regulares por todos os shells durante sua inicialização." Eu acho que isso é enganoso. Pode-se sugerir (para alguns) que simplesmente abrir um shell de terminal sem login a partir da área de trabalho da GUI executará / etc / profile, o que não acontecerá. askubuntu.com/questions/155865/...
Hawkeye Parker
22

Esta resposta é principalmente sobre a ordem na qual variáveis ​​de ambiente como PATHsão atribuídas quando especificadas em diferentes arquivos de configuração. Também abordo onde você costuma defini-los, mas a lista abaixo não lista os arquivos na ordem em que você deve considerá-los. Para obter informações gerais sobre configuração PATHe outras variáveis ​​de ambiente no Ubuntu, também recomendo a leitura de EnvironmentVariables e as outras respostas a esta pergunta.

O local preferido para definir PATHdepende de quais usuários você precisa definir e quando e como deseja que seja definido. Parte de sua decisão será se você deseja definir uma variável de ambiente para todos os usuários ou por usuário. Se você não tiver certeza, recomendo configurá-lo para apenas um usuário (por exemplo, sua conta) e não para todo o sistema.

Como AlexP diz , a PATHvariável de ambiente terá o valor que foi atribuído mais recentemente . Na prática, na maioria das vezes que você define PATH, você inclui o valor antigo de PATHno novo valor, para que as entradas anteriores sejam mantidas.

Assim, na prática, quando PATHé definido a partir de vários arquivos, geralmente contém as entradas fornecidas em todos os arquivos. Mas isso só acontece porque todos os arquivos que o configuram, exceto o primeiro, geralmente fazem referência à PATHprópria variável, fazendo com que seu valor antigo seja incluído no novo.

Portanto, você está efetivamente solicitando a ordem na qual as PATHconfigurações em vários arquivos entram em vigor.

Os locais comuns e de uso geral a PATHserem definidos estão listados abaixo na ordem em que entram em vigor quando um usuário efetua login, não na ordem em que você normalmente deve considerá-los . Cada um dos locais listados abaixo é uma escolha razoável para a configuração PATH em algumas situações , mas apenas alguns são boas escolhas na maioria das vezes.

Na lista abaixo, você verá alguns nomes de diretório como ~/.profile. Caso você não esteja familiarizado com a expansão de til , ~/consulte o diretório inicial do usuário atual. Eu uso principalmente essa sintaxe para compactar. É suportado em scripts de shell, mas não nos arquivos de configuração do PAM.

1. Para todos os usuários: /etc/environment

O PAM no Ubuntu faz com que as variáveis ​​de ambiente listadas /etc/environmentsejam definidas, se esse arquivo existir, o que, por padrão, existe. É assim que as variáveis ​​de ambiente para todos os usuários são mais comumente definidas.

$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games"

Se você deve definir variáveis ​​de ambiente para todas as contas de usuário, em vez de apenas sua conta de usuário, modificar esse arquivo provavelmente é sua melhor escolha. Eu recomendo fazer o backup primeiro. Uma maneira de fazer backup desse arquivo é executar:

sudo cp /etc/environment /etc/environment.orig

A .origextensão não é especificamente necessária - você pode se sentir bem em nomear o arquivo de backup de qualquer coisa que não seja confusa ou já esteja sendo usada. (Além de .orig, .old, .backupe .baksão comuns.)

Você pode editar esse arquivo em qualquer das maneiras que você pode editar qualquer outro arquivo como o usuário root ( sudoedit /etc/enviromnment, sudo nano -w /etc/environment, gksudo gedit /etc/environment, etc.)

/etc/environmentnão suporta a inclusão automática do valor antigo de uma variável. Mas isso geralmente não é necessário, pois na maioria das vezes você definiria uma variável de ambiente para todos os usuários editando /etc/environment, você desejaria que esse fosse seu valor inicial quando o usuário efetuar login, de qualquer maneira. O usuário pode alterá-lo como quiser. Normalmente, é bom que os usuários possam fazer isso.

2. Para todos os usuários: /etc/security/pam_env.conf

O PAM lê variáveis ​​de ambiente para todos os usuários de /etc/security/pam_env.conf, especificadas com a mesma sintaxe usada nos ~/.pam_environmentarquivos por usuário (veja abaixo).

Quando a mesma variável de ambiente é configurada em ambos /etc/environmente /etc/security/pam_env.conf, o valor in pam_env.confé usado - mesmo que esse valor seja especificado como DEFAULTe não OVERRIDE.

No entanto, quando você substitui uma linha environmentpor uma pam_env.conf, pode incluir o conteúdo do valor substituído. Consulte a seção abaixo .pam_environmentpara obter detalhes (pois usa a mesma sintaxe).

Geralmente, não é necessário editar pam_env.confe você deve ter muito cuidado, se o fizer , pois uma linha malformada geralmente impedirá o logon de todas as contas de usuário normais! Por exemplo, o padrão pam_env.confcontém as linhas:

#PATH           DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11

Isso é apresentado como um dos vários exemplos. Uma das coisas que ilustra é como dividir uma tarefa em várias linhas \. Suponha que você descomente apenas a primeira linha, mas esqueceu de descomentar a segunda linha:

PATH           DEFAULT=${HOME}/bin:/usr/local/bin:/bin\
#:/usr/bin:/usr/local/bin/X11:/usr/bin/X11

Não faça isso!

Acabei de testar isso por acidente e impediu que todos os usuários fizessem login com êxito. Para corrigi-lo, tive que inicializar no modo de recuperação e alterá-lo novamente. (Felizmente, fiz isso em uma máquina virtual que uso apenas para testar coisas, para que não me causasse nenhum problema.)

3. Para um usuário: .pam_environmentno diretório inicial do usuário

Uma das maneiras de definir uma variável de ambiente para um único usuário é editar (ou criar) .pam_environmentem seu diretório inicial. Os valores definidos neste arquivo substituem os definidos no /etc/environmentarquivo global .

.pam_environmentnão faz parte do esqueleto dos arquivos que são copiados na pasta inicial do usuário quando a conta do usuário é criada inicialmente. No entanto, se você criar esse arquivo em seu diretório pessoal, poderá usá-lo para definir variáveis ​​de ambiente como PATH. Diferente /etc/environment(mas semelhante /etc/security/pam_env.conf), os .pam_environmentarquivos por usuário suportam a expansão do valor antigo de uma variável de ambiente para uma nova. No entanto, eles não são scripts de shell, e você deve usar uma sintaxe especial para conseguir isso, o que difere um pouco da sintaxe que você usaria em um arquivo como .profile.

Por exemplo, se você tiver um bin2diretório em seu diretório pessoal que deseja adicionar ao final PATH, poderá fazer isso adicionando esta linha a .pam_environment:

PATH DEFAULT=${PATH}:/home/@{PAM_USER}/bin2

Veja a ~/.pam_environmentsubseção de EnvironmentVariables (a partir da qual o exemplo acima está bem adaptado) man pam_enve man pam_env.confpara mais detalhes.

Embora essa tenha sido apontada como a maneira preferida pelos usuários do Ubuntu de alterar ou adicionar variáveis ​​de ambiente e ainda ser considerada uma opção razoável e aceitável, você deve ter cuidado ao editar.pam_environment . Como as edições em todo o sistema /etc/security/pam_env.conf(veja acima), uma linha malformada no .pam_environmentarquivo do usuário impedirá que os logins sejam bem-sucedidos. (Eu testei isso -. De propósito desta vez) Para obter informações sobre como as recomendações têm evoluído , veja Gunnar Hjalmarsson de comentários abaixo e esta ubuntu-develdiscussão .

Esse erro é muito menos sério, em geral , do que uma linha malformada pam_env.conf, porque afeta apenas um usuário. No entanto, no caso de um sistema Ubuntu de desktop com apenas uma conta de usuário que permita logins, um erro durante a edição .pam_environmentserá tão ruim quanto a edição pam_env.conf- se você ainda não estiver logado, não poderá para corrigi-lo sem inicializar no modo de recuperação (ou de um USB ativo, etc.).

(Se você tiver outras contas de usuário, poderá fazer login como outro usuário e corrigir o problema. Mesmo que não seja administrador e não possa sudofazer root, ele ainda poderá ser executado e solicitado a digitar sua senha (não a deles) A conta de convidado , no entanto, não pode fazer isso, pois é proibido usar para assumir a identidade de outro usuário.)su your-accountsu

4. Para todos os usuários: /etc/profilee arquivos dentro/etc/profile.d/

Os shells compatíveis com Bourne (incluindo basho shell do usuário padrão no Ubuntu) executam os comandos /etc/profilequando chamados como um shell de logon.

O Ubuntu /etc/profile.dtermina com:

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

Isso faz com que os comandos em qualquer arquivo no /etc/profile.d/diretório cujo nome termine também .shsejam executados.

A maioria dos gerenciadores de exibição faz com que os comandos /etc/profile(e, portanto, os arquivos entrem /etc/profile.d) sejam executados também para logins gráficos. No entanto, nem todos o fazem, e esse é um argumento significativo a favor do uso dos recursos fornecidos pelo PAM (veja acima) - a menos que nunca haja logins gráficos neste sistema, o que pode ser o caso, por exemplo, se for um servidor sem GUI instalada.

É tradicional definir variáveis ​​de ambiente em todo o sistema /etc/profile, mas isso geralmente não é mais a melhor escolha. Se você não pode definir uma variável de ambiente /etc/environmente deve defini-la para todos os usuários, provavelmente é melhor criar um novo arquivo do /etc/profile.d/que editar- /etc/profilese. Uma razão para isso é que, quando o Ubuntu é atualizado, pode haver um novo /etc/profilearquivo padrão . Dependendo de como você executa a atualização, o arquivo antigo (com suas alterações) será mantido, precedendo esse arquivo de configuração atualizado específico, ou você será solicitado a lidar com a situação.

Quando a mesma variável de ambiente é configurada em /etc/profileum e mais arquivos /etc/profile.d, qual é a última realizada? Isso depende se os comandos /etc/profilenesse conjunto são exibidos antes ou depois da origem dos arquivos profile.d(pelo código que citei acima). Os comandos /etc/profilesão executados na ordem em que aparecem.

/etc/profileé um script de shell e sua sintaxe não é a mesma dos arquivos de configuração do PAM discutidos acima . Sua sintaxe é a mesma que a do ~/.profilearquivo por usuário (veja abaixo).

Se você precisar escrever um código que decida se deseja ou não adicionar um diretório específico PATH(e fazer isso para todos os usuários), não poderá usar /etc/environmentou /etc/security/pam_env.conffazer isso. Esta é talvez a principal situação em que é melhor usar /etc/profileou /etc/profile.d/substituir.

5. Para um usuário: .bash_profileno diretório inicial do usuário

Se um usuário tiver ~/.bash_profile, o bash o usa em vez de ~/.profileou ~/.bash_login(veja abaixo). Normalmente, você não deve ter um .bash_profileem seu diretório pessoal.

Se você o fizer, geralmente deve conter um comando para a origem ~/.profile(por exemplo, . "$HOME/.profile"). Caso contrário, o conteúdo do .profilearquivo por usuário não será executado.

6. Para um usuário: .bash_loginno diretório inicial do usuário

Se um usuário tiver ~/.bash_login, o bash o usa em vez de ~/.profile(veja abaixo), a menos que ~/.bash_profileexista, nesse caso nenhum dos outros será usado, a menos que seja proveniente de `~ / .bash_login.

Assim como em geral .bash_profile, você não deve ter um .bash_loginarquivo no diretório inicial.

7. Para um usuário: .profileno diretório inicial do usuário.

Quando um shell no estilo Bourne é executado como um shell de login, ele executa os comandos /etc/profile(o que normalmente inclui comandos que fazem com que os comandos nos arquivos /etc/profile.d/sejam executados - veja acima). Depois disso, ele executa os comandos no .profilediretório inicial do usuário. Este arquivo é separado para cada usuário. (Bash realmente funciona .bash_profileou .bash_loginao invés, se existirem -., Mas, para os usuários em um sistema Ubuntu, esses arquivos raramente deve ou não existem Para detalhes, ver acima e 6,2 Bash arquivos de inicialização no manual Bash .)

~/.profileé, portanto, o principal local para o usuário colocar comandos que são executados quando fazem logon. É o local tradicional para você definir o seu PATH, mas como o Ubuntu possui o módulo pam_env e suporta ~/.pam_environment, você deve considerar usá-lo.

Assim como /etc/profilenem todos os gerenciadores de exibição executam esse arquivo para logins gráficos, embora a maioria faça. Esta é uma razão para preferir ~/.pam_environmentpara definir variáveis de ambiente (tanto quanto se pode preferir /etc/environmenta /etc/profile).

Você pode expandir variáveis de ambiente, incluindo PATH-se, quando você define PATHna .pam_environment(veja acima). No entanto, se você precisar configurá-lo PATHde uma maneira mais sofisticada, talvez seja necessário usá-lo .profile. Em particular, se você quiser verificar se existe um diretório sempre que um usuário efetuar login e adicioná-lo somente se PATHexistir, não poderá usar seu .pam_environmentarquivo para adicioná-lo ao seu PATH.

Por exemplo, o .profilearquivo por usuário padrão no Ubuntu costumava terminar com:

# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

Veja Gunnar Hjalmarsson 's comentário sobre a resposta de Byte Commander para mais detalhes.

Isso verifica se você possui um binsubdiretório do diretório inicial. Nesse caso, ele adiciona esse subdiretório ao início do seu PATH.

Essa lista omite algumas possibilidades.

Existem outras maneiras pelas quais as variáveis ​​de ambiente são definidas quando os usuários efetuam login, que dependem mais do tipo de login. Por exemplo, você pode ocasionalmente ter variáveis ​​de ambiente definidas apenas para logins gráficos ou apenas para logons remotos baseados em SSH. A lista acima não cobre esses casos.

Eu deixei de fora alguns arquivos nos quais as pessoas às vezes definem variáveis ​​de ambiente, como ~/.bashrce /etc/bash.bashrc, porque geralmente não são locais recomendados para configurar PATHe é raro que você realmente os use para esse fim. Se você usar esses arquivos para adicionar diretórios PATH, eles às vezes serão adicionados muitas vezes e ficarão muito confusos quando você examinar $PATH. (Em casos extremos, isso pode tornar as coisas mais lentas, mas geralmente é apenas uma questão de manter tudo limpo e compreensível.)

Como bashé o shell de login padrão do Ubuntu para os usuários, e a maioria dos usuários o utiliza ou algum outro shell compatível com POSIX, omiti informações sobre como as variáveis ​​de ambiente são definidas em outros shells não-Bourne, como o tcsh.

Eliah Kagan
fonte
11
[comentário nº 1 de 2] Obrigado por esta extensa descrição! (Fiz uma edição menor.) No entanto, tenho dúvidas quanto à (s) maneira (s) recomendada (s). Alguns anos atrás, EnvironmentVariables mencionou /etc/environment/ ~/.pam_environmentcomo os arquivos recomendados. Depois de ter consultado os desenvolvedores , mudei para neutro entre PAM e /etc/profile.d/*.sh/ ~/.profile, e continuo a olhar dessa maneira.
Gunnar Hjalmarsson
11
[comentário nº 2 de 2] Você mencionou alguns argumentos a favor do PAM. Argumentos importantes a favor de /etc/profile.d/*.sh/ ~/.profilesão que a sintaxe é mais simples e que o lightdm / gdm perdoa em caso de erros (nem mesmo os erros de sintaxe impedem o login, mas resultam em mensagens de aviso).
Gunnar Hjalmarsson
Quando você disse pam_env.so, você quis dizer pam_env.conf?
Johan Boulé
@ JohanBoulé Sim, eu quis dizer pam_env.conf. Obrigado! Eu editei para corrigi-lo.
Eliah Kagan
3

O arquivo / etc / environment não é um arquivo de script que não pode ser exportado para lá e não suporta expansão variável do tipo $ HOME, apenas pares simplevariable = value. Portanto, para usar esse arquivo, é necessário simplesmente anexar o caminho à definição existente, especificamente para configurações de variáveis ​​de ambiente em todo o sistema. Um por linha. Especificamente, esse arquivo armazena as configurações de local e de caminho em todo o sistema.

~ / .profile - Este arquivo é executado sempre que um shell bash é executado, geralmente é o recomendado para variáveis ​​de ambiente, no entanto, tem a desvantagem de ser invocado apenas por shells de login, portanto, para que ele entre em vigor, você precisará para sair e entrar novamente - ou pelo menos, inicie um novo shell de login.

eGhoul
fonte
1

O local preferido para definir variáveis ​​ambientais depende de várias coisas:

  1. Você é o único que usa o computador:
    • Nesse caso, o melhor local para configurá-lo seria, /etc/environmentjá que não há perigo de acesso não autorizado.
  2. Se o sistema for usado por muitos
    • Se as variáveis deveriam ser acessadas por todos, o local seria /etc/environment, mas
    • se usuários individuais deveriam ter selecionado acesso a eles, então cada um deve definir o deles~/.profile para cada usuário do sistema, uma vez que está localizado no diretório inicial de cada usuário.

O sistema irá ler /etc/environmentantes de ler ~/.profile. Nenhuma concatenação ocorre e, como Alex P disse, a última atribuição ao caminho prevalece.

Para uma análise mais detalhada dos fatores que determinam como ~/.profilee se /etc/environmentdesenrola com outros locais, vá aqui e aqui , pois esses fatores influenciarão a maneira como você usa esses locais.

George Udosen
fonte