The output of env does not contain IFS, so it isn't not an environment variable, so what it actually is? Is it just a global variable?
IFS="C" bash -c 'echo X"$IFS"X'
if it is an variale, why this line command not override it?
What IFS actually is in bash?
It is a variable.
The output of env does not contain IFS
Because it's not exported. export IFS
to export it.
Is it just a global variable?
Yes, it is a global variable, as in, the scope of the variable is not limited to a function. It may be, it's common to do local IFS
for function local modifications.
IFS="C" bash -c 'echo X"$IFS"X' if it is an variale, why this line command not override it?
The same way:
$ PWD="C" bash -c 'echo X${PWD}X'
X/home/kamilX
Bash ignores that exported values of IFS
and uses its own value, which also Bash reports with variable expansion. Still, the exported value is there, you just can't access it with Bash:
$ IFS="C" python -c 'import os; print(os.environ["IFS"])'
C
how to check whether a variable is global or environ?
You can check if the variable has x
attribute set with declare -p
.
$ declare -p IFS
declare -- IFS="
"
$ export IFS
$ declare -p IFS
declare -x IFS="
"
And source code, from https://github.com/bminor/bash/blob/9439ce094c9aa7557a9d53ac7b412a23aa66e36b/variables.c#L531 :
/* Don't allow IFS to be imported from the environment. */
temp_var = bind_variable ("IFS", " \t\n", 0);
setifs (temp_var);
And https://github.com/bminor/bash/blob/9439ce094c9aa7557a9d53ac7b412a23aa66e36b/subst.c#L11092 and https://github.com/bminor/bash/blob/9439ce094c9aa7557a9d53ac7b412a23aa66e36b/variables.c#L5741 . It is handled specially - some internal Bash variables for word splitting are initialized depending on IFS value.