Pass associative array as parameter list to script2019 Community Moderator ElectionEscaping strings in associative arrays (bash)Iterate bash associative array in MakefileCreate an associative array from the output of two commandsPassing filenames with space between scriptsRetrieved value from associative array is wrong?Return the output of a command into an associative arrayzsh parameter expansion flag (P) with associative arraysBASH associative array printingBash return an associative array from a function and then pass that associative array to other functionsMaking associative array based on another associative array

How to make healing in an exploration game interesting

Bacteria contamination inside a thermos bottle

Knife as defense against stray dogs

Credit cards used everywhere in Singapore or Malaysia?

Do the common programs (for example: "ls", "cat") in Linux and BSD come from the same source code?

Brexit - No Deal Rejection

Have the tides ever turned twice on any open problem?

Employee lack of ownership

gcc: how to detect bad `bool` usage

Describing a chess game in a novel

Experimental tests of Schrodinger evolution, position distribution, in square well and other simple systems?

New passport but visa is in old (lost) passport

Can a one-dimensional blade cut everything ? (chainsaw) (Sword)

Problem with FindRoot

How to solve this challenging limit?

Welcoming 2019 Pi day: How to draw the letter π?

Meme-controlled people

et qui - how do you really understand that kind of phraseology?

Is it insecure to send a password in a `curl` command?

Are ETF trackers fundamentally better than individual stocks?

Why no Iridium-level flares from other satellites?

Are all passive ability checks floors for active ability checks?

How well should I expect Adam to work?

Life insurance that covers only simultaneous/dual deaths



Pass associative array as parameter list to script



2019 Community Moderator ElectionEscaping strings in associative arrays (bash)Iterate bash associative array in MakefileCreate an associative array from the output of two commandsPassing filenames with space between scriptsRetrieved value from associative array is wrong?Return the output of a command into an associative arrayzsh parameter expansion flag (P) with associative arraysBASH associative array printingBash return an associative array from a function and then pass that associative array to other functionsMaking associative array based on another associative array










8















In a script I have an associative array like:



declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )


Is there a single command to transform that into a parameter list in the form



--key1=value1 --key2=value2


without having to manually re-write



 --key1="$VARS[key1]" --key2="$VARS[key2]"


the use-case I had in mind was to pass the array to a script as a list of parameters, like



my_script.sh $(to_param_list $VARS)


To expand on the comment I made on @Kusalananda answer, my exact use case is as follows: I have a script which is used to build a self-extracting installer using makeself, and this script receives some parameters which are to be separated between:



  • parameters for the script itself

  • parameters for the installer inside the self-extracting installer

The scripts then builds the installer like this:



to_param_list installer_param_list installer_param_array
./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "$installer_param_list[@]"


However, I have tested the parameter passing with a very simple installer script inside the package:



while ! -z "$1" ; do
echo "$1"
shift
done


and passing an array like:



installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )


results in this output:



--upgrade-to=19.3.0
--upgrade-from=19
.2.0









