Um ambiente não é tão mágico quanto parece. O shell o armazena na memória e passa para a execve()
chamada do sistema. O processo filho o herda como um ponteiro de matriz chamado environ
. Na página de execve
manual:
SINOPSE
#include <unistd.h>
int execve(const char *filename, char *const argv[],
char *const envp[]);
argv
é uma matriz de sequências de argumentos passadas para o novo programa.
Por convenção, a primeira dessas seqüências deve conter o nome do arquivo associado ao arquivo que está sendo executado. envp
é uma matriz de seqüências de caracteres, convencionalmente no formato key = value, que são passadas como ambiente para o novo programa.
A página de environ(7)
manual também oferece algumas dicas:
SINOPSE
extern char **environ;
DESCRIÇÃO
A variável environ
aponta para uma matriz de ponteiros para seqüências de caracteres chamadas "ambiente". A última ponteiro nesta matriz tem o valor NULL
. (Essa variável deve ser declarada no programa do usuário, mas é declarada no arquivo de cabeçalho <unistd.h>
, caso os arquivos de cabeçalho venham da libc4 ou libc5, e caso venham da glibc e _GNU_SOURCE foi definido.) Essa matriz de strings é disponibilizada para o processo pela chamada exec (3) que iniciou o processo.
Ambas as páginas de manual GNU correspondem à especificação POSIX
exec(3)
família (ou seja, aqueles que não correspondem ao exec * v) passam ** pelo ambiente oculto.exec*e
variantes que passam explicitamente um env, em vez de usar implicitamente aenviron
variável global. Ov
meio "vetor" e refere-se aos argumentos da linha de comando passados como uma matriz (em vez de uma "lista" (função de tamanho variável))execve
é uma chamada do sistema, e todas as outrasexec*
funções são invólucros libc para ele.Você entendeu um pouco errado:
SOME_NAME=value
cria uma variável de shell (na maioria dos shells).export SOME_NAME=value
cria uma variável de ambiente. Para o melhor, para o pior, a maioria dos shells Unix / Linux / * BSD usa sintaxe idêntica ao acessar variáveis de ambiente e variáveis de shell.Em um sentido mais amplo, um "ambiente" é apenas a informação que acompanha a execução do programa. Em programas C, você pode encontrar o ID do processo com uma
getpid()
chamada, em um programa shell você usaria um acesso variável:$$
. O ID do processo é apenas parte do ambiente do programa. Eu acredito que o termo "ambiente" vem de alguns dos tópicos mais teóricos da ciência da computação, como modelar a execução de programas. Os modelos de execução de programas têm um ambiente "que contém as associações entre variáveis e seus valores".E esta última definição mais forte é o que é um "ambiente" para os shells Unix / Linux / * BSD: uma associação entre nomes ("variáveis") e seus valores. Para a maioria das conchas no estilo Unix, os valores são todos cadeias de caracteres, embora isso não seja tão rigoroso quanto costumava ser. Ksh, Zsh e Bash todos digitaram variáveis atualmente. Até as definições de função shell podem ser exportadas.
O uso de um ambiente separado das variáveis de shell simples envolve o
fork/exec
método de iniciar um novo processo usado por todos os Unixes. Quando vocêexport
possui um par de nome / valor, esse par de nome / valor estará presente no ambiente de novos executáveis, iniciados pelo shell com umaexecve(2)
chamada do sistema (geralmente seguindo afork(2)
, exceto quando oexec
comando do shell foi usado).Após um
execve()
, amain()
função do novo binário possui seus argumentos de linha de comando, o ambiente (armazenado como uma matriz de ponteiros terminados em NULL paravar=value
seqüências de caracteres, consulte aenviron(7)
página de manual). Outro estado que é herdado incluiulimit
configurações, diretório de trabalho atual e quaisquer descritores de arquivos abertos para os quais oexecve()
chamador não tinha o FD_CLOEXEC definido. O estado atual do tty (eco ativado, modo bruto etc.) também pode ser considerado parte do estado de execução herdado por umexec
processo recém- editado.Consulte a
bash
descrição do manual do ambiente de execução para obter comandos simples (exceto funções internas ou shell).O ambiente Unix é diferente de pelo menos alguns outros sistemas operacionais: os "léxicos" do VMS podem ser alterados por um processo filho, e essa alteração era visível no pai. Um VMS
cd
em um processo filho afetaria o diretório de trabalho do pai. Pelo menos em algumas circunstâncias, e minha memória pode estar falhando comigo.Algumas variáveis de ambiente são bem conhecidos,
$HOME
,$PATH
,$LD_LIBRARY_PATH
e outros. Algumas são convencionais para um determinado sistema de programação, de modo que um shell pai pode passar muitas e muitas informações de propósito específico para algum programa, como um diretório temporário específico ou um ID de usuário e senha que não aparecemps -ef
. Programas CGI simples herdam muitas informações do servidor da web por meio de variáveis de ambiente, por exemplo.fonte
SOME_NAME=value command
, definirá a variável de ambiente SOME_NAME para essa chamada de comando. Confusamente, não parece definir a variável shell com o mesmo nome.SOME_NAME=value command
se comporta de maneira contrária à sua expectativa é que é uma sintaxe especial que significa "adicione SOME_NAME ao ambiente passado ao comando, mas não altere as variáveis desse shell".fork()
ed, mas eles fazem receber (cópias de) variáveis do shell.As variáveis de ambiente em sua forma mais bruta são apenas um conjunto de pares nome / valor. Conforme descrito na página de manual do bash (
man 1 bash
) na seção AMBIENTE:Em termos práticos, permite definir o comportamento que é compartilhado ou exclusivo dos programas invocados no shell atual. Por exemplo, ao usar
crontab
ouvisudo
você pode definir aEDITOR
variável de ambiente para definir outro editor diferente daquele que seu sistema usaria por padrão. O mesmo pode ser verdadeiro para coisas como oman
comando que examina seuPAGER
ambiente para descobrir com qual programa pager deve ser usado para exibir a saída da página de manual.Muitos comandos unix leem o ambiente e, dependendo do que está definido, alteram sua saída / processamento / ação, dependendo deles. Alguns são compartilhados, outros são exclusivos do programa. A maioria das páginas de manual contém informações sobre como a variável de ambiente afeta o programa descrito.
Outras ilustrações práticas são para itens como sistemas com várias instalações do Oracle na mesma plataforma. Ao definir
ORACLE_HOME
, todo o conjunto de comandos oracle (conforme carregado na suaPATH
variável de ambiente) puxa configurações, definições, mapeamentos e bibliotecas desse diretório de nível superior. O mesmo vale para outros programas, como o java, com suaJAVA_HOME
variável de ambiente.o próprio bash possui muitas variáveis de ambiente que podem alterar o comportamento de várias coisas, como histórico (
HISTSIZE
,HISTFILE
etc), tamanho da tela (COLUMNS
), conclusão da guia (FIGNORE
,GLOBIGNORE
) localidade e codificação / decodificação de caracteres (LANG
,LC_*
), prompt (PS1
..PS4
) e assim por diante (procure novamente o conhecimento na página de manual do bash).Além disso, você pode escrever scripts / programas que usam suas próprias variáveis de ambiente personalizadas (para passar configurações ou alterar a funcionalidade).
fonte
"Variáveis de ambiente" são um conjunto de valores nomeados dinâmicos que podem afetar a maneira como os processos em execução se comportarão em um computador.
Eles fazem parte do ambiente operacional no qual um processo é executado. Por exemplo, um processo em execução pode consultar o valor da variável de ambiente TEMP para descobrir um local adequado para armazenar arquivos temporários, ou a variável HOME ou USERPROFILE para encontrar a estrutura de diretórios pertencente ao usuário que está executando o processo.
Mais informações aqui → http://en.wikipedia.org/wiki/Environment_variable .
Tudo o que você deseja saber sobre variáveis de ambiente ... ↑
fonte
Esta resposta requer alguma experiência e conhecimento de script de shell com os termos variável, valor, substituição de variável, prompt, eco, kernel, shell, utilitário, sessão e processo.
Uma variável de ambiente (envar) é um conjunto de variáveis definidas globalmente que podem afetar a maneira como um determinado processo se comportará no sistema operacional de um computador.
1. Uma introdução exemplar:
Substituímos os envários por a
$
e letras maiúsculas . Por exemplo:$PS1
.Podemos imprimir um envar desta maneira:
$PS1
mantém o valor do prompt do Unix. Digamos que seus valores nativos sejam\u
\w
$
.\u
significa usuário (atual),\w
significa diretório de trabalho,$
é delimitar o prompt.Portanto, se fizermos:,
echo $PS1
veremos os valores de\u
,\w
mais o cifrão no final.Poderíamos mudar o comportamento do Unix nesse contexto, se mudarmos os valores desse envar. Por exemplo:
Agora, o prompt se parece com isso (assumindo que o diretório de trabalho seja chamado "John"):
Da mesma maneira que poderíamos fazer
PS1="Hello, I'm your prompt >"
, issoecho $PS1
trará:No Bash 4.xx, podemos imprimir TODOS os envios no sistema com o
env
comando Sugiro executarenv
no terminal e dar uma olhada na saída.2. Como esses dados são mostrados e manipulados:
O terminal de uma sessão nos permite personalizar os envares que estão chegando com o Bash.
As alterações acima mencionadas são geralmente temporárias, e aqui está o porquê:
Cada sessão (que não é uma sub-sessão) é única e vários processos podem ser executados de maneira única ao mesmo tempo (cada um com seu próprio conjunto de envares), mas geralmente há herança da sessão 0 para a sessão 1 e superior.
As alterações que fazemos em um processo são exclusivas e cessarão se a fecharmos sem salvá-las de alguma maneira.
Então, como podemos salvar essas alterações:
Existem vários tipos de maneiras disponíveis para armazenar alterações no envar, dependendo do escopo escolhido. Aqui estão diferentes escopos (níveis) para essas alterações:
Onde os dados do envar são armazenados:
O Unix é composto de três camadas principais: Kernel, shell e utilitários. AFAIK cada shell possui seus próprios envios, e estes são criados principalmente ou exclusivamente no shell.
O local específico no qual alterar globalmente esses é geralmente,
/etc/profile
embora também possamos fazer isso, é.bashrc
claro.3. Criando novos envios:
Podemos criar novos ambientes e aqui está um caminho; a partir do Bash 4.xx, não há enavar nativo nomeado
MESSAGE
(como dito, os envares geralmente são maiúsculos).irá criá-lo para nós e agora, se digitarmos eco
$MESSAGE
, obteremoshello world!
.Se executarmos
bash
em nossa sessão de trabalho atual (janela), iniciaremos uma nova sub-sessão do bash e não trabalharemos mais no processo original, a menos que seja executadaexit
.Nota: Em sistemas operacionais com um emulador de terminal (como a área de trabalho Ubuntu), uma sub-sessão geralmente é executada na mesma janela, mas uma nova sessão em outra janela não é uma sub-sessão da existente (é um processo adjacente ) .
Nota: Não use sinais especiais em valores de envar como! ou eles não serão salvos.
Exportando o envar da sessão original para todas as sub-sessões:
Ainda podemos usar o envar criado na primeira sessão, também na segunda, sem registrá-lo nos arquivos conf do usuário ou no nível global (consulte os dados a seguir). Veja como fazer isso:
Vá para a sessão original (na janela atual ou em outra) e execute:
ao exportar, não use um
$
sinal.Agora é exportado para todas as sub-sessões. Se você fizer
echo $MESSAGE
uma sub-sessão, seja do seu usuário ou de outro, ela será impressa.Observe que as variáveis internas do Shell, como
PS1
não devem ser exportadas, mas se você deseja exportá-las por qualquer motivo e elas não aparecerem, não executebash
depoisexport
, mas simbash –norc
.4. O envar $ PATH:
$PATH
é o ambiente que os usuários geralmente mudam mais.Se nós
echo $PATH
, vamos ver este fluxo:Os valores impressos desse envar são separados por dois pontos (:), mas aqui está uma maneira potencialmente mais confortável (esses são os mesmos valores):
Esses são diretórios a serem procurados quando executamos um utilitário.
Ao executar
which echo
, obteremos o local do arquivo - por exemplo, podemos ver que ele existe/bin/echo
.Com base nisso, não precisamos digitar echo envar para visualizar os valores do evnar. Nós também podemos fazer:
O envar ainda será executado, por exemplo:
Nos dá
Assim como:
Nos dá
Nota:
$HOME
é abreviado como~
.As relações system- $ PATH e uma possível interação do usuário:
No Bash 4.xx, quando usamos um utilitário sem o caminho completo, o sistema utilizará todos os 6 valores mencionados acima, do
$PATH
envar. Então, ele começará/user/local/bin
e seguirá todo o seu conteúdo procurando peloecho
executável.Nesse caso, ele irá parar em
/bin/echo
, no qual, nesse caso, o executável reside.Portanto, a principal razão pela qual podemos personalizar o
$PATH
envar, é instalar executáveis que não estão sob nenhum de seus valores nativos.Depois de instalar esses executáveis, devemos definir seu
$PATH
valor de acordo e podermos trabalhar com eles.5. Apêndice - expandindo
$PATH
:Podemos
export $PATH
basear sub-sessões (que inclui extensões bash como WP-CLI para WordPress ou Drush for Drupal) desta maneira:Isto irá adicionar um novo valor
/home/John
para$PATH
, em seguida, logo em seguida, ele vai anexar quaisquer valores nativos para ele (direito após os dois pontos), que são armazenados sob a sintaxe$PATH
.Essa mudança permanente pode ser feita no script relevante, geralmente sob
/etc/profile
e pelo nome.bashrc
.fonte
!
um valor de variável de ambiente que não está funcionando logo abaixo de um exemplo mostrando que está funcionando, uma falsa noção de sub-sessões, conselhos bastante bizarros sobre o que fazer depois de exportar uma variável de shell e uma noção falsa de variáveis de ambiente global.warning about ! in an environment variable value not working that is right below an example showing it working
? Por favor exemplo.quite bizarre advice about what to do after exporting a shell variable
, o que exatamente você quer dizer?false notion of global environment variables
, o que exatamente você quer dizer?