[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [shell-script] export para shells sub sequentes?
From: |
Felipe Kellermann |
Subject: |
Re: [shell-script] export para shells sub sequentes? |
Date: |
Mon, 26 Apr 2004 19:14:43 -0300 (BRT) |
On Mon, 26 Apr 2004 5:07pm -0300, Pablo Fernandes wrote:
> Em muitos materiais sobre shell script, encontrei a
> mesma coisa: "Cada shell possui caracterÃsticas
> especÃficas com variáveis de ambiente especÃficas (por
> ser multi usuário), e que precisamos exportar cada
> variável para que as mesmas sejam usadas pelos shells
> sub sequentes".
Estão enganados.
Não é por "shells subseqüentes". É por qualquer programa.
> O que eu queria saber é: Quando executamos algum
> programa, ele não executa em um novo shell? (sempre
Tecnicamente, sim. Qualquer programa. Não é um novo shell, é uma cópia
do teu atual, que depois é substituÃdo pelo programa que tu pediu. Aqui
está a relação com ambientes: Se tu tem um ambiente, tu clona para fazer
a substituição, o teu programa requisitado vai ter o mesmo ambiente.
O `ambiente' é uma tabela no formato `nome=valor' que todos os programas
têm. Essa tabela vai ser herdada de chamada a chamada, e cada chamada
pode substituir sua própria tabela.
init
tabela
atual
HOME=/
TERM=vt110
adicionou
CONSOLE=/dev/console
chamou
getty
getty
tabela
atual
HOME=/
TERM=vt110
CONSOLE=/dev/console
adicionou
TTY=/dev/tty1
chamou
login
login
tabela
atual
HOME=/
TERM=vt110
CONSOLE=/dev/console
TTY=/dev/tty1
mudou
HOME=/home/usuário
adicionou
USER=usuário
UID=1102
SHELL=/bin/sh
chamou
sh
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
CONSOLE=/dev/console
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
adicionou
NOME=Teste
VISUAL=vi
chamou
ls
ls
tabela
atual
HOME=/home/usuário
TERM=vt110
CONSOLE=/dev/console
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
CONSOLE=/dev/console
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
adicionou
NOME=Teste
VISUAL=vi
tirou
CONSOLE
chamou
sh-2
sh-2
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
mudou
NOME=Outro
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
A associação que fazem entre _variáveis_ e ambiente pode confundir. Não
tem nada a ver uma coisa com a outra. É apenas uma opção. Tu também pode
notar que sempre o "ambiente" está em letras maiúsculas, é para fazer uma
diferenciação entre as tuas variáveis e o teu ambiente.
E _por coincidência_ a shell acessa as variáveis da mesma forma que acessa
o ambiente. Não quer dizer que são a mesma coisa. Tu tem `pablo':
$ pablo="/"
O sÃmbolo, nome `pablo', está relacionado com o valor "/" para tua shell.
Essa é uma tabela simples -- são as variáveis que tu tem. Seria o mesmo
que fazer, em C:
const char *pablo = "/";
Nenhum dos dois tem relação alguma com _ambiente_.
Em shell, especialmente bourne shell, se tu quiser associar algum valor ao
teu ambiente atual, da shell, tu pode usar o `export'. A única função do
export é essa: Associar um sÃmbolo, um nome de uma variável, a algum dos
valores daquela tua tabela. Ou seja, naquela relação `nome=valor' que eu
te falei antes. Ou seja, voltando ao nosso exemplo e usando um padrão de
usar _apenas_ variáveis maiúsculas (boas maneiras) para ambiente. Digamos
que tu tá com a tua shell sh-1:
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
Nela, tu tem uma variável `PABLO'. Tu faz aquela associação que eu falei
com o `export'. Vai ficar mais ou menos assim:
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
adicionou
PABLO=/
Além desse ambiente, tu tem a _variável_ `PABLO'. Como tu quis que essa
associação fosse feita, tua shell vai admitir que se tu troca o valor da
variável `PABLO', tu quer trocar o valor que está associado ao ambiente.
$ PABLO=/home/pablo
Teu ambiente vai estar:
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
mudou:
PABLO=/home/pablo
Agora, teu ambiente está assim:
sh-1
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
PABLO=/home/pablo
Se tu chamar um `ls', tu vai ter:
ls
tabela
atual
HOME=/home/usuário
TERM=vt110
TTY=/dev/tty1
USER=usuário
UID=1102
SHELL=/bin/sh
NOME=Teste
VISUAL=vi
PABLO=/home/pablo
Voltando ao exemplo do C, se o `ls' ou qualquer outro programa quisesse
trocar o valor do ambiente dele, como ele poderia fazer? Ele vai fazer
exatamente o que a tua shell faz automaticamente:
Quando ele quiser saber qual é o valor de `PABLO', faz:
valor = getenv(nome);
Sabendo o valor, ele pode modificar ele ou usar outro valor:
setenv(nome, outrovalor, 1);
Observe que esse `1' significa justamente "sobrescrever". Ele diz que
mesmo quando já há algum valor na tabela relacionado a `nome', ele vai
mesmo assim trocar esse valor. Se ainda não existia nenhuma relação a
esse sÃmbolo, ele é apenas adicionado à lista.
O que o shell faz é exatamente a mesma coisa, e é apenas uma opção. A
idéia poderia ter sido diferente, mas não foi, por motivos históricos,
começando pelo fato de que shell, por padrão (a zsh possui) não possui
suporte a tabelas associativas. Portando, a idéia mais básica de:
ENV[NOME]=VALOR
> leio isso tbm). Então isso significaria que quando
> executo um "ls", estou executadno em um novo shell e
> algo como:
>
> pablo="/"
> ls $pablo
>
> não funcionaria, pq nao exportei e preciso exportar a
> variável para ser usada nos outros shells. Aih vejo
Novamente: Tecnicamente tu tá, sim, _duplicando_ teu shell. Mas isso
não tem relação nenhuma com o teu comando de exemplo. Veja que ao fazer
esse comando, tua shell vai expandir para:
ls /
E o `ls' vai executar com um argumento `/'. Sem relação com ambiente.
É preciso novamente lembrar: Não tem nada a ver ambiente com variáveis.
Prova disso é que, se tu usar um `$', já é uma dica. Shell usa apenas
duas formas de "passar" um ambiente a algum outro programa:
- Mudando o próprio ambiente usando as relações que expliquei;
Ou
- Usando a convenção `bourne shell' de `nome=valor programa'.
Então, teu exemplo não tem nada com ambiente. Como tu disse, tu não
exportou (associou) nada e nem passou dessa segunda forma que disse.
> que funciona mesmo sem exportar. Fiz um teste abrindo
> outro xterm, abrindo um novo tty e a mesma variável
> $pablo continua a funcionar. Dando um export foi o
> mesmo efeito. Afinal como é essa história do "precisa
> exportar antes"???
Em um terminal tu atribuiu `/' à variável `pablo' e, sem exportar, abriu
um outro `xterm' e essa variável ainda estava lá. Entendi bem? Foi:
$ pablo=/
$ xterm
E no outro terminal (xterm):
$ echo $pablo
/
É isso? Só há uma explicação: All export. Não é um padrão, mas todas as
shells implementam e exatamente da mesma forma em sua forma `curta', `-a',
e também em sua forma `longa', `allexport'.
Em qualquer shell, com `set -a' (pode ver as opções com `echo $-'), define
a mesma coisa que `set -o allexport', que diz que automaticamente todas as
variáveis vão ser exportadas.
Veja com `echo $-' se já não tem um `a', exemplo:
% echo $-
05689GJKNTWXZaikms
%
Se tem esse `a', está explicado, então.
Se não tem, há algum problema, mande mais informações :-)
--
Felipe Kellermann