Passing named arguments to shell scripts

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












88















Is there any easy way to pass (receive) named parameters to a shell script?



For example,



my_script -p_out '/some/path' -arg_1 '5'


And inside my_script.sh receive them as:



# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"


Is this possible in Bash or Zsh?










share|improve this question



















  • 2





    have a look at docopt – it helps with named parameters and does input validation, too

    – Beat
    May 14 '14 at 21:55











  • Relevant: stackoverflow.com/questions/5499472/…

    – Kaz
    Aug 24 '17 at 4:47















88















Is there any easy way to pass (receive) named parameters to a shell script?



For example,



my_script -p_out '/some/path' -arg_1 '5'


And inside my_script.sh receive them as:



# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"


Is this possible in Bash or Zsh?










share|improve this question



















  • 2





    have a look at docopt – it helps with named parameters and does input validation, too

    – Beat
    May 14 '14 at 21:55











  • Relevant: stackoverflow.com/questions/5499472/…

    – Kaz
    Aug 24 '17 at 4:47













88












88








88


33






Is there any easy way to pass (receive) named parameters to a shell script?



For example,



my_script -p_out '/some/path' -arg_1 '5'


And inside my_script.sh receive them as:



# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"


Is this possible in Bash or Zsh?










share|improve this question
















Is there any easy way to pass (receive) named parameters to a shell script?



For example,



my_script -p_out '/some/path' -arg_1 '5'


And inside my_script.sh receive them as:



# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']

printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"


Is this possible in Bash or Zsh?







bash shell-script zsh arguments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 7 '17 at 11:11









Timo

19817




19817










asked May 14 '14 at 18:19









Amelio Vazquez-ReinaAmelio Vazquez-Reina

12.8k53138235




12.8k53138235







  • 2





    have a look at docopt – it helps with named parameters and does input validation, too

    – Beat
    May 14 '14 at 21:55











  • Relevant: stackoverflow.com/questions/5499472/…

    – Kaz
    Aug 24 '17 at 4:47












  • 2





    have a look at docopt – it helps with named parameters and does input validation, too

    – Beat
    May 14 '14 at 21:55











  • Relevant: stackoverflow.com/questions/5499472/…

    – Kaz
    Aug 24 '17 at 4:47







2




2





have a look at docopt – it helps with named parameters and does input validation, too

– Beat
May 14 '14 at 21:55





have a look at docopt – it helps with named parameters and does input validation, too

– Beat
May 14 '14 at 21:55













Relevant: stackoverflow.com/questions/5499472/…

– Kaz
Aug 24 '17 at 4:47





Relevant: stackoverflow.com/questions/5499472/…

– Kaz
Aug 24 '17 at 4:47










8 Answers
8






active

oldest

votes


















27














The probably closest syntax to that is:



p_out='/some/path' arg_1='5' my_script





share|improve this answer


















  • 7





    Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

    – chepner
    May 14 '14 at 22:55






  • 11





    I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

    – Lucas Cimon
    Sep 1 '15 at 9:13











  • @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

    – Nikos Alexandris
    Dec 18 '17 at 15:46






  • 1





    @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

    – Hauke Laging
    Mar 22 '18 at 11:02











  • You're right @HaukeLaging, thanks for correcting that

    – Lucas Cimon
    Apr 19 '18 at 9:01


















123














If you don't mind being limited to single-letter argument names i.e. my_script -p '/some/path' -a5, then in bash you could use the built-in getopts, e.g.



#!/bin/bash

while getopts ":a:p:" opt; do
case $opt in
a) arg_1="$OPTARG"
;;
p) p_out="$OPTARG"
;;
?) echo "Invalid option -$OPTARG" >&2
;;
esac
done

printf "Argument p_out is %sn" "$p_out"
printf "Argument arg_1 is %sn" "$arg_1"


Then you can do



$ ./my_script -p '/some/path' -a5
Argument p_out is /some/path
Argument arg_1 is 5


There is a helpful Small getopts tutorial or you can type help getopts at the shell prompt.






share|improve this answer




















  • 21





    This should be the accepted answer

    – Kaushik Ghose
    May 21 '15 at 13:38






  • 3





    I know this is a bit old, but why only 1 letter for the arguments?

    – Kevin
    Apr 28 '17 at 15:54











  • I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

    – Milkncookiez
    Feb 14 '18 at 22:48







  • 2





    @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

    – Derek
    May 24 '18 at 15:30


















29














I stole this from drupal.org, but you could do something like this:



while [ $# -gt 0 ]; do
case "$1" in
--p_out=*)
p_out="$1#*="
;;
--arg_1=*)
arg_1="$1#*="
;;
*)
printf "***************************n"
printf "* Error: Invalid argument.*n"
printf "***************************n"
exit 1
esac
shift
done


