Na verdade, eu não sabia que existem dois tipos diferentes de variáveis que posso acessar na linha de comando. Tudo o que eu sabia é que posso declarar variáveis como:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
ou acessá-los com um sinal de $, como:
echo $foo
echo ${bar[1]}
ou usando variáveis embutidas, como:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Agora, ouvi dizer que existem dois (pelo menos?) Tipos de variáveis: variáveis de shell e variáveis de ambiente.
- Qual é o propósito de ter dois tipos diferentes?
- Como sei que tipo é uma variável?
- Quais são os usos típicos de cada um?
shell
command-line
environment-variables
tubarão
fonte
fonte
Respostas:
Variáveis de ambiente são uma lista de
name=value
pares que existem, independentemente do programa (shell, aplicativo, daemon ...). Eles geralmente são herdados pelos processos filhos (criados por uma sequênciafork
/exec
): os processos filhos obtêm sua própria cópia das variáveis pai.As variáveis do shell existem apenas no contexto de um shell. Eles são herdados apenas em subshells (ou seja, quando o shell é bifurcado sem uma
exec
operação). Dependendo dos recursos do shell, as variáveis podem não ser apenas sequências simples, como as do ambiente, mas também matrizes, compostas, variáveis digitadas como número inteiro ou ponto flutuante etc.Quando um shell é iniciado, todas as variáveis de ambiente que herda de seu pai tornam-se também variáveis de shell (a menos que sejam inválidas como variáveis de shell e outros casos de canto, como o
IFS
que é redefinido por alguns shells), mas essas variáveis herdadas são marcadas como exportadas 1 . Isso significa que eles permanecerão disponíveis para processos filhos com o valor potencialmente atualizado definido pelo shell. Esse também é o caso de variáveis criadas sob o shell e marcadas como exportadas com aexport
palavra - chave.Matriz e outras variáveis de tipo complexo não podem ser exportadas, a menos que seu nome e valor possam ser convertidos para o
name=value
padrão ou quando um mecanismo específico do shell está em vigor (por exemplo:bash
exporta funções no ambiente e algumas shells exóticas e não POSIX, comorc
ees
pode exportar matrizes )Portanto, a principal diferença entre variáveis de ambiente e variáveis de shell é seu escopo: variáveis de ambiente são globais, enquanto variáveis de shell não exportadas são locais para o script.
Observe também que os shells modernos (pelo menos
ksh
ebash
) suportam um terceiro escopo de variáveis de shell. As variáveis criadas nas funções com atypeset
palavra - chave são locais para essa função (a maneira como a função é declarada ativa / desativa esse recurso emksh
, e o comportamento de persistência é diferente entrebash
eksh
). Consulte /unix//a/28349/25941 Isso se aplica a cascas modernas como
ksh
,dash
,bash
e similar. O shell Bourne herdado e os shell de sintaxe não Bourne, como eles,csh
têm comportamentos diferentes.fonte
execve()
chamada do sistema e, portanto, são (geralmente) usadas para persistir dados durante a execução de outros comandos (no mesmo processo).IFS
em alguns shells).rc
, como ,es
podem exportar matrizes usando uma codificação adhoc.bash
erc
também pode exportar funções usando variáveis de ambiente (novamente, usando uma codificação especial).ksh93
,typeset
restringe o escopo apenas em funções declaradas com afunction foo { ...; }
sintaxe, não com afoo() cmd
sintaxe Bourne ( ) (e o escopo estático não é dinâmico como em outros shells).Variáveis do shell
Variáveis de shell são variáveis cujo escopo está na sessão de shell atual, por exemplo, em uma sessão de shell interativa ou em um script.
Você pode criar uma variável de shell atribuindo um valor a um nome não utilizado:
O uso de variáveis do shell é acompanhar os dados na sessão atual. As variáveis do shell geralmente têm nomes com letras minúsculas.
Variáveis ambientais
Uma variável de ambiente é uma variável de shell que foi exportada. Isso significa que ficará visível como uma variável, não apenas na sessão do shell que a criou, mas também para qualquer processo (não apenas shells) iniciado a partir dessa sessão.
ou
Depois que uma variável do shell é exportada, ela permanece exportada até que seja desmarcada ou até que sua "propriedade de exportação" seja removida (com
export -n
inbash
), portanto, geralmente não há necessidade de reexportá-la. Desativar uma variável com aunset
exclui (não importa se é uma variável de ambiente ou não).Matrizes e hashes associativos
bash
e outros shells não podem ser exportados para se tornarem variáveis de ambiente. As variáveis de ambiente devem ser variáveis simples cujos valores são cadeias de caracteres e geralmente têm nomes que consistem em letras maiúsculas.O uso de variáveis de ambiente é acompanhar os dados na sessão atual do shell, mas também permitir que qualquer processo iniciado faça parte desses dados. O caso típico disso é a
PATH
variável de ambiente, que pode ser definida no shell e usada posteriormente por qualquer programa que queira iniciar programas sem especificar um caminho completo para eles.A coleta de variáveis de ambiente em um processo é frequentemente chamada de "o ambiente do processo". Cada processo tem seu próprio ambiente.
As variáveis de ambiente só podem ser "encaminhadas", ou seja, um processo filho nunca pode alterar as variáveis de ambiente em seu processo pai e, além de configurar o ambiente para um processo filho ao iniciá-lo, um processo pai não pode alterar o ambiente existente de um processo filho.
As variáveis de ambiente podem ser listadas com
env
(sem argumentos). Fora isso, eles aparecem da mesma forma que variáveis de shell não exportadas em uma sessão de shell. Isso é um pouco especial para o shell, já que a maioria das outras linguagens de programação não costuma misturar variáveis "comuns" com variáveis de ambiente (veja abaixo).env
também pode ser usado para definir os valores de uma ou várias variáveis de ambiente no ambiente de um processo sem configurá-los na sessão atual:Isso começa
make
com a variável de ambienteCC
definida como o valorclang
eCXX
definida comoclang++
.Também pode ser usado para limpar o ambiente de um processo:
Isso inicia,
bash
mas não transfere o ambiente atual para o novobash
processo (ele ainda terá variáveis de ambiente à medida que cria novas a partir de seus scripts de inicialização do shell).Exemplo de diferença
Outras línguas
Existem funções de biblioteca na maioria das linguagens de programação que permitem obter e configurar as variáveis de ambiente. Observe que, como as variáveis de ambiente são armazenadas como um relacionamento simples de valor-chave, elas geralmente não são "variáveis" do idioma. Um programa pode buscar o valor (que é sempre uma cadeia de caracteres) correspondente a uma chave (o nome da variável de ambiente), mas precisará convertê-lo em um número inteiro ou em qualquer tipo de dados que o idioma espere que o valor tenha.
Em C, variáveis de ambiente pode ser acedido utilizando
getenv()
,setenv()
,putenv()
eunsetenv()
. As variáveis criadas com essas rotinas são herdadas da mesma maneira por qualquer processo iniciado pelo programa C.Outros idiomas podem ter estruturas de dados especiais para realizar a mesma coisa, como o
%ENV
hash no Perl ou oENVIRON
array associativo na maioria das implementações doawk
.fonte
getenv()
,setenv()
,putenv()
eunsetenv()
. As variáveis criadas com essas rotinas são herdadas da mesma maneira por qualquer processo iniciado pelo programa C. Outros idiomas podem ter estruturas de dados especiais para a mesma coisa, como%ENV
no Perl.exec*()
família de funções também pode definir o ambiente para o processo que está sendo executado.As variáveis do shell são difíceis de duplicar.
Variáveis de ambiente, no entanto, podem ser duplicadas; eles são apenas uma lista e uma lista pode ter entradas duplicadas. Aqui está
envdup.c
para fazer exatamente isso.Que podemos compilar e executar dizendo
envdup
para executarenv
para nos mostrar quais variáveis de ambiente estão definidas ...Talvez isso seja útil apenas para encontrar bugs ou outras esquisitices na maneira como os programas lidam
**environ
.Parece que o Python 3.6 aqui passa cegamente as duplicatas (uma abstração com vazamento), enquanto o Perl 5.24 não. E as conchas?
Puxa, o que acontece se
sudo
apenas higieniza a primeira entrada do ambiente, mas depoisbash
executa com a segunda? OláPATH
ouLD_RUN_PATH
explorar. Seusudo
(e tudo mais ?) Está corrigido para esse buraco ? Explorações de segurança não são "uma diferença anedótica" nem apenas "um bug" no programa de chamada.fonte
Uma variável de ambiente é como uma variável de shell , mas não é específica para o shell . Todos os processos nos sistemas Unix possuem armazenamento variável de ambiente . A principal diferença entre as variáveis de ambiente e o shell é: que o sistema operacional passa todas as variáveis de ambiente do shell para os programas executados pelo shell, enquanto as variáveis do shell não podem ser acessadas nos comandos executados.
env –
O comando permite executar outro programa em um ambiente customizado sem modificar o atual. Quando usado sem argumento, imprimirá uma lista das variáveis de ambiente atuais.printenv –
O comando imprime todas ou as variáveis de ambiente especificadas.set –
O comando define ou desativa as variáveis do shell. Quando usado sem argumento, imprimirá uma lista de todas as variáveis, incluindo variáveis de ambiente e shell, e funções de shell.unset –
O comando exclui variáveis de shell e ambiente.export –
O comando define variáveis de ambientefonte