Introdução
Ao interagir com o seu servidor através de uma sessão shell, há muitas informações que a sua shell compila para determinar o seu comportamento e acesso a recursos. Algumas destas definições estão contidas nas definições de configuração e outras são determinadas pela entrada do utilizador.
Uma forma de a shell manter o registo de todas estas definições e detalhes é através de uma área que mantém chamada ambiente. O ambiente é uma área que a shell constrói sempre que inicia uma sessão que contém variáveis que definem as propriedades do sistema.
Neste guia, discutiremos como interagir com o ambiente e ler ou definir variáveis ambientais e da shell interactivamente e através de ficheiros de configuração.
Como Funciona o Ambiente e Variáveis Ambientais
Cada vez que uma sessão da shell se desdobra, ocorre um processo de recolha e compilação de informação que deve estar disponível para o processo da shell e os seus processos filhos. Obtém os dados para estas definições a partir de uma variedade de ficheiros e definições diferentes no sistema.
O ambiente fornece um meio através do qual o processo shell pode obter ou definir definições e, por sua vez, passá-las aos seus processos filhos.
O ambiente é implementado como cordas que representam pares de valores chave. Se forem passados múltiplos valores, são tipicamente separados por dois pontos (:
) caracteres. Cada par será geralmente parecido com isto:
KEY=value1:value2:...
Se o valor contiver um espaço branco significativo, são usadas citações:
KEY="value with spaces"
As chaves nestes cenários são variáveis. Podem ser um de dois tipos, variáveis ambientais ou variáveis shell.
As variáveis ambientais são variáveis definidas para a shell actual e são herdadas por quaisquer shells ou processos de criança. As variáveis ambientais são utilizadas para passar informação para processos que são gerados a partir da shell.
Variáveis de concha são variáveis que estão contidas exclusivamente dentro da shell na qual foram definidas ou definidas. São frequentemente usadas para manter o registo de dados efémeros, como o directório de trabalho actual.
Por convenção, estes tipos de variáveis são geralmente definidos usando todas as letras maiúsculas. Isto ajuda os utilizadores a distinguir as variáveis ambientais dentro de outros contextos.
Printing Shell and Environmental Variables
Cada sessão de shell mantém um registo das suas próprias shell e variáveis ambientais. Podemos aceder a estas de algumas formas diferentes.
Podemos ver uma lista de todas as nossas variáveis ambientais usando os comandos env
ou printenv
. No seu estado padrão, devem funcionar exactamente da mesma forma:
- printenv
Isto é bastante típico da saída de ambos printenv
e env
. A diferença entre os dois comandos é apenas aparente na sua funcionalidade mais específica. Por exemplo, com printenv
, é possível solicitar os valores de variáveis individuais:
- printenv SHELL
Output/bin/bash
Por outro lado, env
permite-lhe modificar o ambiente em que os programas são executados passando um conjunto de definições de variáveis para um comando como este:
- env VAR1="value" command_to_run command_options
Desde que, como aprendemos acima, os processos infantis herdam tipicamente as variáveis ambientais do processo dos pais, isto dá-lhe a oportunidade de sobrepor valores ou adicionar variáveis adicionais para a criança.
Como pode ver na saída do nosso comando printenv
, existem bastantes variáveis ambientais configuradas através dos nossos ficheiros de sistema e processos sem a nossa entrada.
Estes mostram as variáveis ambientais, mas como vemos as variáveis shell?
O comando set
pode ser usado para isto. Se escrevermos set
sem quaisquer parâmetros adicionais, obteremos uma lista de todas as variáveis shell, variáveis ambientais, variáveis locais, e funções shell:
- set
Esta é normalmente uma lista enorme. Provavelmente pretende canalizá-la para um programa de pager para lidar mais facilmente com a quantidade de saída:
- set | less
A quantidade de informação adicional que recebemos de volta é um pouco avassaladora. Provavelmente não precisamos de conhecer todas as funções de bash que são definidas, por exemplo.
Podemos limpar a saída especificando que set
deve funcionar no modo POSIX, que não imprimirá as funções shell. Podemos executar isto numa sub-esfera para que não altere o nosso ambiente actual:
- (set -o posix; set)
Isto irá listar todas as variáveis ambientais e de shell que estão definidas.
Podemos tentar comparar esta saída com a saída do comando env
ou printenv
para tentar obter uma lista apenas de variáveis shell, mas isto será imperfeito devido às diferentes formas que estes comandos emitem a informação:
- comm -23 <(set -o posix; set | sort) <(env | sort)
Isto provavelmente incluirá ainda algumas variáveis ambientais, devido ao facto de os comandos set
não citarem os valores das cadeias de caracteres.
Isto deve ainda dar-lhe uma boa ideia das variáveis ambientais e de shell que são definidas na sua sessão.
Estas variáveis são utilizadas para todo o tipo de coisas. Elas fornecem uma forma alternativa de definir valores persistentes para a sessão entre processos, sem escrever alterações num ficheiro.
Variáveis Comuns Ambientais e de Shell
algumas variáveis ambientais e de shell são muito úteis e são referenciadas com bastante frequência.
Aqui estão algumas variáveis ambientais comuns com que se deparará:
-
SHELL
: Isto descreve a shell que irá interpretar quaisquer comandos que digite. Na maior parte dos casos, isto será baseado por defeito, mas outros valores podem ser definidos se preferir outras opções. -
TERM
: Isto especifica o tipo de terminal a emular ao executar a shell. Diferentes terminais de hardware podem ser emulados para diferentes requisitos operacionais. Normalmente não precisa de se preocupar com isto embora. -
USER
: O actual utilizador registado. -
PWD
: O directório de trabalho actual. -
OLDPWD
: O directório de trabalho anterior. Este é mantido pela shell a fim de voltar ao seu directório anterior executandocd -
. -
LS_COLORS
: Isto define códigos de cor que são usados para opcionalmente adicionar saída colorida ao comandols
. Isto é utilizado para distinguir diferentes tipos de ficheiros e fornecer mais informações ao utilizador num relance. -
MAIL
: O caminho para a caixa de correio do utilizador actual. -
PATH
: Uma lista de directórios que o sistema irá verificar quando procurar por comandos. Quando um utilizador digita um comando, o sistema verificará os directórios nesta ordem para o executável. -
LANG
: A linguagem actual e definições de localização, incluindo a codificação de caracteres. -
HOME
: O directório home do utilizador actual. -
_
: O mais recente comando anteriormente executado.
Além destas variáveis ambientais, algumas variáveis shell que verá com frequência são:
-
BASHOPTS
: A lista de opções que foram utilizadas quando a bash foi executada. Isto pode ser útil para descobrir se o ambiente de bash irá funcionar da forma que pretende. -
BASH_VERSION
: A versão de bash a ser executada, em forma legível para o ser humano. -
BASH_VERSINFO
: A versão da bash, em saída legível por máquina. -
COLUMNS
: O número de colunas de largura que estão a ser utilizadas para desenhar a saída no ecrã. -
DIRSTACK
: A pilha de directórios que estão disponíveis com opushd
epopd
comandos. -
HISTFILESIZE
: Número de linhas de histórico de comandos armazenadas num ficheiro. -
HISTSIZE
: Número de linhas do histórico de comandos permitidas na memória. -
HOSTNAME
: O nome da máquina do computador neste momento. -
IFS
: O separador de campo interno para separar a entrada na linha de comando. Por defeito, este é um espaço. -
PS1
: A definição do prompt de comando primário. Esta é usada para definir o aspecto do seu prompt quando inicia uma sessão de shell. OPS2
é utilizado para declarar avisos secundários para quando um comando abrange várias linhas. -
SHELLOPTS
: Opções de shell que podem ser definidas com oset
option. -
UID
: O UID do utilizador actual.
Configurar Shell e Variáveis Ambientais
Para compreender melhor a diferença entre shell e variáveis ambientais, e para introduzir a sintaxe para definir estas variáveis, faremos uma pequena demonstração.
Criar Variáveis Shell
Começaremos por definir uma variável shell dentro da nossa sessão actual. Isto é fácil de realizar; apenas precisamos de especificar um nome e um valor. Vamos aderir à convenção de manter todos os limites para o nome da variável, e defini-lo com uma simples string.
- TEST_VAR='Hello World!'
Aqui, utilizamos citações uma vez que o valor da nossa variável contém um espaço. Além disso, utilizámos citações simples porque o ponto de exclamação é um carácter especial na concha da bash que normalmente se expande para a história da bash, se não for fugido ou colocado entre aspas simples.
Agora temos uma variável da concha. Esta variável está disponível na nossa sessão actual, mas não será transmitida aos processos infantis.
p>Podemos ver isto através do grepping para a nossa nova variável dentro da saída set
:
- set | grep TEST_VAR
Podemos verificar que esta não é uma variável ambiental tentando a mesma coisa com printenv
:
- printenv | grep TEST_VAR
Não deve ser devolvida nenhuma saída.
Vamos tomar isto como uma oportunidade para demonstrar uma forma de aceder ao valor de qualquer shell ou variável ambiental.
- echo $TEST_VAR
OutputHello World!
Como pode ver, referencie o valor de uma variável precedendo-a com um sinal $
. A concha leva isto a significar que deve substituir o valor da variável quando se deparar com isto.
Então agora temos uma variável da concha. Ela não deve ser transmitida a nenhum processo infantil. Podemos desovar uma nova shell de dentro da nossa actual para demonstrar:
- bash
- echo $TEST_VAR
Se digitarmos bash
para desovar uma shell criança, e depois tentarmos aceder ao conteúdo da variável, nada será devolvido. Isto é o que esperávamos.
Voltar à nossa concha original digitando exit
:
- exit
Criar variáveis ambientais
Agora, vamos transformar a nossa variável de concha numa variável ambiental. Podemos fazer isto exportando a variável. O comando para o fazer é adequadamente nomeado:
- export TEST_VAR
Isto irá transformar a nossa variável numa variável ambiental. Podemos verificar isto verificando novamente a nossa listagem ambiental:
- printenv | grep TEST_VAR
OutputTEST_VAR=Hello World!
Desta vez, a nossa variável aparece. Vamos tentar novamente a nossa experiência com a nossa concha infantil:
- bash
- echo $TEST_VAR
OutputHello World!
Grande! A nossa concha infantil recebeu a variável definida pelos seus pais. Antes de sairmos desta concha infantil, vamos tentar exportar outra variável. Podemos definir variáveis ambientais num único passo como este:
- export NEW_VAR="Testing export"
Teste que é exportada como uma variável ambiental:
- printenv | grep NEW_VAR
OutputNEW_VAR=Testing export
Agora, vamos sair de novo para a nossa casca original:
- exit
Vamos ver se a nossa nova variável está disponível:
- echo $NEW_VAR
Nada é devolvida.
Isto porque as variáveis ambientais só são passadas para processos infantis. Não há uma forma integrada de definir as variáveis ambientais da casca do pai. Isto é bom na maioria dos casos e evita que programas afectem o ambiente operacional a partir do qual foram chamados.
A variável NEW_VAR
foi definida como uma variável ambiental na nossa concha infantil. Esta variável estaria disponível para si própria e para qualquer uma das suas conchas e processos infantis. Quando saímos para a nossa concha principal, esse ambiente foi destruído.
Variáveis de Desactivação e Desactivação
Ainda temos a nossa TEST_VAR
variável definida como uma variável ambiental. Podemos alterá-la de volta para uma variável de shell digitando:
- export -n TEST_VAR
Já não é uma variável ambiental:
- printenv | grep TEST_VAR
No entanto, ainda é uma variável de shell:
- set | grep TEST_VAR
Se quisermos desajustar completamente uma variável, seja casca ou ambiental, podemos fazê-lo com o comando unset
:
- unset TEST_VAR
Podemos verificar que já não está definida:
- echo $TEST_VAR
Nada é devolvida porque a variável foi desajustada.
Configurar variáveis ambientais em Login
Já mencionámos que muitos programas utilizam variáveis ambientais para decidir as especificidades de como operar. Não queremos ter de definir variáveis importantes sempre que iniciamos uma nova sessão shell, e já vimos quantas variáveis já estão definidas no início de sessão, por isso como fazemos e definimos as variáveis automaticamente?
Este é de facto um problema mais complexo do que parece inicialmente, devido aos numerosos ficheiros de configuração que a shell bash lê, dependendo de como é iniciada.
A diferença entre sessões de Login, Não-Login, Interactivo, e Não-Interactivo da shell
A shell da bash lê diferentes ficheiros de configuração dependendo de como a sessão é iniciada.
Uma distinção entre diferentes sessões é se a shell está a ser gerada como sessão de Login ou não-login.
Uma shell de Login é uma sessão de shell que começa por autenticar o utilizador. Se estiver a iniciar uma sessão terminal ou através de SSH e autenticar, a sua sessão shell será definida como uma shell de início de sessão.
Se iniciar uma nova sessão shell a partir da sua sessão autenticada, como fizemos chamando o comando bash
a partir do terminal, é iniciada uma sessão shell não-login. Não lhe foram solicitados os seus detalhes de autenticação quando iniciou a sua shell criança.
Outra distinção que pode ser feita é se uma sessão shell é interactiva, ou não interactiva.
Uma sessão shell interactiva é uma sessão shell que está ligada a um terminal. Uma sessão shell não-interactiva é uma que não está ligada a uma sessão terminal.
Assim, cada sessão shell é classificada como sessão de login ou não-interactiva e interactiva ou não-interactiva.
Uma sessão normal que começa com SSH é normalmente uma shell interactiva de login. Um script executado a partir da linha de comando é normalmente executado numa shell não-interactiva e não-login. Uma sessão terminal pode ser qualquer combinação destas duas propriedades.
Se uma sessão shell for classificada como shell de início de sessão ou não-interactiva tem implicações sobre quais os ficheiros que são lidos para inicializar a sessão shell.
Uma sessão iniciada como sessão de início de sessão lerá os detalhes de configuração do ficheiro /etc/profile
primeiro. Depois procurará o primeiro ficheiro de configuração da shell de início de sessão no directório home do utilizador para obter detalhes de configuração específicos do utilizador.
lê o primeiro ficheiro que pode encontrar de ~/.bash_profile
~/.bash_login
, e ~/.profile
e não lê mais ficheiros.
Em contraste, uma sessão definida como uma shell não-login leerá /etc/bash.bashrc
e depois o ficheiro específico do utilizador ~/.bashrc
para construir o seu ambiente.
shells não-interactivas lêem a variável ambiental chamada BASH_ENV
e lêem o ficheiro especificado para definir o novo ambiente.
Implementing Environmental Variables
Como se pode ver, há uma variedade de ficheiros diferentes que normalmente precisaríamos de ver para colocar as nossas definições.
Isto proporciona muita flexibilidade que pode ajudar em situações específicas em que queremos determinadas configurações numa shell de login, e outras configurações numa shell sem login. No entanto, na maioria das vezes queremos as mesmas definições em ambas as situações.
Felizmente, a maioria das distribuições Linux configuram os ficheiros de configuração de início de sessão para obter os ficheiros de configuração sem início de sessão. Isto significa que é possível definir variáveis ambientais que se pretendam em ambos dentro dos ficheiros de configuração não-login. Serão então lidos em ambos os cenários.
Estaremos normalmente a definir variáveis ambientais específicas do utilizador, e normalmente queremos que as nossas definições estejam disponíveis tanto nos ficheiros de configuração de início de sessão como nos ficheiros de configuração sem início de sessão. Isto significa que o lugar para definir estas variáveis é no ~/.bashrc
file.
Abrir este ficheiro agora:
- nano ~/.bashrc
Isto muito provavelmente já conterá bastantes dados. A maioria das definições aqui são para definir opções de bash, que não estão relacionadas com variáveis ambientais. Pode definir variáveis ambientais tal como faria a partir da linha de comando:
- export VARNAME=value
Ainda novas variáveis ambientais podem ser adicionadas em qualquer parte do ficheiro ~/.bashrc
, desde que não sejam colocadas no meio de outro comando ou para loop. Podemos então guardar e fechar o ficheiro. Da próxima vez que iniciar uma sessão shell, a sua declaração de variável ambiental será lida e passada para o ambiente shell. Pode forçar a sua sessão actual a ler o ficheiro agora, digitando:
- source ~/.bashrc
Conclusion
Ambiente e variáveis shell estão sempre presentes nas suas sessões shell e podem ser muito úteis. São uma forma interessante para um processo dos pais definir detalhes de configuração para os seus filhos, e são uma forma de definir opções fora dos ficheiros.
Isto tem muitas vantagens em situações específicas. Por exemplo, alguns mecanismos de implementação dependem de variáveis ambientais para configurar a informação de autenticação. Isto é útil porque não requer a sua manutenção em ficheiros que possam ser vistos por partes externas.
Existem muitos outros cenários, mais mundanos, mas mais comuns, onde será necessário ler ou alterar o ambiente do seu sistema. Estas ferramentas e técnicas devem dar-lhe uma boa base para fazer estas alterações e utilizá-las correctamente.