No Linux e, que eu saiba, todos os sistemas Unix, emuladores de terminal executam shells interativos e sem login por padrão. Isso significa que, para o bash, o shell iniciado irá:
Quando um shell interativo que não é um shell de login é iniciado, o bash lê e executa comandos de
/etc/bash.bashrc
e~/.bashrc
, se esses arquivos existirem. Isso pode ser inibido usando a--norc
opçãoA
--rcfile
opção file forçará o bash a ler e executar comandos do arquivo em vez de/etc/bash.bashrc
e~/.bashrc
.
E para shells de login:
Quando o bash é chamado como um shell de logon interativo ou como um shell não interativo com a
--login
opção, ele primeiro lê e executa comandos do arquivo/etc/profile
, se esse arquivo existir. Depois de ler esse arquivo, ele procura~/.bash_profile
,~/.bash_login
e~/.profile
, nessa ordem, e lê e executa os comandos do primeiro que existe e é legível.A
--noprofile
opção pode ser usada quando o shell é iniciado para inibir esse comportamento.
No OSX, no entanto, o shell padrão (que é o bash) iniciado no terminal padrão (Terminal.app) na verdade origina ~/.bash_profile
ou ~.profile
etc. Em outras palavras, ele atua como um shell de logon.
Pergunta principal : Por que o shell interativo padrão é um shell de login no OSX? Por que a OSX escolheu fazer isso? Isso significa que todas as instruções / tutoriais para itens baseados em shell que mencionam a alteração de itens ~/.bashrc
falharão no OSX ou vice-versa ~/.profile
. Ainda assim, enquanto muitas acusações podem ser feitas na Apple, a contratação de desenvolvedores incompetentes ou idiotas não é uma delas. Presumivelmente, eles tinham uma boa razão para isso, então por quê?
Subquestions: O Terminal.app realmente executa um shell de logon interativo ou mudou o comportamento do bash? Isso é específico do Terminal.app ou é independente do emulador de terminal?
Respostas:
A maneira como ele deve funcionar é que, no momento em que você recebe um prompt de shell, ambos
.profile
e.bashrc
foram executados. Os detalhes específicos de como chegar a esse ponto são de relevância secundária, mas se um dos arquivos não for executado, você terá um shell com configurações incompletas.O motivo pelo qual os emuladores de terminal no Linux (e em outros sistemas baseados em X) não precisam ser executados
.profile
é que normalmente já foram executados quando você efetuou login no X. As configurações.profile
devem ser do tipo que pode ser herdado por subprocessos, portanto, desde que seja executado uma vez quando você efetuar login (por exemplo, via.Xsession
), quaisquer outros subshells não precisarão executá-lo novamente.Como a página wiki Debian vinculada por Alan Shutko explica:
Todas as mesmas regras também são válidas para o OSX, exceto por uma coisa - a GUI do OSX não é executada
.profile
quando você faz login, aparentemente porque tem seu próprio método de carregar configurações globais. Mas isso significa que um emulador de terminal no OSX faz necessidade de correr.profile
(dizendo ao shell lança que é um shell de login), caso contrário você pode acabar com uma concha potencialmente aleijado.Agora, uma espécie de peculiaridade boba do bash, não compartilhada pela maioria dos outros shells, é que ele não será executado automaticamente
.bashrc
se for iniciado como um shell de login. A solução padrão para isso é incluir algo como os seguintes comandos em.bash_profile
:Como alternativa, é possível não ter nenhum
.bash_profile
, e apenas inclua algum código específico do bash no.profile
arquivo genérico para executar,.bashrc
se necessário.Se o OSX usar
.bash_profile
como padrão ou.profile
não fizer isso, é sem dúvida um bug. De qualquer forma, a solução alternativa adequada é simplesmente adicionar essas linhas a.bash_profile
.Edit: Como observa Strugee , o shell padrão no OSX costumava ser o tcsh, cujo comportamento é muito mais saudável a esse respeito: quando executado como um shell de login interativo, o tcsh lê automaticamente ambos
.profile
e.tcshrc
/.cshrc
e, portanto, não precisa de nenhuma solução alternativa, como o.bash_profile
truque Mostrado acima.Com base nisso, tenho 99% de certeza de que a falha do OSX em fornecer um padrão apropriado
.bash_profile
é porque, quando eles mudaram do tcsh para o bash, o pessoal da Apple simplesmente não percebeu essa verruga no comportamento de inicialização do bash. Com o tcsh, esses truques não eram necessários - iniciar o tcsh como um shell de login em um emulador de terminal OSX Just Plain Works e faz a coisa certa sem esses kluges.fonte
.bashrc
irrelevante? Por que eles escolheram fazer todos os shells fazer login em shells? Até onde eu sei, apenas sua última frase trata disso e apenas diz que é um bug..profile
quando o usuário efetua login na GUI, portanto, eles precisam executá-lo posteriormente para obter variáveis de ambiente como$PATH
, normalmente definidas.profile
, configuradas corretamente . O fato de que, como efeito colateral, isso faz com que.bashrc
não seja fornecido, é um bug; você pode discutir se é um bug no bash ou no OSX, mas isso não muda o fato de que o comportamento correto seria garantir que as variáveis de ambiente.profile
e a configuração do bash.bashrc
sejam carregadas..bashrc
fonte.profile
seria uma péssima idéia, pois faria com que cada sub-shell fosse executado novamente.profile
. Se nada mais, isso faria com que os.profile
idiomas comunsexport PATH = "$HOME/bin:$PATH"
continuassem com entradas redundantes$PATH
. Ter.profile
origem.bashrc
faz muito mais sentido, mas somente depois de verificar se o shell em que está sendo executado é, de fato, bash. Ter.bash_profile
fonte de ambos.profile
e.bashrc
, como sugeri acima, é a IMO, a opção mais sensata..profile
", enquanto a resposta para "por que eles não são.bashrc
originários.profile
?" é "porque é um bug!" Sério, isso não pode ser uma decisão intencional; é apenas algo que eles ignoraram, presumivelmente porque, no ecossistema Mac, os projéteis são cidadãos de segunda classe com os quais a maioria dos usuários não deveria lidar. (. Ps Ver também a resposta de strugee para uma explicação histórica, é quase certamente uma regressão do interruptor de tcsh para bash.)A principal razão pela qual os aplicativos do terminal X executam shells sem login por padrão é que, no início dos tempos, sua .Xsession executaria o .profile para configurar seus itens de login iniciais. Então, como tudo já estava configurado, os aplicativos de terminal não precisavam executá-lo, eles podiam executar o .bashrc. A discussão sobre por que isso importaria está em https://wiki.debian.org/DotFiles :
No OS X, os ambientes de usuário não são iniciados por uma pilha de scripts de shell, e o launchd não gera .profile a qualquer momento. (Isso é uma pena, pois significa que é muito mais irritante definir variáveis de ambiente, mas a vida é assim.) Como isso não acontece, quando seria executado .profile? Só se você entrar? Isso parece meio inútil, já que muitas caixas nunca serão alvos de ssh. Também pode fazer com que os terminais executem shell de login por padrão, para que o .profile seja executado em algum momento.
E o .bashrc, então? Isso é inútil? Não. Ele ainda tem o objetivo que tinha nos dias do VT100. É usado sempre que você abre um shell que não seja a janela do Terminal. Portanto, se você sair do Emacs ou vi, ou se fizer um usuário su.
fonte
.profile
fontes do Debian.bashrc
, não por que o OSX decidiu fazer todos os shells fazer login por padrão. Na verdade, você está respondendo a outra pergunta minha , e obrigado! No entanto, sua resposta não explica a opção OSX e a citação do Debian é completamente irrelevante aqui, tanto quanto eu posso dizer (por favor, deixe-me saber se estou apenas perdendo o ponto). A maneira OSX torna o.bashrc
etc inútil e não o torna.profile
mais útil.Não sei por que eles teriam feito isso. No entanto, aqui está o meu palpite.
Para começar, vale a pena notar que em um sistema GNU / Linux, é claro que você pode mudar para vt1, vt2, etc. Você obtém um shell de login lá. Em um sistema OS X, não há equivalente. A única maneira de acessar os fundamentos do UNIX é através de um emulador de terminal ou através do modo de usuário único (exoneração de responsabilidade: nunca usei o modo de usuário único; é o IIRC controlado por linha de comando, mas posso estar errado). Portanto, no OS X, qualquer que seja o padrão no emulador, é o padrão para todo o sistema.
Agora, por que você tornaria o padrão um shell de login? Existem algumas razões (leia-se: não muitas) para pensar nisso.
tcsh
. Esse é um palpite o mais selvagem possível, mas pode ser quetcsh
normalmente algo tenha acontecido quando executado como um shell de login, e o padrão histórico permaneceu. (Duvido, no entanto - talvez um dos regulares mais velhos pudesse nos dizer.)Honestamente, eu uso o Darwin há ~ 6 anos e não consigo responder a essa pergunta corretamente. Realmente não faz sentido para mim também.
Para responder à sua subquestão,
bash
não está corrigido nem nada (pelo menos para isso). O emulador de terminal padrão executa shells de login por padrão e, presumivelmente, o iTerm copia isso.fonte
.profile
e.tcshrc
/.cshrc
sem exigir kluges como o que eu dei na minha resposta. Dado isso, suspeito que esse comportamento seja uma regressão não corrigida causada pela mudança de tcsh para bash..login
e.tcshrc
/.cshrc
? Não faria sentido que o tcsh fosse fonte.profile
; normalmente contém comandos comsh
sintaxe quetcsh
não serão aceitos. Não tenho macOS, mas fiz/bin/tcsh
meu shell de login no Ubuntu 16.04..profile
não é originário. O tcsh (1) não menciona esse arquivo, nem o tcsh (1) .Esta é uma atualização para o status atual: as respostas ficaram obsoletas à medida que novas versões do MacOSX foram lançadas e o comportamento do login foi alterado.
Esta pergunta foi feita e respondida em 2014. Pesquisei o assunto na tentativa de criar um conjunto .bashrc e .bash_profile comum para usar em diferentes distribuições Linux e BSD (como eles chamam, se não forem distribuições).
Recentemente, comprei um Mac Mini usado com o Sierra instalado, agora tenho sistemas com 10.6, 10.10, 10.11 e 10.12. Embora eu tenha analisado os mais antigos (deixando pistas sobre o status anterior), a instalação do 10.12 Sierra é intocada.
Resultados: No 10.12 Sierra, NÃO há .bashrc, .bash_profile ou .profile padrão criados. No / etc, existem bashrc, bashrc_Apple_Terminal e profile. Conteúdo de / etc / profile:
Conteúdo de / etc / bashrc:
O script / etc / bashrc_Apple_Terminal define a variável PROMPT_COMMAND e define um mecanismo para preservar o estado da sessão para cada terminal; se o aplicativo do terminal for encerrado, o status da sessão anterior será restaurado quando o aplicativo for reiniciado. Caso contrário, quase nada ($ PS1 mínimo) é definido em / etc / bashrc, deixando qualquer outra personalização ($ PS1 real, aliases, funções) a ser definida nas configurações ~ / .bashrc e $ PATH em .bash_profile (ou em .profile , proveniente de .bash_profile).
Confirmei que o iTerm2 se comporta da mesma maneira que o aplicativo Terminal, exceto que o comportamento padrão de iniciar uma sessão de logon é visível e pode ser editado.
Se você executar uma sessão de terminal X11 (agora XQuartz) XTerm, verá uma sessão sem login, a mesma de um sistema Linux; .bash_profile (ou .profile) é ignorado e você obtém .bashrc.
E aqui está a minha resposta:
Embora o aplicativo Terminal afirme ser um xterm (TERM = xterm-256color), ele não define a variável $ DISPLAY a menos que o X11 esteja instalado. Estamos vendo uma simulação de um ambiente X, mas não completamente real. Se você fizer o SSH em outro sistema com a opção -X (ativar o encaminhamento do X11), ela falhará porque não há variável $ DISPLAY. Se você instalou o X11 e, em seguida, o SSH em outro sistema, o encaminhamento do X11 será bem-sucedido.
Conclusão (e resposta curta): o aplicativo Terminal não é um terminal X11 verdadeiro (não define $ DISPLAY); ele se comporta muito mais como um logon SSH do que uma sessão XTerm, pois deve ser uma sessão de logon para definir valores de / etc / profile e ~ / .bash_profile ou ~ / .profile
fonte
As respostas acima explicado a razão pela qual conchas interativos são shells de login no MacOS por padrão: ajustes no
/etc/profile
,~/.profile
são herdadas por um escudo non-login em sistemas baseados em X, mas não no MacOS . Aqui, quero lembrar que você deve sempre usar o shell de login no macOS devido à existência depath_helper
:Se você estiver usando um shell sem login, alguns caminhos não serão importados.
Eu acho que é sempre uma boa ideia para o desenvolvedor colocar um arquivo
/etc/paths.d
para importar seus valores de caminho, mas não para vincular os binários solicitáveis em locais como/usr/bin
ou/bin
. (O padrãoPATH
é/usr/bin:/bin:/usr/sbin:/sbin
. Nem todo mundo usa o Homebrew ou o MacPorts adicionando valores personalizadosPATH
. Portanto, nem sempre há um lugar seguro para colocar os links simbólicos dos comandos que podem ser chamados.)Aqui está um exemplo de arquivos em
/etc/paths.d
. Basicamente, você está colocando um valor por linha.Referência:
man path_helper
fonte