The only caveat is that you have to use the syntax my_script --p_out=/some/path --arg_1=5.






share|improve this answer


















  • 5





    The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

    – Milkncookiez
    May 30 '17 at 14:27


















14














I use this script and works like a charm:



for ARGUMENT in "$@"
do

KEY=$(echo $ARGUMENT | cut -f1 -d=)
VALUE=$(echo $ARGUMENT | cut -f2 -d=)

case "$KEY" in
STEPS) STEPS=$VALUE ;;
REPOSITORY_NAME) REPOSITORY_NAME=$VALUE ;;
*)
esac


done

echo "STEPS = $STEPS"
echo "REPOSITORY_NAME = $REPOSITORY_NAME"


Usage



bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"


Console result :



STEPS = ABC
REPOSITORY_NAME = stackexchange


STEPS and REPOSITORY_NAME are ready to use in the script.



It does not matter what order the arguments are in.



Hope this helps.






share|improve this answer




















  • 1





    This is neat and should be the accepted answer.

    – mmorin
    Feb 1 at 17:07











  • thank you @mmorin

    – JRichardsz
    Feb 1 at 18:09











  • Very clear and helpful. Thanks.

    – rotarydial
    Feb 4 at 3:28


















13














With zsh, you'd use zparseopts:



#! /bin/zsh -
zmodload zsh/zutil
zparseopts -A ARGUMENTS -p_out: -arg_1:

p_out=$ARGUMENTS[--p_out]
arg1=$ARGUMENTS[--arg_1]

printf 'Argument p_out is "%s"n' "$p_out"
printf 'Argument arg_1 is "%s"n' "$arg_1"


But you'd call the script with myscript --p_out foo.



Note that zparseopts doesn't support abbreviating long options or the --p_out=foo syntax like GNU getopt(3) does.






share|improve this answer























  • Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

    – Timo
    Nov 7 '17 at 14:59











  • @Timo, see info zsh zparseopts for details

    – Stéphane Chazelas
    Nov 7 '17 at 16:20


















8














I just came up with this script



