Discussion:
[shell-script] Array deixa de existir após fim de loop
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-12-05 15:32:01 UTC
Permalink
Alguém sabe dizer o motivo? Não encontrei explicação:

cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4

cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
echo "${#letras[@]}: ${letras[@]}";
echo "${#numeros[@]}: ${numeros[@]}";
done ;
echo "--${numeros[@]}--";
echo "--${letras[@]}--"

1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
Jonathan Lessa jonathanlessa@gmail.com [shell-script]
2017-12-05 15:36:06 UTC
Permalink
Boa tarde!

Aparentemente vc não está inicializando as variáveis antes do while, quando
vc as cria dentro de uma estrutura de loop elas são encerradas quando sai
do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Att.:
Jonathan Lessa
Licenciado em Informática
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-12-05 15:39:20 UTC
Permalink
Jonathan, eu nunca vi isso acontecer no bash antes, a não ser que você
declare a variável como local dentro de uma função. De toda forma, já tinha
tentado fazer com declare -a pros dois arrays antes do loop, e mesmo assim
ele sai vazio no final.

for i in {1..10}; do j+=1; done ; echo $j
1111111111
Post by Jonathan Lessa ***@gmail.com [shell-script]
Boa tarde!
Aparentemente vc não está inicializando as variáveis antes do while,
quando vc as cria dentro de uma estrutura de loop elas são encerradas
quando sai do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Jonathan Lessa
Licenciado em Informática
Jonathan Lessa jonathanlessa@gmail.com [shell-script]
2017-12-05 15:48:40 UTC
Permalink
Desculpe, passei por situações semelhantes antes e resolveu pra mim. Fui
testar aqui e realmente não surtiu efeito, mas consegui o que vc deseja da
seguinte forma:


while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
echo "${#letras[@]}: ${letras[@]}";
echo "${#numeros[@]}: ${numeros[@]}";
done < input
Post by Alfredo Casanova ***@gmail.com [shell-script]
Jonathan, eu nunca vi isso acontecer no bash antes, a não ser que você
declare a variável como local dentro de uma função. De toda forma, já tinha
tentado fazer com declare -a pros dois arrays antes do loop, e mesmo assim
ele sai vazio no final.
for i in {1..10}; do j+=1; done ; echo $j
1111111111
Post by Jonathan Lessa ***@gmail.com [shell-script]
Boa tarde!
Aparentemente vc não está inicializando as variáveis antes do while,
quando vc as cria dentro de uma estrutura de loop elas são encerradas
quando sai do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Jonathan Lessa
Licenciado em Informática
--
Att.:
Jonathan Lessa
Licenciado em Informática
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-12-05 15:55:12 UTC
Permalink
Eu tinha testado assim e vi que tinha funcionado. Não consigo entender pq
da primeira forma não funciona.
Post by Jonathan Lessa ***@gmail.com [shell-script]
Desculpe, passei por situações semelhantes antes e resolveu pra mim. Fui
testar aqui e realmente não surtiu efeito, mas consegui o que vc deseja da
while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done < input
Post by Alfredo Casanova ***@gmail.com [shell-script]
Jonathan, eu nunca vi isso acontecer no bash antes, a não ser que você
declare a variável como local dentro de uma função. De toda forma, já tinha
tentado fazer com declare -a pros dois arrays antes do loop, e mesmo assim
ele sai vazio no final.
for i in {1..10}; do j+=1; done ; echo $j
1111111111
Post by Jonathan Lessa ***@gmail.com [shell-script]
Boa tarde!
Aparentemente vc não está inicializando as variáveis antes do while,
quando vc as cria dentro de uma estrutura de loop elas são encerradas
quando sai do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Jonathan Lessa
Licenciado em Informática
--
Jonathan Lessa
Licenciado em Informática
Jonathan Lessa jonathanlessa@gmail.com [shell-script]
2017-12-05 16:24:17 UTC
Permalink
Não seria porque nessa estrutura o loop acaba sendo executado em um
subshell?
Post by Alfredo Casanova ***@gmail.com [shell-script]
Eu tinha testado assim e vi que tinha funcionado. Não consigo entender pq
da primeira forma não funciona.
Post by Jonathan Lessa ***@gmail.com [shell-script]
Desculpe, passei por situações semelhantes antes e resolveu pra mim. Fui
testar aqui e realmente não surtiu efeito, mas consegui o que vc deseja da
while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done < input
Post by Alfredo Casanova ***@gmail.com [shell-script]
Jonathan, eu nunca vi isso acontecer no bash antes, a não ser que você
declare a variável como local dentro de uma função. De toda forma, já tinha
tentado fazer com declare -a pros dois arrays antes do loop, e mesmo assim
ele sai vazio no final.
for i in {1..10}; do j+=1; done ; echo $j
1111111111
Post by Jonathan Lessa ***@gmail.com [shell-script]
Boa tarde!
Aparentemente vc não está inicializando as variáveis antes do while,
quando vc as cria dentro de uma estrutura de loop elas são encerradas
quando sai do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Jonathan Lessa
Licenciado em Informática
--
Jonathan Lessa
Licenciado em Informática
--
Att.:
Jonathan Lessa
Licenciado em Informática
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-12-05 16:31:24 UTC
Permalink
Pensei nisso, mas fiz um export ao final do loop e mesmo assim não consegui
printar a variável fora dele.
Post by Jonathan Lessa ***@gmail.com [shell-script]
Não seria porque nessa estrutura o loop acaba sendo executado em um
subshell?
Post by Alfredo Casanova ***@gmail.com [shell-script]
Eu tinha testado assim e vi que tinha funcionado. Não consigo entender pq
da primeira forma não funciona.
Post by Jonathan Lessa ***@gmail.com [shell-script]
Desculpe, passei por situações semelhantes antes e resolveu pra mim. Fui
testar aqui e realmente não surtiu efeito, mas consegui o que vc deseja da
while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done < input
Post by Alfredo Casanova ***@gmail.com [shell-script]
Jonathan, eu nunca vi isso acontecer no bash antes, a não ser que você
declare a variável como local dentro de uma função. De toda forma, já tinha
tentado fazer com declare -a pros dois arrays antes do loop, e mesmo assim
ele sai vazio no final.
for i in {1..10}; do j+=1; done ; echo $j
1111111111
Post by Jonathan Lessa ***@gmail.com [shell-script]
Boa tarde!
Aparentemente vc não está inicializando as variáveis antes do while,
quando vc as cria dentro de uma estrutura de loop elas são encerradas
quando sai do loop.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
--
Jonathan Lessa
Licenciado em Informática
--
Jonathan Lessa
Licenciado em Informática
--
Jonathan Lessa
Licenciado em Informática
itamarnet@yahoo.com.br [shell-script]
2017-12-05 16:35:57 UTC
Permalink
Caro Alfredo
essa forma funciona?


