Global associative array only visible when the script is sourced a second timebash vs zsh: scoping and...
Gofer work in exchange for LoR
Good way to stop electrolyte tabs from turning into powder?
How can I enter recovery mode (for Mac OS, on an iMac) remotely?
Unsolved Problems due to Lack of Computational Power
Units of measurement, especially length, when body parts vary in size among races
What is the purpose/function of this power inductor in parallel?
Why do we use low resistance cables to minimize power losses?
What allows us to use imaginary numbers?
Animate flow lines of time-dependent 3D dynamical system
Is a USB 3.0 device possible with a four contact USB 2.0 connector?
A Magic Diamond
How to render "have ideas above his station" into German
What should I do if actually I found a serious flaw in someone's PhD thesis and an article derived from that PhD thesis?
Attacking the Hydra
What exactly happened to the 18 crew members who were reported as "missing" in "Q Who"?
What was the intention with the Commodore 128?
How would armour (and combat) change if the fighter didn't need to actually wear it?
Is there a fallacy about "appeal to 'big words'"?
Setting up a Mathematical Institute of Refereeing?
How do I pass a "list of lists" as the argument to a function of the form F[x,y]?
Build a mob of suspiciously happy lenny faces ( ͡° ͜ʖ ͡°)
String routines
How do I answer an interview question about how to handle a hard deadline I won't be able to meet?
Why should I pay for an SSL certificate?
Global associative array only visible when the script is sourced a second time
bash vs zsh: scoping and `typeset -g`How to initialize a read-only, global, associative array in Bash?Error when constructing an associative arraybash silently does function return on (re-)declare of global associative read-only arraydisplay array in a function - not working“bad array subscript” error when adding entry to an associative arrayCreate an associative array from the output of two commandsReturn the output of a command into an associative arrayPass associative array as parameter list to script
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}
I have the following script called .bash_functions.test
which is already sourced by my .bash_functions
script:
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
And when I run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
Finally, when I source the script once more and re-run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
In fact, I use my Source
function in the first source call and the source
builtin and the second source call:
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
And here is what happens:
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Why is it working like this?
bash associative-array
add a comment |
I have the following script called .bash_functions.test
which is already sourced by my .bash_functions
script:
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
And when I run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
Finally, when I source the script once more and re-run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
In fact, I use my Source
function in the first source call and the source
builtin and the second source call:
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
And here is what happens:
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Why is it working like this?
bash associative-array
1
Does your.bash_functions
source.bash_functions.test
from within a function by any chance? If that was the case, thedeclare
would cause that associative array to be declared local to that function and you'd needdeclare -gA
to make sure the variable is declared in the global scope.
– Stéphane Chazelas
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday
add a comment |
I have the following script called .bash_functions.test
which is already sourced by my .bash_functions
script:
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
And when I run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
Finally, when I source the script once more and re-run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
In fact, I use my Source
function in the first source call and the source
builtin and the second source call:
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
And here is what happens:
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Why is it working like this?
bash associative-array
I have the following script called .bash_functions.test
which is already sourced by my .bash_functions
script:
# vim: set syn=sh noet:
mp4Options_BIS="-movflags +frag_keyframe"
declare -A audioExtension=( [libspeex]=spx [speex]=spx [opus]=opus [vorbis]=ogg [aac]=m4a [mp3]=mp3 [mp2]=mp2 [ac3]=ac3 [wmav2]=wma [pcm_dvd]=wav [pcm_s16le]=wav )
function test1 {
echo "=> mp4Options_BIS = $mp4Options_BIS"
echo "=> audioExtension = ${audioExtension[*]}"
}
And when I run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
Finally, when I source the script once more and re-run the test1
function I see this:
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
In fact, I use my Source
function in the first source call and the source
builtin and the second source call:
$ grep -r .bash_functions.test
.bash_functions:source $initDir/.bash_functions.test
$ type Source
Source is a function
Source ()
{
test "$debug" -gt 0 && time source "$@" && echo || source "$@"
}
And here is what happens:
$ Source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension =
$ source .initBash/.bash_functions.test
$ test1
=> mp4Options_BIS = -movflags +frag_keyframe
=> audioExtension = ac3 wma opus mp3 wav mp2 wav spx m4a spx ogg
Why is it working like this?
bash associative-array
bash associative-array
edited yesterday
Jeff Schaller♦
49k11 gold badges72 silver badges162 bronze badges
49k11 gold badges72 silver badges162 bronze badges
asked yesterday
SebMaSebMa
3891 gold badge4 silver badges14 bronze badges
3891 gold badge4 silver badges14 bronze badges
1
Does your.bash_functions
source.bash_functions.test
from within a function by any chance? If that was the case, thedeclare
would cause that associative array to be declared local to that function and you'd needdeclare -gA
to make sure the variable is declared in the global scope.
– Stéphane Chazelas
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday
add a comment |
1
Does your.bash_functions
source.bash_functions.test
from within a function by any chance? If that was the case, thedeclare
would cause that associative array to be declared local to that function and you'd needdeclare -gA
to make sure the variable is declared in the global scope.
– Stéphane Chazelas
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday
1
1
Does your
.bash_functions
source .bash_functions.test
from within a function by any chance? If that was the case, the declare
would cause that associative array to be declared local to that function and you'd need declare -gA
to make sure the variable is declared in the global scope.– Stéphane Chazelas
yesterday
Does your
.bash_functions
source .bash_functions.test
from within a function by any chance? If that was the case, the declare
would cause that associative array to be declared local to that function and you'd need declare -gA
to make sure the variable is declared in the global scope.– Stéphane Chazelas
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday
add a comment |
1 Answer
1
active
oldest
votes
declare
/typeset
without -g
declares variables in the current scope in addition to setting the type.
Here, because declare -A audioExtension=(...)
ends up being run within the Source
function, that causes the audioExtension
variable to be declared local to that function, and as a consequence its definition to be lost once Source
returns.
You could change it to typeset -Ag audioExtension=(...)
which always declares the variable in the global scope (it's different from zsh/mksh/yash where typeset -g
only prevents the variable from being made local (only updates the type/attributes and value); it makes a difference when your Source
function is called from another function itself; see bash vs zsh: scoping and `typeset -g` for details).
If you used ksh93
instead of bash
(that's the shell bash
borrowed that associative array syntax from), you could define your Source
function as:
Source() {
...
}
as opposed to:
function Source {
...
}
In ksh93, functions defined with the Bourne-style func() cmd
syntax don't have a local scope while function func {
ones have static local scope (there, there's only one global scope and one local per-function scope, not a stack of local scopes).
In bash
(and other shells with local scoping), there's no similar way to have a function that doesn't introduce a new scope. You could use an alias
instead like:
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(note that the aliases are expanded at the time code is read, not at the time it's executed).
It would make a functional difference compared to your function approach in that in:
Source ./myfile | other-cmd
We would be timing both source myfile
and other-cmd
as it's expanded to time source ./myfile | other-cmd
while in the function approach we would only by timing source ./myfile
.
Using source=(time source); "${source[@]}" /some/file
wouldn't work (it would invoke the time
standalone utility instead of the bash
time keyword).
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535698%2fglobal-associative-array-only-visible-when-the-script-is-sourced-a-second-time%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
declare
/typeset
without -g
declares variables in the current scope in addition to setting the type.
Here, because declare -A audioExtension=(...)
ends up being run within the Source
function, that causes the audioExtension
variable to be declared local to that function, and as a consequence its definition to be lost once Source
returns.
You could change it to typeset -Ag audioExtension=(...)
which always declares the variable in the global scope (it's different from zsh/mksh/yash where typeset -g
only prevents the variable from being made local (only updates the type/attributes and value); it makes a difference when your Source
function is called from another function itself; see bash vs zsh: scoping and `typeset -g` for details).
If you used ksh93
instead of bash
(that's the shell bash
borrowed that associative array syntax from), you could define your Source
function as:
Source() {
...
}
as opposed to:
function Source {
...
}
In ksh93, functions defined with the Bourne-style func() cmd
syntax don't have a local scope while function func {
ones have static local scope (there, there's only one global scope and one local per-function scope, not a stack of local scopes).
In bash
(and other shells with local scoping), there's no similar way to have a function that doesn't introduce a new scope. You could use an alias
instead like:
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(note that the aliases are expanded at the time code is read, not at the time it's executed).
It would make a functional difference compared to your function approach in that in:
Source ./myfile | other-cmd
We would be timing both source myfile
and other-cmd
as it's expanded to time source ./myfile | other-cmd
while in the function approach we would only by timing source ./myfile
.
Using source=(time source); "${source[@]}" /some/file
wouldn't work (it would invoke the time
standalone utility instead of the bash
time keyword).
add a comment |
declare
/typeset
without -g
declares variables in the current scope in addition to setting the type.
Here, because declare -A audioExtension=(...)
ends up being run within the Source
function, that causes the audioExtension
variable to be declared local to that function, and as a consequence its definition to be lost once Source
returns.
You could change it to typeset -Ag audioExtension=(...)
which always declares the variable in the global scope (it's different from zsh/mksh/yash where typeset -g
only prevents the variable from being made local (only updates the type/attributes and value); it makes a difference when your Source
function is called from another function itself; see bash vs zsh: scoping and `typeset -g` for details).
If you used ksh93
instead of bash
(that's the shell bash
borrowed that associative array syntax from), you could define your Source
function as:
Source() {
...
}
as opposed to:
function Source {
...
}
In ksh93, functions defined with the Bourne-style func() cmd
syntax don't have a local scope while function func {
ones have static local scope (there, there's only one global scope and one local per-function scope, not a stack of local scopes).
In bash
(and other shells with local scoping), there's no similar way to have a function that doesn't introduce a new scope. You could use an alias
instead like:
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(note that the aliases are expanded at the time code is read, not at the time it's executed).
It would make a functional difference compared to your function approach in that in:
Source ./myfile | other-cmd
We would be timing both source myfile
and other-cmd
as it's expanded to time source ./myfile | other-cmd
while in the function approach we would only by timing source ./myfile
.
Using source=(time source); "${source[@]}" /some/file
wouldn't work (it would invoke the time
standalone utility instead of the bash
time keyword).
add a comment |
declare
/typeset
without -g
declares variables in the current scope in addition to setting the type.
Here, because declare -A audioExtension=(...)
ends up being run within the Source
function, that causes the audioExtension
variable to be declared local to that function, and as a consequence its definition to be lost once Source
returns.
You could change it to typeset -Ag audioExtension=(...)
which always declares the variable in the global scope (it's different from zsh/mksh/yash where typeset -g
only prevents the variable from being made local (only updates the type/attributes and value); it makes a difference when your Source
function is called from another function itself; see bash vs zsh: scoping and `typeset -g` for details).
If you used ksh93
instead of bash
(that's the shell bash
borrowed that associative array syntax from), you could define your Source
function as:
Source() {
...
}
as opposed to:
function Source {
...
}
In ksh93, functions defined with the Bourne-style func() cmd
syntax don't have a local scope while function func {
ones have static local scope (there, there's only one global scope and one local per-function scope, not a stack of local scopes).
In bash
(and other shells with local scoping), there's no similar way to have a function that doesn't introduce a new scope. You could use an alias
instead like:
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(note that the aliases are expanded at the time code is read, not at the time it's executed).
It would make a functional difference compared to your function approach in that in:
Source ./myfile | other-cmd
We would be timing both source myfile
and other-cmd
as it's expanded to time source ./myfile | other-cmd
while in the function approach we would only by timing source ./myfile
.
Using source=(time source); "${source[@]}" /some/file
wouldn't work (it would invoke the time
standalone utility instead of the bash
time keyword).
declare
/typeset
without -g
declares variables in the current scope in addition to setting the type.
Here, because declare -A audioExtension=(...)
ends up being run within the Source
function, that causes the audioExtension
variable to be declared local to that function, and as a consequence its definition to be lost once Source
returns.
You could change it to typeset -Ag audioExtension=(...)
which always declares the variable in the global scope (it's different from zsh/mksh/yash where typeset -g
only prevents the variable from being made local (only updates the type/attributes and value); it makes a difference when your Source
function is called from another function itself; see bash vs zsh: scoping and `typeset -g` for details).
If you used ksh93
instead of bash
(that's the shell bash
borrowed that associative array syntax from), you could define your Source
function as:
Source() {
...
}
as opposed to:
function Source {
...
}
In ksh93, functions defined with the Bourne-style func() cmd
syntax don't have a local scope while function func {
ones have static local scope (there, there's only one global scope and one local per-function scope, not a stack of local scopes).
In bash
(and other shells with local scoping), there's no similar way to have a function that doesn't introduce a new scope. You could use an alias
instead like:
shopt -s expand_aliases
if [ "$debug" -gt 0 ]; then
alias Source='time source'
else
alias Source=source
fi
(note that the aliases are expanded at the time code is read, not at the time it's executed).
It would make a functional difference compared to your function approach in that in:
Source ./myfile | other-cmd
We would be timing both source myfile
and other-cmd
as it's expanded to time source ./myfile | other-cmd
while in the function approach we would only by timing source ./myfile
.
Using source=(time source); "${source[@]}" /some/file
wouldn't work (it would invoke the time
standalone utility instead of the bash
time keyword).
edited yesterday
answered yesterday
Stéphane ChazelasStéphane Chazelas
330k58 gold badges641 silver badges1008 bronze badges
330k58 gold badges641 silver badges1008 bronze badges
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
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
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f535698%2fglobal-associative-array-only-visible-when-the-script-is-sourced-a-second-time%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
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
Required, but never shown
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
Required, but never shown
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
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Does your
.bash_functions
source.bash_functions.test
from within a function by any chance? If that was the case, thedeclare
would cause that associative array to be declared local to that function and you'd needdeclare -gA
to make sure the variable is declared in the global scope.– Stéphane Chazelas
yesterday
@StéphaneChazelas You're right. Can you convert your comment to an answer?
– SebMa
yesterday