while [ $# -gt 0 ]; do

if [[ $1 == *"--"* ]]; then
v="$1/--/"
declare $v="$2"
fi

shift
done


pass it like my_script --p_out /some/path --arg_1 5 and then in the script you can use $arg_1 and $p_out.






share|improve this answer























  • I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

    – hol
    Sep 24 '18 at 9:45



















-2














If a function or an application has more than zero arguments, it always has a last argument.



If you want to read option flag and value pairs, as in:
$ ./t.sh -o output -i input -l last



And you want to accept a variable number of option/value pairs,



And do not want a huge "if .. then .. else .. fi" tree,



Then after checking for an argument count of non-zero and even,



Write a while loop with these four eval statements as the body, followed by a case statement using the two values determined in each pass through the loop.



The tricky part of the scripting is demonstrated here:



#!/bin/sh 

# For each pair - this chunk is hard coded for the last pair.
eval TMP="'$'$#"
eval "PICK=$TMP"
eval TMP="'$'$(($#-1))"
eval "OPT=$TMP"

# process as required - usually a case statement on $OPT
echo "$OPT n $PICK"

# Then decrement the indices (as in third eval statement)

:<< EoF_test
$ ./t.sh -o output -i input -l last
-l
last
$ ./t.sh -o output -l last
-l
last
$ ./t.sh -l last
-l
last
EoF_test





share|improve this answer
































    -3














    mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
    #!/bin/sh
    eval "$1"


    you've just injected command line parameters inside script scope !!






    share|improve this answer




















    • 3





      This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

      – Michael Mrozek
      Feb 18 '15 at 14:48










    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%2f129391%2fpassing-named-arguments-to-shell-scripts%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    8 Answers
    8






    active

    oldest

    votes








    8 Answers
    8






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    27














    The probably closest syntax to that is:



    p_out='/some/path' arg_1='5' my_script





    share|improve this answer


















    • 7





      Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

      – chepner
      May 14 '14 at 22:55






    • 11





      I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

      – Lucas Cimon
      Sep 1 '15 at 9:13











    • @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

      – Nikos Alexandris
      Dec 18 '17 at 15:46






    • 1





      @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

      – Hauke Laging
      Mar 22 '18 at 11:02











    • You're right @HaukeLaging, thanks for correcting that

      – Lucas Cimon
      Apr 19 '18 at 9:01















    27














    The probably closest syntax to that is:



    p_out='/some/path' arg_1='5' my_script





    share|improve this answer


















    • 7





      Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

      – chepner
      May 14 '14 at 22:55






    • 11





      I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

      – Lucas Cimon
      Sep 1 '15 at 9:13











    • @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

      – Nikos Alexandris
      Dec 18 '17 at 15:46






    • 1





      @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

      – Hauke Laging
      Mar 22 '18 at 11:02











    • You're right @HaukeLaging, thanks for correcting that

      – Lucas Cimon
      Apr 19 '18 at 9:01













    27












    27








    27







    The probably closest syntax to that is:



    p_out='/some/path' arg_1='5' my_script





    share|improve this answer













    The probably closest syntax to that is:



    p_out='/some/path' arg_1='5' my_script






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 14 '14 at 18:27









    Hauke LagingHauke Laging

    57.1k1287135




    57.1k1287135







    • 7





      Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

      – chepner
      May 14 '14 at 22:55






    • 11





      I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

      – Lucas Cimon
      Sep 1 '15 at 9:13











    • @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

      – Nikos Alexandris
      Dec 18 '17 at 15:46






    • 1





      @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

      – Hauke Laging
      Mar 22 '18 at 11:02











    • You're right @HaukeLaging, thanks for correcting that

      – Lucas Cimon
      Apr 19 '18 at 9:01












    • 7





      Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

      – chepner
      May 14 '14 at 22:55






    • 11





      I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

      – Lucas Cimon
      Sep 1 '15 at 9:13











    • @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

      – Nikos Alexandris
      Dec 18 '17 at 15:46






    • 1





      @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

      – Hauke Laging
      Mar 22 '18 at 11:02











    • You're right @HaukeLaging, thanks for correcting that

      – Lucas Cimon
      Apr 19 '18 at 9:01







    7




    7





    Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

    – chepner
    May 14 '14 at 22:55





    Related to this, if the -k option is set in the calling shell, then my_script p_out='/some/path' arg_1='5' has the same effect. (All arguments in the form of an assignment are added to the environment, not just those assignments preceding the command.)

    – chepner
    May 14 '14 at 22:55




    11




    11





    I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

    – Lucas Cimon
    Sep 1 '15 at 9:13





    I used to love this syntax, but it has a BIG caveat: after the command/function execution, those variables will still be defined in the current scope ! E.g.: x=42 echo $x; echo $x Which means in the next execution of my_script, if p_out is omitted, it will stick to the value passed the last time !! ('/some/path')

    – Lucas Cimon
    Sep 1 '15 at 9:13













    @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

    – Nikos Alexandris
    Dec 18 '17 at 15:46





    @LucasCimon Can you not unset them after the first execution, reset them before the next execution?

    – Nikos Alexandris
    Dec 18 '17 at 15:46




    1




    1





    @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

    – Hauke Laging
    Mar 22 '18 at 11:02





    @LucasCimon That is not correct. x=42 echo $x does not even output anything if $x was not defined before.

    – Hauke Laging
    Mar 22 '18 at 11:02













    You're right @HaukeLaging, thanks for correcting that

    – Lucas Cimon
    Apr 19 '18 at 9:01





    You're right @HaukeLaging, thanks for correcting that

    – Lucas Cimon
    Apr 19 '18 at 9:01













    123














    If you don't mind being limited to single-letter argument names i.e. my_script -p '/some/path' -a5, then in bash you could use the built-in getopts, e.g.



    #!/bin/bash

    while getopts ":a:p:" opt; do
    case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    ?) echo "Invalid option -$OPTARG" >&2
    ;;
    esac
    done

    printf "Argument p_out is %sn" "$p_out"
    printf "Argument arg_1 is %sn" "$arg_1"


    Then you can do



    $ ./my_script -p '/some/path' -a5
    Argument p_out is /some/path
    Argument arg_1 is 5


    There is a helpful Small getopts tutorial or you can type help getopts at the shell prompt.






    share|improve this answer




















    • 21





      This should be the accepted answer

      – Kaushik Ghose
      May 21 '15 at 13:38






    • 3





      I know this is a bit old, but why only 1 letter for the arguments?

      – Kevin
      Apr 28 '17 at 15:54











    • I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

      – Milkncookiez
      Feb 14 '18 at 22:48







    • 2





      @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

      – Derek
      May 24 '18 at 15:30















    123














    If you don't mind being limited to single-letter argument names i.e. my_script -p '/some/path' -a5, then in bash you could use the built-in getopts, e.g.



    #!/bin/bash

    while getopts ":a:p:" opt; do
    case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    ?) echo "Invalid option -$OPTARG" >&2
    ;;
    esac
    done

    printf "Argument p_out is %sn" "$p_out"
    printf "Argument arg_1 is %sn" "$arg_1"


    Then you can do



    $ ./my_script -p '/some/path' -a5
    Argument p_out is /some/path
    Argument arg_1 is 5


    There is a helpful Small getopts tutorial or you can type help getopts at the shell prompt.






    share|improve this answer




















    • 21





      This should be the accepted answer

      – Kaushik Ghose
      May 21 '15 at 13:38






    • 3





      I know this is a bit old, but why only 1 letter for the arguments?

      – Kevin
      Apr 28 '17 at 15:54











    • I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

      – Milkncookiez
      Feb 14 '18 at 22:48







    • 2





      @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

      – Derek
      May 24 '18 at 15:30













    123












    123








    123







    If you don't mind being limited to single-letter argument names i.e. my_script -p '/some/path' -a5, then in bash you could use the built-in getopts, e.g.



    #!/bin/bash

    while getopts ":a:p:" opt; do
    case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    ?) echo "Invalid option -$OPTARG" >&2
    ;;
    esac
    done

    printf "Argument p_out is %sn" "$p_out"
    printf "Argument arg_1 is %sn" "$arg_1"


    Then you can do



    $ ./my_script -p '/some/path' -a5
    Argument p_out is /some/path
    Argument arg_1 is 5


    There is a helpful Small getopts tutorial or you can type help getopts at the shell prompt.






    share|improve this answer















    If you don't mind being limited to single-letter argument names i.e. my_script -p '/some/path' -a5, then in bash you could use the built-in getopts, e.g.



    #!/bin/bash

    while getopts ":a:p:" opt; do
    case $opt in
    a) arg_1="$OPTARG"
    ;;
    p) p_out="$OPTARG"
    ;;
    ?) echo "Invalid option -$OPTARG" >&2
    ;;
    esac
    done

    printf "Argument p_out is %sn" "$p_out"
    printf "Argument arg_1 is %sn" "$arg_1"


    Then you can do



    $ ./my_script -p '/some/path' -a5
    Argument p_out is /some/path
    Argument arg_1 is 5


    There is a helpful Small getopts tutorial or you can type help getopts at the shell prompt.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Oct 28 '16 at 13:04









    Community

    1




    1










    answered May 14 '14 at 19:36









    steeldriversteeldriver

    36.6k35287




    36.6k35287







    • 21





      This should be the accepted answer

      – Kaushik Ghose
      May 21 '15 at 13:38






    • 3





      I know this is a bit old, but why only 1 letter for the arguments?

      – Kevin
      Apr 28 '17 at 15:54











    • I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

      – Milkncookiez
      Feb 14 '18 at 22:48







    • 2





      @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

      – Derek
      May 24 '18 at 15:30












    • 21





      This should be the accepted answer

      – Kaushik Ghose
      May 21 '15 at 13:38






    • 3





      I know this is a bit old, but why only 1 letter for the arguments?

      – Kevin
      Apr 28 '17 at 15:54











    • I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

      – Milkncookiez
      Feb 14 '18 at 22:48







    • 2





      @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

      – Derek
      May 24 '18 at 15:30







    21




    21





    This should be the accepted answer

    – Kaushik Ghose
    May 21 '15 at 13:38





    This should be the accepted answer

    – Kaushik Ghose
    May 21 '15 at 13:38




    3




    3





    I know this is a bit old, but why only 1 letter for the arguments?

    – Kevin
    Apr 28 '17 at 15:54





    I know this is a bit old, but why only 1 letter for the arguments?

    – Kevin
    Apr 28 '17 at 15:54













    I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

    – Milkncookiez
    Feb 14 '18 at 22:48






    I implemented this (but with i and d). When I run it with my_script -i asd -d asd I get an empty string for the d argument. When I run it my_script -d asd -i asd I get empty string for both arguments.

    – Milkncookiez
    Feb 14 '18 at 22:48





    2




    2





    @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

    – Derek
    May 24 '18 at 15:30





    @Milkncookiez -- I had a similar problem -- I didn't include a ':' after the last argument (a 'w' in my case). Once I added the ':' it started working as expected

    – Derek
    May 24 '18 at 15:30











    29














    I stole this from drupal.org, but you could do something like this:



    while [ $# -gt 0 ]; do
    case "$1" in
    --p_out=*)
    p_out="$1#*="
    ;;
    --arg_1=*)
    arg_1="$1#*="
    ;;
    *)
    printf "***************************n"
    printf "* Error: Invalid argument.*n"
    printf "***************************n"
    exit 1
    esac
    shift
    done


    The only caveat is that you have to use the syntax my_script --p_out=/some/path --arg_1=5.






    share|improve this answer


















    • 5





      The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

      – Milkncookiez
      May 30 '17 at 14:27















    29














    I stole this from drupal.org, but you could do something like this:



    while [ $# -gt 0 ]; do
    case "$1" in
    --p_out=*)
    p_out="$1#*="
    ;;
    --arg_1=*)
    arg_1="$1#*="
    ;;
    *)
    printf "***************************n"
    printf "* Error: Invalid argument.*n"
    printf "***************************n"
    exit 1
    esac
    shift
    done


    The only caveat is that you have to use the syntax my_script --p_out=/some/path --arg_1=5.






    share|improve this answer


















    • 5





      The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

      – Milkncookiez
      May 30 '17 at 14:27













    29












    29








    29







    I stole this from drupal.org, but you could do something like this:



    while [ $# -gt 0 ]; do
    case "$1" in
    --p_out=*)
    p_out="$1#*="
    ;;
    --arg_1=*)
    arg_1="$1#*="
    ;;
    *)
    printf "***************************n"
    printf "* Error: Invalid argument.*n"
    printf "***************************n"
    exit 1
    esac
    shift
    done


    The only caveat is that you have to use the syntax my_script --p_out=/some/path --arg_1=5.






    share|improve this answer













    I stole this from drupal.org, but you could do something like this:



    while [ $# -gt 0 ]; do
    case "$1" in
    --p_out=*)
    p_out="$1#*="
    ;;
    --arg_1=*)
    arg_1="$1#*="
    ;;
    *)
    printf "***************************n"
    printf "* Error: Invalid argument.*n"
    printf "***************************n"
    exit 1
    esac
    shift
    done


    The only caveat is that you have to use the syntax my_script --p_out=/some/path --arg_1=5.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 21 '15 at 20:51









    cdmocdmo

    39035




    39035







    • 5





      The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

      – Milkncookiez
      May 30 '17 at 14:27












    • 5





      The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

      – Milkncookiez
      May 30 '17 at 14:27







    5




    5





    The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

    – Milkncookiez
    May 30 '17 at 14:27





    The caveat is not necessary. :) You can have the conditions as follows: -c|--condition)

    – Milkncookiez
    May 30 '17 at 14:27











    14














    I use this script and works like a charm:



    for ARGUMENT in "$@"
    do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)

    case "$KEY" in
    STEPS) STEPS=$VALUE ;;
    REPOSITORY_NAME) REPOSITORY_NAME=$VALUE ;;
    *)
    esac


    done

    echo "STEPS = $STEPS"
    echo "REPOSITORY_NAME = $REPOSITORY_NAME"


    Usage



    bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"


    Console result :



    STEPS = ABC
    REPOSITORY_NAME = stackexchange


    STEPS and REPOSITORY_NAME are ready to use in the script.



    It does not matter what order the arguments are in.



    Hope this helps.






    share|improve this answer




















    • 1





      This is neat and should be the accepted answer.

      – mmorin
      Feb 1 at 17:07











    • thank you @mmorin

      – JRichardsz
      Feb 1 at 18:09











    • Very clear and helpful. Thanks.

      – rotarydial
      Feb 4 at 3:28















    14














    I use this script and works like a charm:



    for ARGUMENT in "$@"
    do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)

    case "$KEY" in
    STEPS) STEPS=$VALUE ;;
    REPOSITORY_NAME) REPOSITORY_NAME=$VALUE ;;
    *)
    esac


    done

    echo "STEPS = $STEPS"
    echo "REPOSITORY_NAME = $REPOSITORY_NAME"


    Usage



    bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"


    Console result :



    STEPS = ABC
    REPOSITORY_NAME = stackexchange


    STEPS and REPOSITORY_NAME are ready to use in the script.



    It does not matter what order the arguments are in.



    Hope this helps.






    share|improve this answer




















    • 1





      This is neat and should be the accepted answer.

      – mmorin
      Feb 1 at 17:07











    • thank you @mmorin

      – JRichardsz
      Feb 1 at 18:09











    • Very clear and helpful. Thanks.

      – rotarydial
      Feb 4 at 3:28













    14












    14








    14







    I use this script and works like a charm:



    for ARGUMENT in "$@"
    do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)

    case "$KEY" in
    STEPS) STEPS=$VALUE ;;
    REPOSITORY_NAME) REPOSITORY_NAME=$VALUE ;;
    *)
    esac


    done

    echo "STEPS = $STEPS"
    echo "REPOSITORY_NAME = $REPOSITORY_NAME"


    Usage



    bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"


    Console result :



    STEPS = ABC
    REPOSITORY_NAME = stackexchange


    STEPS and REPOSITORY_NAME are ready to use in the script.



    It does not matter what order the arguments are in.



    Hope this helps.






    share|improve this answer















    I use this script and works like a charm:



    for ARGUMENT in "$@"
    do

    KEY=$(echo $ARGUMENT | cut -f1 -d=)
    VALUE=$(echo $ARGUMENT | cut -f2 -d=)

    case "$KEY" in
    STEPS) STEPS=$VALUE ;;
    REPOSITORY_NAME) REPOSITORY_NAME=$VALUE ;;
    *)
    esac


    done

    echo "STEPS = $STEPS"
    echo "REPOSITORY_NAME = $REPOSITORY_NAME"


    Usage



    bash my_scripts.sh STEPS="ABC" REPOSITORY_NAME="stackexchange"


    Console result :



    STEPS = ABC
    REPOSITORY_NAME = stackexchange


    STEPS and REPOSITORY_NAME are ready to use in the script.



    It does not matter what order the arguments are in.



    Hope this helps.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Feb 24 at 12:24

























    answered Mar 24 '17 at 17:17









    JRichardszJRichardsz

    24926




    24926







    • 1





      This is neat and should be the accepted answer.

      – mmorin
      Feb 1 at 17:07











    • thank you @mmorin

      – JRichardsz
      Feb 1 at 18:09











    • Very clear and helpful. Thanks.

      – rotarydial
      Feb 4 at 3:28












    • 1





      This is neat and should be the accepted answer.

      – mmorin
      Feb 1 at 17:07











    • thank you @mmorin

      – JRichardsz
      Feb 1 at 18:09











    • Very clear and helpful. Thanks.

      – rotarydial
      Feb 4 at 3:28







    1




    1





    This is neat and should be the accepted answer.

    – mmorin
    Feb 1 at 17:07





    This is neat and should be the accepted answer.

    – mmorin
    Feb 1 at 17:07













    thank you @mmorin

    – JRichardsz
    Feb 1 at 18:09





    thank you @mmorin

    – JRichardsz
    Feb 1 at 18:09













    Very clear and helpful. Thanks.

    – rotarydial
    Feb 4 at 3:28





    Very clear and helpful. Thanks.

    – rotarydial
    Feb 4 at 3:28











    13














    With zsh, you'd use zparseopts:



    #! /bin/zsh -
    zmodload zsh/zutil
    zparseopts -A ARGUMENTS -p_out: -arg_1:

    p_out=$ARGUMENTS[--p_out]
    arg1=$ARGUMENTS[--arg_1]

    printf 'Argument p_out is "%s"n' "$p_out"
    printf 'Argument arg_1 is "%s"n' "$arg_1"


    But you'd call the script with myscript --p_out foo.



    Note that zparseopts doesn't support abbreviating long options or the --p_out=foo syntax like GNU getopt(3) does.






    share|improve this answer























    • Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

      – Timo
      Nov 7 '17 at 14:59











    • @Timo, see info zsh zparseopts for details

      – Stéphane Chazelas
      Nov 7 '17 at 16:20















    13














    With zsh, you'd use zparseopts:



    #! /bin/zsh -
    zmodload zsh/zutil
    zparseopts -A ARGUMENTS -p_out: -arg_1:

    p_out=$ARGUMENTS[--p_out]
    arg1=$ARGUMENTS[--arg_1]

    printf 'Argument p_out is "%s"n' "$p_out"
    printf 'Argument arg_1 is "%s"n' "$arg_1"


    But you'd call the script with myscript --p_out foo.



    Note that zparseopts doesn't support abbreviating long options or the --p_out=foo syntax like GNU getopt(3) does.






    share|improve this answer























    • Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

      – Timo
      Nov 7 '17 at 14:59











    • @Timo, see info zsh zparseopts for details

      – Stéphane Chazelas
      Nov 7 '17 at 16:20













    13












    13








    13







    With zsh, you'd use zparseopts:



    #! /bin/zsh -
    zmodload zsh/zutil
    zparseopts -A ARGUMENTS -p_out: -arg_1:

    p_out=$ARGUMENTS[--p_out]
    arg1=$ARGUMENTS[--arg_1]

    printf 'Argument p_out is "%s"n' "$p_out"
    printf 'Argument arg_1 is "%s"n' "$arg_1"


    But you'd call the script with myscript --p_out foo.



    Note that zparseopts doesn't support abbreviating long options or the --p_out=foo syntax like GNU getopt(3) does.






    share|improve this answer













    With zsh, you'd use zparseopts:



    #! /bin/zsh -
    zmodload zsh/zutil
    zparseopts -A ARGUMENTS -p_out: -arg_1:

    p_out=$ARGUMENTS[--p_out]
    arg1=$ARGUMENTS[--arg_1]

    printf 'Argument p_out is "%s"n' "$p_out"
    printf 'Argument arg_1 is "%s"n' "$arg_1"


    But you'd call the script with myscript --p_out foo.



    Note that zparseopts doesn't support abbreviating long options or the --p_out=foo syntax like GNU getopt(3) does.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered May 19 '14 at 13:15









    Stéphane ChazelasStéphane Chazelas

    308k57582940




    308k57582940












    • Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

      – Timo
      Nov 7 '17 at 14:59











    • @Timo, see info zsh zparseopts for details

      – Stéphane Chazelas
      Nov 7 '17 at 16:20

















    • Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

      – Timo
      Nov 7 '17 at 14:59











    • @Timo, see info zsh zparseopts for details

      – Stéphane Chazelas
      Nov 7 '17 at 16:20
















    Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

    – Timo
    Nov 7 '17 at 14:59





    Do you know why the zparseopts uses just one dash for the arguments whereas in the it is 2 dashes? Does not make sense!

    – Timo
    Nov 7 '17 at 14:59













    @Timo, see info zsh zparseopts for details

    – Stéphane Chazelas
    Nov 7 '17 at 16:20





    @Timo, see info zsh zparseopts for details

    – Stéphane Chazelas
    Nov 7 '17 at 16:20











    8














    I just came up with this script



    while [ $# -gt 0 ]; do

    if [[ $1 == *"--"* ]]; then
    v="$1/--/"
    declare $v="$2"
    fi

    shift
    done


    pass it like my_script --p_out /some/path --arg_1 5 and then in the script you can use $arg_1 and $p_out.






    share|improve this answer























    • I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

      – hol
      Sep 24 '18 at 9:45
















    8














    I just came up with this script



    while [ $# -gt 0 ]; do

    if [[ $1 == *"--"* ]]; then
    v="$1/--/"
    declare $v="$2"
    fi

    shift
    done


    pass it like my_script --p_out /some/path --arg_1 5 and then in the script you can use $arg_1 and $p_out.






    share|improve this answer























    • I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

      – hol
      Sep 24 '18 at 9:45














    8












    8








    8







    I just came up with this script



    while [ $# -gt 0 ]; do

    if [[ $1 == *"--"* ]]; then
    v="$1/--/"
    declare $v="$2"
    fi

    shift
    done


    pass it like my_script --p_out /some/path --arg_1 5 and then in the script you can use $arg_1 and $p_out.






    share|improve this answer













    I just came up with this script



    while [ $# -gt 0 ]; do

    if [[ $1 == *"--"* ]]; then
    v="$1/--/"
    declare $v="$2"
    fi

    shift
    done


    pass it like my_script --p_out /some/path --arg_1 5 and then in the script you can use $arg_1 and $p_out.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Aug 24 '17 at 4:38









    Shahzad MalikShahzad Malik

    18111




    18111












    • I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

      – hol
      Sep 24 '18 at 9:45


















    • I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

      – hol
      Sep 24 '18 at 9:45

















    I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

    – hol
    Sep 24 '18 at 9:45






    I like this solution in KSH88 I had to v=``echo $1 | awk 'print substr($1,3)'`` typeset $v="$2" (Remove one backtick each side)

    – hol
    Sep 24 '18 at 9:45












    -2














    If a function or an application has more than zero arguments, it always has a last argument.



    If you want to read option flag and value pairs, as in:
    $ ./t.sh -o output -i input -l last



    And you want to accept a variable number of option/value pairs,



    And do not want a huge "if .. then .. else .. fi" tree,



    Then after checking for an argument count of non-zero and even,



    Write a while loop with these four eval statements as the body, followed by a case statement using the two values determined in each pass through the loop.



    The tricky part of the scripting is demonstrated here:



    #!/bin/sh 

    # For each pair - this chunk is hard coded for the last pair.
    eval TMP="'$'$#"
    eval "PICK=$TMP"
    eval TMP="'$'$(($#-1))"
    eval "OPT=$TMP"

    # process as required - usually a case statement on $OPT
    echo "$OPT n $PICK"

    # Then decrement the indices (as in third eval statement)

    :<< EoF_test
    $ ./t.sh -o output -i input -l last
    -l
    last
    $ ./t.sh -o output -l last
    -l
    last
    $ ./t.sh -l last
    -l
    last
    EoF_test





    share|improve this answer





























      -2














      If a function or an application has more than zero arguments, it always has a last argument.



      If you want to read option flag and value pairs, as in:
      $ ./t.sh -o output -i input -l last



      And you want to accept a variable number of option/value pairs,



      And do not want a huge "if .. then .. else .. fi" tree,



      Then after checking for an argument count of non-zero and even,



      Write a while loop with these four eval statements as the body, followed by a case statement using the two values determined in each pass through the loop.



      The tricky part of the scripting is demonstrated here:



      #!/bin/sh 

      # For each pair - this chunk is hard coded for the last pair.
      eval TMP="'$'$#"
      eval "PICK=$TMP"
      eval TMP="'$'$(($#-1))"
      eval "OPT=$TMP"

      # process as required - usually a case statement on $OPT
      echo "$OPT n $PICK"

      # Then decrement the indices (as in third eval statement)

      :<< EoF_test
      $ ./t.sh -o output -i input -l last
      -l
      last
      $ ./t.sh -o output -l last
      -l
      last
      $ ./t.sh -l last
      -l
      last
      EoF_test





      share|improve this answer



























        -2












        -2








        -2







        If a function or an application has more than zero arguments, it always has a last argument.



        If you want to read option flag and value pairs, as in:
        $ ./t.sh -o output -i input -l last



        And you want to accept a variable number of option/value pairs,



        And do not want a huge "if .. then .. else .. fi" tree,



        Then after checking for an argument count of non-zero and even,



        Write a while loop with these four eval statements as the body, followed by a case statement using the two values determined in each pass through the loop.



        The tricky part of the scripting is demonstrated here:



        #!/bin/sh 

        # For each pair - this chunk is hard coded for the last pair.
        eval TMP="'$'$#"
        eval "PICK=$TMP"
        eval TMP="'$'$(($#-1))"
        eval "OPT=$TMP"

        # process as required - usually a case statement on $OPT
        echo "$OPT n $PICK"

        # Then decrement the indices (as in third eval statement)

        :<< EoF_test
        $ ./t.sh -o output -i input -l last
        -l
        last
        $ ./t.sh -o output -l last
        -l
        last
        $ ./t.sh -l last
        -l
        last
        EoF_test





        share|improve this answer















        If a function or an application has more than zero arguments, it always has a last argument.



        If you want to read option flag and value pairs, as in:
        $ ./t.sh -o output -i input -l last



        And you want to accept a variable number of option/value pairs,



        And do not want a huge "if .. then .. else .. fi" tree,



        Then after checking for an argument count of non-zero and even,



        Write a while loop with these four eval statements as the body, followed by a case statement using the two values determined in each pass through the loop.



        The tricky part of the scripting is demonstrated here:



        #!/bin/sh 

        # For each pair - this chunk is hard coded for the last pair.
        eval TMP="'$'$#"
        eval "PICK=$TMP"
        eval TMP="'$'$(($#-1))"
        eval "OPT=$TMP"

        # process as required - usually a case statement on $OPT
        echo "$OPT n $PICK"

        # Then decrement the indices (as in third eval statement)

        :<< EoF_test
        $ ./t.sh -o output -i input -l last
        -l
        last
        $ ./t.sh -o output -l last
        -l
        last
        $ ./t.sh -l last
        -l
        last
        EoF_test






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Oct 23 '16 at 20:48

























        answered Oct 23 '16 at 20:38









        knc1knc1

        52




        52





















            -3














            mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
            #!/bin/sh
            eval "$1"


            you've just injected command line parameters inside script scope !!






            share|improve this answer




















            • 3





              This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

              – Michael Mrozek
              Feb 18 '15 at 14:48















            -3














            mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
            #!/bin/sh
            eval "$1"


            you've just injected command line parameters inside script scope !!






            share|improve this answer




















            • 3





              This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

              – Michael Mrozek
              Feb 18 '15 at 14:48













            -3












            -3








            -3







            mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
            #!/bin/sh
            eval "$1"


            you've just injected command line parameters inside script scope !!






            share|improve this answer















            mitsos@redhat24$ my_script "a=1;b=mitsos;c=karamitsos"
            #!/bin/sh
            eval "$1"


            you've just injected command line parameters inside script scope !!







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited May 21 '15 at 21:16









            Stéphane Chazelas

            308k57582940




            308k57582940










            answered Feb 18 '15 at 12:09









            thettalosthettalos

            5




            5







            • 3





              This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

              – Michael Mrozek
              Feb 18 '15 at 14:48












            • 3





              This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

              – Michael Mrozek
              Feb 18 '15 at 14:48







            3




            3





            This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

            – Michael Mrozek
            Feb 18 '15 at 14:48





            This doesn't work with the syntax the OP specified; they want -a 1 -b mitsos -c karamitsos

            – Michael Mrozek
            Feb 18 '15 at 14:48

















            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%2f129391%2fpassing-named-arguments-to-shell-scripts%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

            How to check contact read email or not when send email to Individual?

            Bahrain

            Postfix configuration issue with fips on centos 7; mailgun relay