share|improve this question




























    8















    In a script I have an associative array like:



    declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )


    Is there a single command to transform that into a parameter list in the form



    --key1=value1 --key2=value2


    without having to manually re-write



     --key1="$VARS[key1]" --key2="$VARS[key2]"


    the use-case I had in mind was to pass the array to a script as a list of parameters, like



    my_script.sh $(to_param_list $VARS)


    To expand on the comment I made on @Kusalananda answer, my exact use case is as follows: I have a script which is used to build a self-extracting installer using makeself, and this script receives some parameters which are to be separated between:



    • parameters for the script itself

    • parameters for the installer inside the self-extracting installer

    The scripts then builds the installer like this:



    to_param_list installer_param_list installer_param_array
    ./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "$installer_param_list[@]"


    However, I have tested the parameter passing with a very simple installer script inside the package:



    while ! -z "$1" ; do
    echo "$1"
    shift
    done


    and passing an array like:



    installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )


    results in this output:



    --upgrade-to=19.3.0
    --upgrade-from=19
    .2.0









    share|improve this question


























      8












      8








      8


      2






      In a script I have an associative array like:



      declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )


      Is there a single command to transform that into a parameter list in the form



      --key1=value1 --key2=value2


      without having to manually re-write



       --key1="$VARS[key1]" --key2="$VARS[key2]"


      the use-case I had in mind was to pass the array to a script as a list of parameters, like



      my_script.sh $(to_param_list $VARS)


      To expand on the comment I made on @Kusalananda answer, my exact use case is as follows: I have a script which is used to build a self-extracting installer using makeself, and this script receives some parameters which are to be separated between:



      • parameters for the script itself

      • parameters for the installer inside the self-extracting installer

      The scripts then builds the installer like this:



      to_param_list installer_param_list installer_param_array
      ./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "$installer_param_list[@]"


      However, I have tested the parameter passing with a very simple installer script inside the package:



      while ! -z "$1" ; do
      echo "$1"
      shift
      done


      and passing an array like:



      installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )


      results in this output:



      --upgrade-to=19.3.0
      --upgrade-from=19
      .2.0









      share|improve this question
















      In a script I have an associative array like:



      declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )


      Is there a single command to transform that into a parameter list in the form



      --key1=value1 --key2=value2


      without having to manually re-write



       --key1="$VARS[key1]" --key2="$VARS[key2]"


      the use-case I had in mind was to pass the array to a script as a list of parameters, like



      my_script.sh $(to_param_list $VARS)


      To expand on the comment I made on @Kusalananda answer, my exact use case is as follows: I have a script which is used to build a self-extracting installer using makeself, and this script receives some parameters which are to be separated between:



      • parameters for the script itself

      • parameters for the installer inside the self-extracting installer

      The scripts then builds the installer like this:



      to_param_list installer_param_list installer_param_array
      ./makeself ./path/to/sourcedir ./path/to/created/installer "My installer" ./path/to/install/inside/package "$installer_param_list[@]"


      However, I have tested the parameter passing with a very simple installer script inside the package:



      while ! -z "$1" ; do
      echo "$1"
      shift
      done


      and passing an array like:



      installer_param_array=( ["upgrade-from"]="19 .2.0" ["upgrade-to"]="19.3.0" )


      results in this output:



      --upgrade-to=19.3.0
      --upgrade-from=19
      .2.0






      bash parameter associative-array






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 7 hours ago









      Jeff Schaller

      43.4k1160140




      43.4k1160140










      asked yesterday









      Matteo TassinariMatteo Tassinari

      1507




      1507




















          1 Answer
          1






          active

          oldest

          votes


















          11














          With a helper function:



          #!/bin/bash

          to_param_list ()
          declare -n outlist=$1
          declare -n inhash=$2

          for param in "$!inhash[@]"; do
          outlist+=( "--$param=$inhash[$param]" )
          done


          declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )

          to_param_list list my_vars
          my_script.sh "$list[@]"


          The final command in the above script would expand to the equivalent of having written



          my_script.sh "--key2=value" "--key1=value1"


          The to_param_list function takes the name of an array variable and the name of an associative array variable and uses these to create two "name reference" variables in the function (namerefs were introduced in bash release 4.3). These are then use to populate the given array variable with the keys and values in the appropriate format from the associative array.



          The loop in the function iterates over "$!inhash[@]", which is the list of individually quoted keys in your associative array.



          Once the function call returns, the script would use the array to call your other script or command.



          Running the above with



          declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          the script would output



          Arg: --key2=some thing
          Arg: --key3=* * *
          Arg: --key1=hello world


          This shows that the options are generated without word splitting or filename globbing coming into effect. It also shows that the order of the keys may not be preserved since accessing the keys out of an associative array will do so in a fairly random order.




          You can't really use a command substitution safely here as the result of it would be a single string. If unquoted, this string would then be split on whitespace characters (by default), which would additionally split both the keys and values of your associative array. The shell would also perform filename globbing on the resulting words. Double quoting the command substitution would not help as that would result in calling your my_script.sh with a single argument.




          Regarding your issue with makeself:



          The makeself script does this with the arguments to your installer script:



          SCRIPTARGS="$*"


          This saves the arguments as a string in $SCRIPTARGS (concatenated, separated by spaces). This later gets inserted into the self-extracting archive as-is. For the options to be parsed correctly when they are re-evaluated (which they are when running the installer), you will have to provide an extra set of quotes in the values of the parameters for them to be properly delimited.



          installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )


          Note that this is not a bug in my code. It's just a side effect of makeself producing shell code based on user-supplied values.



          Ideally, the makeself script should have written each of the provided arguments with an extra set of quotes around them, but it doesn't, presumable because it's difficult to know what effect that may have. Instead, it leaves it to the user to provide these extra quotes.



          Rerunning my test from above, but now with



          declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          produces



          Arg: --key2='some value'
          Arg: --key3='* * *'
          Arg: --key1='hello world'


          You can see that these strings, when re-evaluated by the shell, would not get split on spaces.



          Obviously, you could use your initial associative array and instead add the quotes in the to_param_list function by changing



          outlist+=( "--$param=$inhash[$param]" )


          into



          outlist+=( "--$param='$inhash[$param]'" )


          Either of these changes to your code would include the single quotes in the values of the options, so a re-evaluation of the values would become necessary.






          share|improve this answer

























          • Thanks, I'm gonna try that right away.

            – Matteo Tassinari
            yesterday











          • I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

            – Matteo Tassinari
            yesterday











          • @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

            – Kusalananda
            yesterday







          • 1





            No, it's not that, I'll try to edit my question to better show my use-case.

            – Matteo Tassinari
            yesterday






          • 1





            I added my actual use-case and the error I'm having

            – Matteo Tassinari
            11 hours ago










          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
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506440%2fpass-associative-array-as-parameter-list-to-script%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









          11














          With a helper function:



          #!/bin/bash

          to_param_list ()
          declare -n outlist=$1
          declare -n inhash=$2

          for param in "$!inhash[@]"; do
          outlist+=( "--$param=$inhash[$param]" )
          done


          declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )

          to_param_list list my_vars
          my_script.sh "$list[@]"


          The final command in the above script would expand to the equivalent of having written



          my_script.sh "--key2=value" "--key1=value1"


          The to_param_list function takes the name of an array variable and the name of an associative array variable and uses these to create two "name reference" variables in the function (namerefs were introduced in bash release 4.3). These are then use to populate the given array variable with the keys and values in the appropriate format from the associative array.



          The loop in the function iterates over "$!inhash[@]", which is the list of individually quoted keys in your associative array.



          Once the function call returns, the script would use the array to call your other script or command.



          Running the above with



          declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          the script would output



          Arg: --key2=some thing
          Arg: --key3=* * *
          Arg: --key1=hello world


          This shows that the options are generated without word splitting or filename globbing coming into effect. It also shows that the order of the keys may not be preserved since accessing the keys out of an associative array will do so in a fairly random order.




          You can't really use a command substitution safely here as the result of it would be a single string. If unquoted, this string would then be split on whitespace characters (by default), which would additionally split both the keys and values of your associative array. The shell would also perform filename globbing on the resulting words. Double quoting the command substitution would not help as that would result in calling your my_script.sh with a single argument.




          Regarding your issue with makeself:



          The makeself script does this with the arguments to your installer script:



          SCRIPTARGS="$*"


          This saves the arguments as a string in $SCRIPTARGS (concatenated, separated by spaces). This later gets inserted into the self-extracting archive as-is. For the options to be parsed correctly when they are re-evaluated (which they are when running the installer), you will have to provide an extra set of quotes in the values of the parameters for them to be properly delimited.



          installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )


          Note that this is not a bug in my code. It's just a side effect of makeself producing shell code based on user-supplied values.



          Ideally, the makeself script should have written each of the provided arguments with an extra set of quotes around them, but it doesn't, presumable because it's difficult to know what effect that may have. Instead, it leaves it to the user to provide these extra quotes.



          Rerunning my test from above, but now with



          declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          produces



          Arg: --key2='some value'
          Arg: --key3='* * *'
          Arg: --key1='hello world'


          You can see that these strings, when re-evaluated by the shell, would not get split on spaces.



          Obviously, you could use your initial associative array and instead add the quotes in the to_param_list function by changing



          outlist+=( "--$param=$inhash[$param]" )


          into



          outlist+=( "--$param='$inhash[$param]'" )


          Either of these changes to your code would include the single quotes in the values of the options, so a re-evaluation of the values would become necessary.






          share|improve this answer

























          • Thanks, I'm gonna try that right away.

            – Matteo Tassinari
            yesterday











          • I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

            – Matteo Tassinari
            yesterday











          • @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

            – Kusalananda
            yesterday







          • 1





            No, it's not that, I'll try to edit my question to better show my use-case.

            – Matteo Tassinari
            yesterday






          • 1





            I added my actual use-case and the error I'm having

            – Matteo Tassinari
            11 hours ago















          11














          With a helper function:



          #!/bin/bash

          to_param_list ()
          declare -n outlist=$1
          declare -n inhash=$2

          for param in "$!inhash[@]"; do
          outlist+=( "--$param=$inhash[$param]" )
          done


          declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )

          to_param_list list my_vars
          my_script.sh "$list[@]"


          The final command in the above script would expand to the equivalent of having written



          my_script.sh "--key2=value" "--key1=value1"


          The to_param_list function takes the name of an array variable and the name of an associative array variable and uses these to create two "name reference" variables in the function (namerefs were introduced in bash release 4.3). These are then use to populate the given array variable with the keys and values in the appropriate format from the associative array.



          The loop in the function iterates over "$!inhash[@]", which is the list of individually quoted keys in your associative array.



          Once the function call returns, the script would use the array to call your other script or command.



          Running the above with



          declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          the script would output



          Arg: --key2=some thing
          Arg: --key3=* * *
          Arg: --key1=hello world


          This shows that the options are generated without word splitting or filename globbing coming into effect. It also shows that the order of the keys may not be preserved since accessing the keys out of an associative array will do so in a fairly random order.




          You can't really use a command substitution safely here as the result of it would be a single string. If unquoted, this string would then be split on whitespace characters (by default), which would additionally split both the keys and values of your associative array. The shell would also perform filename globbing on the resulting words. Double quoting the command substitution would not help as that would result in calling your my_script.sh with a single argument.




          Regarding your issue with makeself:



          The makeself script does this with the arguments to your installer script:



          SCRIPTARGS="$*"


          This saves the arguments as a string in $SCRIPTARGS (concatenated, separated by spaces). This later gets inserted into the self-extracting archive as-is. For the options to be parsed correctly when they are re-evaluated (which they are when running the installer), you will have to provide an extra set of quotes in the values of the parameters for them to be properly delimited.



          installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )


          Note that this is not a bug in my code. It's just a side effect of makeself producing shell code based on user-supplied values.



          Ideally, the makeself script should have written each of the provided arguments with an extra set of quotes around them, but it doesn't, presumable because it's difficult to know what effect that may have. Instead, it leaves it to the user to provide these extra quotes.



          Rerunning my test from above, but now with



          declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          produces



          Arg: --key2='some value'
          Arg: --key3='* * *'
          Arg: --key1='hello world'


          You can see that these strings, when re-evaluated by the shell, would not get split on spaces.



          Obviously, you could use your initial associative array and instead add the quotes in the to_param_list function by changing



          outlist+=( "--$param=$inhash[$param]" )


          into



          outlist+=( "--$param='$inhash[$param]'" )


          Either of these changes to your code would include the single quotes in the values of the options, so a re-evaluation of the values would become necessary.






          share|improve this answer

























          • Thanks, I'm gonna try that right away.

            – Matteo Tassinari
            yesterday











          • I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

            – Matteo Tassinari
            yesterday











          • @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

            – Kusalananda
            yesterday







          • 1





            No, it's not that, I'll try to edit my question to better show my use-case.

            – Matteo Tassinari
            yesterday






          • 1





            I added my actual use-case and the error I'm having

            – Matteo Tassinari
            11 hours ago













          11












          11








          11







          With a helper function:



          #!/bin/bash

          to_param_list ()
          declare -n outlist=$1
          declare -n inhash=$2

          for param in "$!inhash[@]"; do
          outlist+=( "--$param=$inhash[$param]" )
          done


          declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )

          to_param_list list my_vars
          my_script.sh "$list[@]"


          The final command in the above script would expand to the equivalent of having written



          my_script.sh "--key2=value" "--key1=value1"


          The to_param_list function takes the name of an array variable and the name of an associative array variable and uses these to create two "name reference" variables in the function (namerefs were introduced in bash release 4.3). These are then use to populate the given array variable with the keys and values in the appropriate format from the associative array.



          The loop in the function iterates over "$!inhash[@]", which is the list of individually quoted keys in your associative array.



          Once the function call returns, the script would use the array to call your other script or command.



          Running the above with



          declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          the script would output



          Arg: --key2=some thing
          Arg: --key3=* * *
          Arg: --key1=hello world


          This shows that the options are generated without word splitting or filename globbing coming into effect. It also shows that the order of the keys may not be preserved since accessing the keys out of an associative array will do so in a fairly random order.




          You can't really use a command substitution safely here as the result of it would be a single string. If unquoted, this string would then be split on whitespace characters (by default), which would additionally split both the keys and values of your associative array. The shell would also perform filename globbing on the resulting words. Double quoting the command substitution would not help as that would result in calling your my_script.sh with a single argument.




          Regarding your issue with makeself:



          The makeself script does this with the arguments to your installer script:



          SCRIPTARGS="$*"


          This saves the arguments as a string in $SCRIPTARGS (concatenated, separated by spaces). This later gets inserted into the self-extracting archive as-is. For the options to be parsed correctly when they are re-evaluated (which they are when running the installer), you will have to provide an extra set of quotes in the values of the parameters for them to be properly delimited.



          installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )


          Note that this is not a bug in my code. It's just a side effect of makeself producing shell code based on user-supplied values.



          Ideally, the makeself script should have written each of the provided arguments with an extra set of quotes around them, but it doesn't, presumable because it's difficult to know what effect that may have. Instead, it leaves it to the user to provide these extra quotes.



          Rerunning my test from above, but now with



          declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          produces



          Arg: --key2='some value'
          Arg: --key3='* * *'
          Arg: --key1='hello world'


          You can see that these strings, when re-evaluated by the shell, would not get split on spaces.



          Obviously, you could use your initial associative array and instead add the quotes in the to_param_list function by changing



          outlist+=( "--$param=$inhash[$param]" )


          into



          outlist+=( "--$param='$inhash[$param]'" )


          Either of these changes to your code would include the single quotes in the values of the options, so a re-evaluation of the values would become necessary.






          share|improve this answer















          With a helper function:



          #!/bin/bash

          to_param_list ()
          declare -n outlist=$1
          declare -n inhash=$2

          for param in "$!inhash[@]"; do
          outlist+=( "--$param=$inhash[$param]" )
          done


          declare -A my_vars=( ["key1"]="value1" ["key2"]="value" )

          to_param_list list my_vars
          my_script.sh "$list[@]"


          The final command in the above script would expand to the equivalent of having written



          my_script.sh "--key2=value" "--key1=value1"


          The to_param_list function takes the name of an array variable and the name of an associative array variable and uses these to create two "name reference" variables in the function (namerefs were introduced in bash release 4.3). These are then use to populate the given array variable with the keys and values in the appropriate format from the associative array.



          The loop in the function iterates over "$!inhash[@]", which is the list of individually quoted keys in your associative array.



          Once the function call returns, the script would use the array to call your other script or command.



          Running the above with



          declare -A my_vars=( ["key1"]="hello world" ["key2"]="some thing" ["key3"]="* * *" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          the script would output



          Arg: --key2=some thing
          Arg: --key3=* * *
          Arg: --key1=hello world


          This shows that the options are generated without word splitting or filename globbing coming into effect. It also shows that the order of the keys may not be preserved since accessing the keys out of an associative array will do so in a fairly random order.




          You can't really use a command substitution safely here as the result of it would be a single string. If unquoted, this string would then be split on whitespace characters (by default), which would additionally split both the keys and values of your associative array. The shell would also perform filename globbing on the resulting words. Double quoting the command substitution would not help as that would result in calling your my_script.sh with a single argument.




          Regarding your issue with makeself:



          The makeself script does this with the arguments to your installer script:



          SCRIPTARGS="$*"


          This saves the arguments as a string in $SCRIPTARGS (concatenated, separated by spaces). This later gets inserted into the self-extracting archive as-is. For the options to be parsed correctly when they are re-evaluated (which they are when running the installer), you will have to provide an extra set of quotes in the values of the parameters for them to be properly delimited.



          installer_param_array=( ["upgrade-from"]="'19 .2.0'" ["upgrade-to"]="'19.3.0'" )


          Note that this is not a bug in my code. It's just a side effect of makeself producing shell code based on user-supplied values.



          Ideally, the makeself script should have written each of the provided arguments with an extra set of quotes around them, but it doesn't, presumable because it's difficult to know what effect that may have. Instead, it leaves it to the user to provide these extra quotes.



          Rerunning my test from above, but now with



          declare -A my_vars=( ["key1"]="'hello world'" ["key2"]="'some value'" ["key3"]="'* * *'" )

          to_param_list list my_vars
          printf 'Arg: %sn' "$list[@]"


          produces



          Arg: --key2='some value'
          Arg: --key3='* * *'
          Arg: --key1='hello world'


          You can see that these strings, when re-evaluated by the shell, would not get split on spaces.



          Obviously, you could use your initial associative array and instead add the quotes in the to_param_list function by changing



          outlist+=( "--$param=$inhash[$param]" )


          into



          outlist+=( "--$param='$inhash[$param]'" )


          Either of these changes to your code would include the single quotes in the values of the options, so a re-evaluation of the values would become necessary.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 10 hours ago

























          answered yesterday









          KusalanandaKusalananda

          135k17256424




          135k17256424












          • Thanks, I'm gonna try that right away.

            – Matteo Tassinari
            yesterday











          • I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

            – Matteo Tassinari
            yesterday











          • @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

            – Kusalananda
            yesterday







          • 1





            No, it's not that, I'll try to edit my question to better show my use-case.

            – Matteo Tassinari
            yesterday






          • 1





            I added my actual use-case and the error I'm having

            – Matteo Tassinari
            11 hours ago

















          • Thanks, I'm gonna try that right away.

            – Matteo Tassinari
            yesterday











          • I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

            – Matteo Tassinari
            yesterday











          • @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

            – Kusalananda
            yesterday







          • 1





            No, it's not that, I'll try to edit my question to better show my use-case.

            – Matteo Tassinari
            yesterday






          • 1





            I added my actual use-case and the error I'm having

            – Matteo Tassinari
            11 hours ago
















          Thanks, I'm gonna try that right away.

          – Matteo Tassinari
          yesterday





          Thanks, I'm gonna try that right away.

          – Matteo Tassinari
          yesterday













          I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

          – Matteo Tassinari
          yesterday





          I tried your solution, however if one of the values in the starting associative array contains any space, the resulting command will break up

          – Matteo Tassinari
          yesterday













          @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

          – Kusalananda
          yesterday






          @MatteoTassinari No it would not. If it does, then you have forgotten the double quotes in "--$param=$inhash[$param]" or in "$list[@]", or the script that receives the options does something wrong in parsing them.

          – Kusalananda
          yesterday





          1




          1





          No, it's not that, I'll try to edit my question to better show my use-case.

          – Matteo Tassinari
          yesterday





          No, it's not that, I'll try to edit my question to better show my use-case.

          – Matteo Tassinari
          yesterday




          1




          1





          I added my actual use-case and the error I'm having

          – Matteo Tassinari
          11 hours ago





          I added my actual use-case and the error I'm having

          – Matteo Tassinari
          11 hours ago

















          draft saved

          draft discarded
















































          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.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f506440%2fpass-associative-array-as-parameter-list-to-script%23new-answer', 'question_page');

          );

          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







          Popular posts from this blog

          Adding axes to figuresAdding axes labels to LaTeX figuresLaTeX equivalent of ConTeXt buffersRotate a node but not its content: the case of the ellipse decorationHow to define the default vertical distance between nodes?TikZ scaling graphic and adjust node position and keep font sizeNumerical conditional within tikz keys?adding axes to shapesAlign axes across subfiguresAdding figures with a certain orderLine up nested tikz enviroments or how to get rid of themAdding axes labels to LaTeX figures

          Luettelo Yhdysvaltain laivaston lentotukialuksista Lähteet | Navigointivalikko

          Gary (muusikko) Sisällysluettelo Historia | Rockin' High | Lähteet | Aiheesta muualla | NavigointivalikkoInfobox OKTuomas "Gary" Keskinen Ancaran kitaristiksiProjekti Rockin' High