for a in `cat input`; do
letras[++i]=${a%|*};
numeros[++j]=${a#*|};
echo "${#letras[@]}: ${letras[@]}";
echo "${#numeros[@]}: ${numeros[@]}";
done;
echo "--${numeros[@]}--";
echo "--${letras[@]}--"


Até onde sei parece que dentro do while as variáveis, declarando ou não antes, não são preservadas, durando apenas no loop como um subshell.
Lembro de ter lido algo a respeito se não me engano do livro do Julio, então essa construção com o for pode ser uma opção alternativa.


Depois confirmo a fonte de onde vi essa citação.


[]'s
Itamar
'Julio C. Neves' julio.neves@gmail.com [shell-script]
2017-12-05 20:22:07 UTC
Permalink
Alfredo, tire o cat input | do início e no fone ponha
done < input
O pior gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
'Julio C. Neves' julio.neves@gmail.com [shell-script]
2017-12-05 21:35:07 UTC
Permalink
Vou repetir o e-mail pq o corretor pornográfico do telefone esculhambou
tudo:
Alfredo, tire o "cat input |" do início e no done ponha:

done < input

O pipe gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by 'Julio C. Neves' ***@gmail.com [shell-script]
Alfredo, tire o cat input | do início e no fone ponha
done < input
O pior gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
Rodrigo Tenorio rodrigo.boechat.tenorio@gmail.com [shell-script]
2017-12-06 09:31:44 UTC
Permalink
Mestre,

O pipe gera um subshell qualquer situação?
Por exemplo num: cat txtFile | grep anything

Grato,
Boëchat
Post by 'Julio C. Neves' ***@gmail.com [shell-script]
Vou repetir o e-mail pq o corretor pornográfico do telefone esculhambou
done < input
O pipe gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by 'Julio C. Neves' ***@gmail.com [shell-script]
Alfredo, tire o cat input | do início e no fone ponha
done < input
O pior gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
'Julio C. Neves' julio.neves@gmail.com [shell-script]
2017-12-06 22:21:42 UTC
Permalink
Sim, não só um pipe, mas tb parênteses, crases, ...

Faça estes 2 testes:

$ Var=5; (echo Var começou = $Var; Var=8; echo No subshell passou a valer
$Var); echo Saindo do subshell, volta a ser = $Var
$ echo -e "estão logados $(Var=$(who | wc -l)) $Var pessoas\n Mas este
é o valor anterior de Var, o certo seria $(who | wc -l)"



Abraços,
Julio
* Atenção! Últimos treinamentos presenciais do ano! *
Cidade Local Período
Brasilia LinuxSolutions <http://bit.ly/cursoshelljulioneves> 27/11-01/12
São Paulo 4Linux
<https://www.4linux.com.br/curso/programacao-em-shell-script> 05-09/12
Rio de Janeiro LinuxSolutions <http://bit.ly/cursoshelljulioneves> 11-15/12

*Damos treinamento em sua empresa **com certificado*
*e nota fiscal **por **um preço, **no mínimo, 50% mais*
*barato que qualquer curso.*

​​
Nosso time de instrutores *in company* é formado somente por
​
​
autores
​ ​
​
de
*Best Sellers​ ​*​laureados ​sobre os temas. P. exemplo:

Shell básico e Programação em Shell Julio Neves
Bacula Heitor Medrado
Zabbix Adail Host
Produção Gráfica e Videografismo Cadunico







Em 6 de dezembro de 2017 07:31, Rodrigo Tenorio
Post by Rodrigo Tenorio ***@gmail.com [shell-script]
Mestre,
O pipe gera um subshell qualquer situação?
Por exemplo num: cat txtFile | grep anything
Grato,
Boëchat
Post by 'Julio C. Neves' ***@gmail.com [shell-script]
Vou repetir o e-mail pq o corretor pornográfico do telefone esculhambou
done < input
O pipe gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by 'Julio C. Neves' ***@gmail.com [shell-script]
Alfredo, tire o cat input | do início e no fone ponha
done < input
O pior gera um subshell e tudo que foi criado e alterado nele desaparece
qdo ele morre.
Post by Alfredo Casanova ***@gmail.com [shell-script]
cat input
A|1.1.1.1
B|2.2.2.2
C|3.3.3.3
D|4.4.4.4
cat input | while IFS=\| read letra numero; do
letras+=($letra);
numeros+=($numero);
done ;
1: A
1: 1.1.1.1
2: A B
2: 1.1.1.1 2.2.2.2
3: A B C
3: 1.1.1.1 2.2.2.2 3.3.3.3
4: A B C D
4: 1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4
----
----
Loading...