My variable's value is 0, but I didn't set it to 0
Clash Royale CLAN TAG#URR8PPP
up vote
7
down vote
favorite
Today I noticed one of my zsh functions is not functioning; I investigated the issue, and the culprit was this:
for i in a b
do
echo "$i"
done
0
0
Then I opened a new zsh, and in that, things were working normally:
for i in a b
do
echo "$i"
done
a
b
Can anyone explain the reason behind the first one acting weird to me?
zsh variable
add a comment |Â
up vote
7
down vote
favorite
Today I noticed one of my zsh functions is not functioning; I investigated the issue, and the culprit was this:
for i in a b
do
echo "$i"
done
0
0
Then I opened a new zsh, and in that, things were working normally:
for i in a b
do
echo "$i"
done
a
b
Can anyone explain the reason behind the first one acting weird to me?
zsh variable
3
Was variablei
previously typeset (or declared) as an integer in the first case?
â steeldriver
Aug 18 at 18:48
@steeldriver I changedi
toweirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?
â HappyFace
Aug 18 at 19:27
1
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21
add a comment |Â
up vote
7
down vote
favorite
up vote
7
down vote
favorite
Today I noticed one of my zsh functions is not functioning; I investigated the issue, and the culprit was this:
for i in a b
do
echo "$i"
done
0
0
Then I opened a new zsh, and in that, things were working normally:
for i in a b
do
echo "$i"
done
a
b
Can anyone explain the reason behind the first one acting weird to me?
zsh variable
Today I noticed one of my zsh functions is not functioning; I investigated the issue, and the culprit was this:
for i in a b
do
echo "$i"
done
0
0
Then I opened a new zsh, and in that, things were working normally:
for i in a b
do
echo "$i"
done
a
b
Can anyone explain the reason behind the first one acting weird to me?
zsh variable
edited Aug 18 at 21:27
Gilles
507k12010031531
507k12010031531
asked Aug 18 at 18:37
HappyFace
1018
1018
3
Was variablei
previously typeset (or declared) as an integer in the first case?
â steeldriver
Aug 18 at 18:48
@steeldriver I changedi
toweirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?
â HappyFace
Aug 18 at 19:27
1
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21
add a comment |Â
3
Was variablei
previously typeset (or declared) as an integer in the first case?
â steeldriver
Aug 18 at 18:48
@steeldriver I changedi
toweirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?
â HappyFace
Aug 18 at 19:27
1
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21
3
3
Was variable
i
previously typeset (or declared) as an integer in the first case?â steeldriver
Aug 18 at 18:48
Was variable
i
previously typeset (or declared) as an integer in the first case?â steeldriver
Aug 18 at 18:48
@steeldriver I changed
i
to weirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?â HappyFace
Aug 18 at 19:27
@steeldriver I changed
i
to weirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?â HappyFace
Aug 18 at 19:27
1
1
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
10
down vote
accepted
% typeset -i i
% for i in a b; print $i
0
0
Variables in zsh
can be assigned various types, above -i
for "represent internally as an integer", which will cause the variable to be represented as that. This can also be done via integer i
. There are various ways to inspect what a variable is:
% print $(t)i
integer
% typeset -p i
typeset -i i=0
And the usual shell +
to disable (see also set -x
, set +x
) it:
% typeset +i i
% for i in a b; print $i
a
b
It may be beneficial to hunt down what changed the type of that variable and restrict that change to a local scope (within a function) so that the global namespace is not polluted with random types, especially on oft used throwaway variable names such as i
. It is rather easy to pollute the global namespace, as all that requires is assignment to an undeclared variable:
% () local l=42; g=43
% print $l
% print $g
43
Or someone could needlessly add the -g
flag to a typeset
which makes the variable global:
% () typeset -g -i h=42
% for h in a b; print $h
0
0
Exported variables may persist into new processes (a non-subshell child via fork
, or a replacement via exec
), but not the type:
% export -i h=42
% print $h $(t)h
42 integer-export
% ( print $(t)h )
integer-export
% exec zsh -l
% print $h $(t)h
42 scalar-export
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (.
,source
,eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it does
â thrig
Aug 18 at 19:55
2
I think you could alsounset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need totypeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can'tunset
readonly variables in them.
â ilkkachu
Aug 18 at 20:38
1
@ilkkachu, also, in bash or mksh, you may need to callunset
several times in case it has been declared local in several ancestor contexts (in those (andyash
,unset
doesn't unset, it peels off one layer oflocal
(except inbash
when the variable has been declared in the current context)).
â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?export
is for scalar variables to be transmitted across execs, that's independent of processes.
â Stéphane Chazelas
Aug 19 at 13:56
 |Â
show 2 more comments
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
10
down vote
accepted
% typeset -i i
% for i in a b; print $i
0
0
Variables in zsh
can be assigned various types, above -i
for "represent internally as an integer", which will cause the variable to be represented as that. This can also be done via integer i
. There are various ways to inspect what a variable is:
% print $(t)i
integer
% typeset -p i
typeset -i i=0
And the usual shell +
to disable (see also set -x
, set +x
) it:
% typeset +i i
% for i in a b; print $i
a
b
It may be beneficial to hunt down what changed the type of that variable and restrict that change to a local scope (within a function) so that the global namespace is not polluted with random types, especially on oft used throwaway variable names such as i
. It is rather easy to pollute the global namespace, as all that requires is assignment to an undeclared variable:
% () local l=42; g=43
% print $l
% print $g
43
Or someone could needlessly add the -g
flag to a typeset
which makes the variable global:
% () typeset -g -i h=42
% for h in a b; print $h
0
0
Exported variables may persist into new processes (a non-subshell child via fork
, or a replacement via exec
), but not the type:
% export -i h=42
% print $h $(t)h
42 integer-export
% ( print $(t)h )
integer-export
% exec zsh -l
% print $h $(t)h
42 scalar-export
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (.
,source
,eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it does
â thrig
Aug 18 at 19:55
2
I think you could alsounset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need totypeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can'tunset
readonly variables in them.
â ilkkachu
Aug 18 at 20:38
1
@ilkkachu, also, in bash or mksh, you may need to callunset
several times in case it has been declared local in several ancestor contexts (in those (andyash
,unset
doesn't unset, it peels off one layer oflocal
(except inbash
when the variable has been declared in the current context)).
â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?export
is for scalar variables to be transmitted across execs, that's independent of processes.
â Stéphane Chazelas
Aug 19 at 13:56
 |Â
show 2 more comments
up vote
10
down vote
accepted
% typeset -i i
% for i in a b; print $i
0
0
Variables in zsh
can be assigned various types, above -i
for "represent internally as an integer", which will cause the variable to be represented as that. This can also be done via integer i
. There are various ways to inspect what a variable is:
% print $(t)i
integer
% typeset -p i
typeset -i i=0
And the usual shell +
to disable (see also set -x
, set +x
) it:
% typeset +i i
% for i in a b; print $i
a
b
It may be beneficial to hunt down what changed the type of that variable and restrict that change to a local scope (within a function) so that the global namespace is not polluted with random types, especially on oft used throwaway variable names such as i
. It is rather easy to pollute the global namespace, as all that requires is assignment to an undeclared variable:
% () local l=42; g=43
% print $l
% print $g
43
Or someone could needlessly add the -g
flag to a typeset
which makes the variable global:
% () typeset -g -i h=42
% for h in a b; print $h
0
0
Exported variables may persist into new processes (a non-subshell child via fork
, or a replacement via exec
), but not the type:
% export -i h=42
% print $h $(t)h
42 integer-export
% ( print $(t)h )
integer-export
% exec zsh -l
% print $h $(t)h
42 scalar-export
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (.
,source
,eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it does
â thrig
Aug 18 at 19:55
2
I think you could alsounset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need totypeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can'tunset
readonly variables in them.
â ilkkachu
Aug 18 at 20:38
1
@ilkkachu, also, in bash or mksh, you may need to callunset
several times in case it has been declared local in several ancestor contexts (in those (andyash
,unset
doesn't unset, it peels off one layer oflocal
(except inbash
when the variable has been declared in the current context)).
â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?export
is for scalar variables to be transmitted across execs, that's independent of processes.
â Stéphane Chazelas
Aug 19 at 13:56
 |Â
show 2 more comments
up vote
10
down vote
accepted
up vote
10
down vote
accepted
% typeset -i i
% for i in a b; print $i
0
0
Variables in zsh
can be assigned various types, above -i
for "represent internally as an integer", which will cause the variable to be represented as that. This can also be done via integer i
. There are various ways to inspect what a variable is:
% print $(t)i
integer
% typeset -p i
typeset -i i=0
And the usual shell +
to disable (see also set -x
, set +x
) it:
% typeset +i i
% for i in a b; print $i
a
b
It may be beneficial to hunt down what changed the type of that variable and restrict that change to a local scope (within a function) so that the global namespace is not polluted with random types, especially on oft used throwaway variable names such as i
. It is rather easy to pollute the global namespace, as all that requires is assignment to an undeclared variable:
% () local l=42; g=43
% print $l
% print $g
43
Or someone could needlessly add the -g
flag to a typeset
which makes the variable global:
% () typeset -g -i h=42
% for h in a b; print $h
0
0
Exported variables may persist into new processes (a non-subshell child via fork
, or a replacement via exec
), but not the type:
% export -i h=42
% print $h $(t)h
42 integer-export
% ( print $(t)h )
integer-export
% exec zsh -l
% print $h $(t)h
42 scalar-export
% typeset -i i
% for i in a b; print $i
0
0
Variables in zsh
can be assigned various types, above -i
for "represent internally as an integer", which will cause the variable to be represented as that. This can also be done via integer i
. There are various ways to inspect what a variable is:
% print $(t)i
integer
% typeset -p i
typeset -i i=0
And the usual shell +
to disable (see also set -x
, set +x
) it:
% typeset +i i
% for i in a b; print $i
a
b
It may be beneficial to hunt down what changed the type of that variable and restrict that change to a local scope (within a function) so that the global namespace is not polluted with random types, especially on oft used throwaway variable names such as i
. It is rather easy to pollute the global namespace, as all that requires is assignment to an undeclared variable:
% () local l=42; g=43
% print $l
% print $g
43
Or someone could needlessly add the -g
flag to a typeset
which makes the variable global:
% () typeset -g -i h=42
% for h in a b; print $h
0
0
Exported variables may persist into new processes (a non-subshell child via fork
, or a replacement via exec
), but not the type:
% export -i h=42
% print $h $(t)h
42 integer-export
% ( print $(t)h )
integer-export
% exec zsh -l
% print $h $(t)h
42 scalar-export
edited Aug 19 at 13:44
answered Aug 18 at 19:26
thrig
22.6k12853
22.6k12853
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (.
,source
,eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it does
â thrig
Aug 18 at 19:55
2
I think you could alsounset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need totypeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can'tunset
readonly variables in them.
â ilkkachu
Aug 18 at 20:38
1
@ilkkachu, also, in bash or mksh, you may need to callunset
several times in case it has been declared local in several ancestor contexts (in those (andyash
,unset
doesn't unset, it peels off one layer oflocal
(except inbash
when the variable has been declared in the current context)).
â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?export
is for scalar variables to be transmitted across execs, that's independent of processes.
â Stéphane Chazelas
Aug 19 at 13:56
 |Â
show 2 more comments
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (.
,source
,eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it does
â thrig
Aug 18 at 19:55
2
I think you could alsounset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need totypeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can'tunset
readonly variables in them.
â ilkkachu
Aug 18 at 20:38
1
@ilkkachu, also, in bash or mksh, you may need to callunset
several times in case it has been declared local in several ancestor contexts (in those (andyash
,unset
doesn't unset, it peels off one layer oflocal
(except inbash
when the variable has been declared in the current context)).
â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?export
is for scalar variables to be transmitted across execs, that's independent of processes.
â Stéphane Chazelas
Aug 19 at 13:56
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
Is it possible to protect a script against this pollution?
â HappyFace
Aug 18 at 19:30
2
2
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (
.
, source
, eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it doesâ thrig
Aug 18 at 19:55
"a script" runs as a different process, as I understand it, so should not be affected. if you are sourcing random code (
.
, source
, eval
) into an existing process then bad code could easily pollute the environment, in which case you'll either need to not do that, or audit every line of the random code to see what it doesâ thrig
Aug 18 at 19:55
2
2
I think you could also
unset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need to typeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can't unset
readonly variables in them.â ilkkachu
Aug 18 at 20:38
I think you could also
unset var
to make it lose any special properties it may have. Well, unless it's also readonly, in which case you'd need to typeset +r var
first. Bash and ksh could have the same issue with variables set as integers, with the same solution. Except that you can't unset
readonly variables in them.â ilkkachu
Aug 18 at 20:38
1
1
@ilkkachu, also, in bash or mksh, you may need to call
unset
several times in case it has been declared local in several ancestor contexts (in those (and yash
, unset
doesn't unset, it peels off one layer of local
(except in bash
when the variable has been declared in the current context)).â Stéphane Chazelas
Aug 19 at 8:30
@ilkkachu, also, in bash or mksh, you may need to call
unset
several times in case it has been declared local in several ancestor contexts (in those (and yash
, unset
doesn't unset, it peels off one layer of local
(except in bash
when the variable has been declared in the current context)).â Stéphane Chazelas
Aug 19 at 8:30
What's a non-subshell child via fork?
export
is for scalar variables to be transmitted across execs, that's independent of processes.â Stéphane Chazelas
Aug 19 at 13:56
What's a non-subshell child via fork?
export
is for scalar variables to be transmitted across execs, that's independent of processes.â Stéphane Chazelas
Aug 19 at 13:56
 |Â
show 2 more comments
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f463392%2fmy-variables-value-is-0-but-i-didnt-set-it-to-0%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
3
Was variable
i
previously typeset (or declared) as an integer in the first case?â steeldriver
Aug 18 at 18:48
@steeldriver I changed
i
toweirdName13
and it indeed fixed the issue. But I hadn't done anything with i. How can one undo this typeset? And how can I protect my scripts when i is typeset as an integer?â HappyFace
Aug 18 at 19:27
1
@HappyFace if you haven't declared your function's local variables as local, expect them to be stomped by random things.
â muru
Aug 19 at 1:21