Passing a command with arguments to a script

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











up vote
6
down vote

favorite
1












I am trying to write a shell script that receives as an input a command with arguments and runs it.



As an example, I am hoping to use this in cron as follows:



0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


The details of what my_wrapper.sh does don't matter, but it is a zsh script and I want it to receive command arg1 arg2 arg3 ... and invoke it. Note that the arguments may contain single quotes, double quotes, etc.



What is the proper way of passing and receiving commands with arguments to scripts?



Update:



On the command line in zsh, @Gilles' first solution works great:



#!/bin/zsh
task_name=$1
shift
"$@" > /path/to/logging_directory/$task_name


and then invoking > my_wrapper.sh date "%Y-%b-%d" from the command line does the job.



However, when I try to use it as follows in cron:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


It doesn't work.



Final update (problem solved):



As explained in Gilles' answer, crontab requires escaping any % signs. After changing the above to:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


it worked. All set.










share|improve this question



















  • 1




    Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
    – cremefraiche
    Dec 28 '14 at 5:41










  • Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
    – Amelio Vazquez-Reina
    Dec 28 '14 at 19:29















up vote
6
down vote

favorite
1












I am trying to write a shell script that receives as an input a command with arguments and runs it.



As an example, I am hoping to use this in cron as follows:



0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


The details of what my_wrapper.sh does don't matter, but it is a zsh script and I want it to receive command arg1 arg2 arg3 ... and invoke it. Note that the arguments may contain single quotes, double quotes, etc.



What is the proper way of passing and receiving commands with arguments to scripts?



Update:



On the command line in zsh, @Gilles' first solution works great:



#!/bin/zsh
task_name=$1
shift
"$@" > /path/to/logging_directory/$task_name


and then invoking > my_wrapper.sh date "%Y-%b-%d" from the command line does the job.



However, when I try to use it as follows in cron:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


It doesn't work.



Final update (problem solved):



As explained in Gilles' answer, crontab requires escaping any % signs. After changing the above to:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


it worked. All set.










share|improve this question



















  • 1




    Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
    – cremefraiche
    Dec 28 '14 at 5:41










  • Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
    – Amelio Vazquez-Reina
    Dec 28 '14 at 19:29













up vote
6
down vote

favorite
1









up vote
6
down vote

favorite
1






1





I am trying to write a shell script that receives as an input a command with arguments and runs it.



As an example, I am hoping to use this in cron as follows:



0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


The details of what my_wrapper.sh does don't matter, but it is a zsh script and I want it to receive command arg1 arg2 arg3 ... and invoke it. Note that the arguments may contain single quotes, double quotes, etc.



What is the proper way of passing and receiving commands with arguments to scripts?



Update:



On the command line in zsh, @Gilles' first solution works great:



#!/bin/zsh
task_name=$1
shift
"$@" > /path/to/logging_directory/$task_name


and then invoking > my_wrapper.sh date "%Y-%b-%d" from the command line does the job.



However, when I try to use it as follows in cron:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


It doesn't work.



Final update (problem solved):



As explained in Gilles' answer, crontab requires escaping any % signs. After changing the above to:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


it worked. All set.










share|improve this question















I am trying to write a shell script that receives as an input a command with arguments and runs it.



As an example, I am hoping to use this in cron as follows:



0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


The details of what my_wrapper.sh does don't matter, but it is a zsh script and I want it to receive command arg1 arg2 arg3 ... and invoke it. Note that the arguments may contain single quotes, double quotes, etc.



What is the proper way of passing and receiving commands with arguments to scripts?



Update:



On the command line in zsh, @Gilles' first solution works great:



#!/bin/zsh
task_name=$1
shift
"$@" > /path/to/logging_directory/$task_name


and then invoking > my_wrapper.sh date "%Y-%b-%d" from the command line does the job.



However, when I try to use it as follows in cron:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


It doesn't work.



Final update (problem solved):



As explained in Gilles' answer, crontab requires escaping any % signs. After changing the above to:



CRON_WRAPPER="/long/path/to/my_wrapper.sh"
0 11 * * * $CRON_WRAPPER "current_date.log" date "+%Y-%b-%d"


it worked. All set.







shell zsh






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 29 '14 at 1:35

























asked Dec 28 '14 at 5:24









Amelio Vazquez-Reina

11.9k51124228




11.9k51124228







  • 1




    Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
    – cremefraiche
    Dec 28 '14 at 5:41










  • Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
    – Amelio Vazquez-Reina
    Dec 28 '14 at 19:29













  • 1




    Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
    – cremefraiche
    Dec 28 '14 at 5:41










  • Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
    – Amelio Vazquez-Reina
    Dec 28 '14 at 19:29








1




1




Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
– cremefraiche
Dec 28 '14 at 5:41




Is there a reason you are trying to pass the command as an argument instead of invoking the command in the script and passing the arguments to it when you run the script?
– cremefraiche
Dec 28 '14 at 5:41












Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
– Amelio Vazquez-Reina
Dec 28 '14 at 19:29





Thanks @cremefraiche. Not sure I follow, but just in case: my_wrapper.sh is meant to be a generic wrapper for cron jobs. For now it only logs the output on a predefined folder (the folder's name is given by the current date, and the logging filename is task_name followed by the current timestamp). I also hope to email myself a note saying that the task task_name finished correctly. Are you suggesting to not use a generic wrapper to do all this?
– Amelio Vazquez-Reina
Dec 28 '14 at 19:29











3 Answers
3






active

oldest

votes

















up vote
3
down vote



accepted










You have two choices: you can pass a program to execute with some arguments, or you can pass a shell script. Both concepts can be called “a command”.



A program with some arguments takes the form of a list of strings, the first of which is the path to an executable file (or a name not containing any slash, to be looked up in the list of directories indicated by the PATH environment variable). This has the advantage that the user can pass arguments to that command without worrying about quoting; the user can invoke a shell explicitly (sh -c … if they want). If you choose this, pass each string (the program and its argument) as a separate argument to your script. These would typically be the last arguments to your script (if you want to be able to pass more arguments, you need to designate a special string as an end-of-program-arguments marker, which you then can't pass to the program unless you make the syntax even more complicated).



0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...


and in your script:



#!/bin/zsh
task_name=$1
shift
"$@"


A shell script is a string that you pass to the sh program for execution. This allows the user to write any shell snippet without having to explicitly invoke a shell, and is simpler to parse since it's a single string, hence a single argument to your program. In an sh script, you could call eval, but don't do this in zsh, because users wouldn't expect to have to write zsh syntax which is a little different from sh syntax.



0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


and in your script:



#!/bin/zsh
task_name=$1
sh -c "$2"





share|improve this answer




















  • Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:37







  • 2




    @user815423426 You need to quote the percent signs for cron.
    – Gilles
    Dec 29 '14 at 0:49










  • Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:51







  • 2




    @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
    – Gilles
    Dec 29 '14 at 1:03










  • I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
    – Amelio Vazquez-Reina
    Dec 29 '14 at 1:33

















up vote
4
down vote













The best way to handle this is to pass the actual command args to your wrapper as args instead of as a string. You can call your wrapper like this:



my_wrapper "task_name" command arg1 arg2 arg3


my_wrapper would contain the following:



task_name=$1
shift # remove the task_name from the command+args
"$@" # execute the command with args, while preserving spaces etc





share|improve this answer




















  • Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
    – Amelio Vazquez-Reina
    Dec 28 '14 at 21:07







  • 1




    I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
    – bbaja42
    Dec 29 '14 at 0:40

















up vote
1
down vote













I was having I think a similar issue with dash options and I came across this question here in my searching so I wanted to share what helped me. I was using the following crontab:



0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt


And inside the bash script I was using this to get the -f option:



while getopts ":f" opt; do
case $opt in
f)
force_full=1
;;
?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done


So I noticed that the option wasn't being honored when I ran this through cron for some reason. Well, adding /bin/bash to the cronjob fixed it right up. The new crontab is:



0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt





share|improve this answer








New contributor




Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

















    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',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    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%2f176226%2fpassing-a-command-with-arguments-to-a-script%23new-answer', 'question_page');

    );

    Post as a guest






























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    You have two choices: you can pass a program to execute with some arguments, or you can pass a shell script. Both concepts can be called “a command”.



    A program with some arguments takes the form of a list of strings, the first of which is the path to an executable file (or a name not containing any slash, to be looked up in the list of directories indicated by the PATH environment variable). This has the advantage that the user can pass arguments to that command without worrying about quoting; the user can invoke a shell explicitly (sh -c … if they want). If you choose this, pass each string (the program and its argument) as a separate argument to your script. These would typically be the last arguments to your script (if you want to be able to pass more arguments, you need to designate a special string as an end-of-program-arguments marker, which you then can't pass to the program unless you make the syntax even more complicated).



    0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...


    and in your script:



    #!/bin/zsh
    task_name=$1
    shift
    "$@"


    A shell script is a string that you pass to the sh program for execution. This allows the user to write any shell snippet without having to explicitly invoke a shell, and is simpler to parse since it's a single string, hence a single argument to your program. In an sh script, you could call eval, but don't do this in zsh, because users wouldn't expect to have to write zsh syntax which is a little different from sh syntax.



    0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


    and in your script:



    #!/bin/zsh
    task_name=$1
    sh -c "$2"





    share|improve this answer




















    • Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:37







    • 2




      @user815423426 You need to quote the percent signs for cron.
      – Gilles
      Dec 29 '14 at 0:49










    • Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:51







    • 2




      @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
      – Gilles
      Dec 29 '14 at 1:03










    • I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
      – Amelio Vazquez-Reina
      Dec 29 '14 at 1:33














    up vote
    3
    down vote



    accepted










    You have two choices: you can pass a program to execute with some arguments, or you can pass a shell script. Both concepts can be called “a command”.



    A program with some arguments takes the form of a list of strings, the first of which is the path to an executable file (or a name not containing any slash, to be looked up in the list of directories indicated by the PATH environment variable). This has the advantage that the user can pass arguments to that command without worrying about quoting; the user can invoke a shell explicitly (sh -c … if they want). If you choose this, pass each string (the program and its argument) as a separate argument to your script. These would typically be the last arguments to your script (if you want to be able to pass more arguments, you need to designate a special string as an end-of-program-arguments marker, which you then can't pass to the program unless you make the syntax even more complicated).



    0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...


    and in your script:



    #!/bin/zsh
    task_name=$1
    shift
    "$@"


    A shell script is a string that you pass to the sh program for execution. This allows the user to write any shell snippet without having to explicitly invoke a shell, and is simpler to parse since it's a single string, hence a single argument to your program. In an sh script, you could call eval, but don't do this in zsh, because users wouldn't expect to have to write zsh syntax which is a little different from sh syntax.



    0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


    and in your script:



    #!/bin/zsh
    task_name=$1
    sh -c "$2"





    share|improve this answer




















    • Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:37







    • 2




      @user815423426 You need to quote the percent signs for cron.
      – Gilles
      Dec 29 '14 at 0:49










    • Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:51







    • 2




      @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
      – Gilles
      Dec 29 '14 at 1:03










    • I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
      – Amelio Vazquez-Reina
      Dec 29 '14 at 1:33












    up vote
    3
    down vote



    accepted







    up vote
    3
    down vote



    accepted






    You have two choices: you can pass a program to execute with some arguments, or you can pass a shell script. Both concepts can be called “a command”.



    A program with some arguments takes the form of a list of strings, the first of which is the path to an executable file (or a name not containing any slash, to be looked up in the list of directories indicated by the PATH environment variable). This has the advantage that the user can pass arguments to that command without worrying about quoting; the user can invoke a shell explicitly (sh -c … if they want). If you choose this, pass each string (the program and its argument) as a separate argument to your script. These would typically be the last arguments to your script (if you want to be able to pass more arguments, you need to designate a special string as an end-of-program-arguments marker, which you then can't pass to the program unless you make the syntax even more complicated).



    0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...


    and in your script:



    #!/bin/zsh
    task_name=$1
    shift
    "$@"


    A shell script is a string that you pass to the sh program for execution. This allows the user to write any shell snippet without having to explicitly invoke a shell, and is simpler to parse since it's a single string, hence a single argument to your program. In an sh script, you could call eval, but don't do this in zsh, because users wouldn't expect to have to write zsh syntax which is a little different from sh syntax.



    0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


    and in your script:



    #!/bin/zsh
    task_name=$1
    sh -c "$2"





    share|improve this answer












    You have two choices: you can pass a program to execute with some arguments, or you can pass a shell script. Both concepts can be called “a command”.



    A program with some arguments takes the form of a list of strings, the first of which is the path to an executable file (or a name not containing any slash, to be looked up in the list of directories indicated by the PATH environment variable). This has the advantage that the user can pass arguments to that command without worrying about quoting; the user can invoke a shell explicitly (sh -c … if they want). If you choose this, pass each string (the program and its argument) as a separate argument to your script. These would typically be the last arguments to your script (if you want to be able to pass more arguments, you need to designate a special string as an end-of-program-arguments marker, which you then can't pass to the program unless you make the syntax even more complicated).



    0 11 * * * my_wrapper.sh "task_name" command arg1 arg2 arg3 ...


    and in your script:



    #!/bin/zsh
    task_name=$1
    shift
    "$@"


    A shell script is a string that you pass to the sh program for execution. This allows the user to write any shell snippet without having to explicitly invoke a shell, and is simpler to parse since it's a single string, hence a single argument to your program. In an sh script, you could call eval, but don't do this in zsh, because users wouldn't expect to have to write zsh syntax which is a little different from sh syntax.



    0 11 * * * my_wrapper.sh "task_name" "command arg1 arg2 arg3 ..."


    and in your script:



    #!/bin/zsh
    task_name=$1
    sh -c "$2"






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 28 '14 at 23:29









    Gilles

    513k12010161547




    513k12010161547











    • Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:37







    • 2




      @user815423426 You need to quote the percent signs for cron.
      – Gilles
      Dec 29 '14 at 0:49










    • Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:51







    • 2




      @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
      – Gilles
      Dec 29 '14 at 1:03










    • I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
      – Amelio Vazquez-Reina
      Dec 29 '14 at 1:33
















    • Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:37







    • 2




      @user815423426 You need to quote the percent signs for cron.
      – Gilles
      Dec 29 '14 at 0:49










    • Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
      – Amelio Vazquez-Reina
      Dec 29 '14 at 0:51







    • 2




      @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
      – Gilles
      Dec 29 '14 at 1:03










    • I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
      – Amelio Vazquez-Reina
      Dec 29 '14 at 1:33















    Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:37





    Thanks @Gilles, your first solution works well, but does not seem to work well when using parameter expansion in cron. Really odd. I added an update to the OP to reflect this.
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:37





    2




    2




    @user815423426 You need to quote the percent signs for cron.
    – Gilles
    Dec 29 '14 at 0:49




    @user815423426 You need to quote the percent signs for cron.
    – Gilles
    Dec 29 '14 at 0:49












    Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:51





    Thanks. Apparently that isn't the problem (I quoted the argument in the update to the OP) I have the same problem after quoting the percent signs, or with e.g. python -c "2+2"
    – Amelio Vazquez-Reina
    Dec 29 '14 at 0:51





    2




    2




    @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
    – Gilles
    Dec 29 '14 at 1:03




    @user815423426 I don't see anything obviously wrong. Add set -x; : "$^@" at the top of the script to get a debugging trace and post the content of the email that cron sends you.
    – Gilles
    Dec 29 '14 at 1:03












    I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
    – Amelio Vazquez-Reina
    Dec 29 '14 at 1:33




    I just realized that the link asks to escape the percent sign. I was quoting things as date "+%Y-%b-%d" I should have read your link better. All set!
    – Amelio Vazquez-Reina
    Dec 29 '14 at 1:33












    up vote
    4
    down vote













    The best way to handle this is to pass the actual command args to your wrapper as args instead of as a string. You can call your wrapper like this:



    my_wrapper "task_name" command arg1 arg2 arg3


    my_wrapper would contain the following:



    task_name=$1
    shift # remove the task_name from the command+args
    "$@" # execute the command with args, while preserving spaces etc





    share|improve this answer




















    • Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
      – Amelio Vazquez-Reina
      Dec 28 '14 at 21:07







    • 1




      I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
      – bbaja42
      Dec 29 '14 at 0:40














    up vote
    4
    down vote













    The best way to handle this is to pass the actual command args to your wrapper as args instead of as a string. You can call your wrapper like this:



    my_wrapper "task_name" command arg1 arg2 arg3


    my_wrapper would contain the following:



    task_name=$1
    shift # remove the task_name from the command+args
    "$@" # execute the command with args, while preserving spaces etc





    share|improve this answer




















    • Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
      – Amelio Vazquez-Reina
      Dec 28 '14 at 21:07







    • 1




      I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
      – bbaja42
      Dec 29 '14 at 0:40












    up vote
    4
    down vote










    up vote
    4
    down vote









    The best way to handle this is to pass the actual command args to your wrapper as args instead of as a string. You can call your wrapper like this:



    my_wrapper "task_name" command arg1 arg2 arg3


    my_wrapper would contain the following:



    task_name=$1
    shift # remove the task_name from the command+args
    "$@" # execute the command with args, while preserving spaces etc





    share|improve this answer












    The best way to handle this is to pass the actual command args to your wrapper as args instead of as a string. You can call your wrapper like this:



    my_wrapper "task_name" command arg1 arg2 arg3


    my_wrapper would contain the following:



    task_name=$1
    shift # remove the task_name from the command+args
    "$@" # execute the command with args, while preserving spaces etc






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 28 '14 at 5:56









    jordanm

    29.3k27891




    29.3k27891











    • Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
      – Amelio Vazquez-Reina
      Dec 28 '14 at 21:07







    • 1




      I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
      – bbaja42
      Dec 29 '14 at 0:40
















    • Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
      – Amelio Vazquez-Reina
      Dec 28 '14 at 21:07







    • 1




      I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
      – bbaja42
      Dec 29 '14 at 0:40















    Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
    – Amelio Vazquez-Reina
    Dec 28 '14 at 21:07





    Thanks, if I try my_wrapper "get_date" date '+%d', it tries to invoke date +%d (it drops the single quotes), so the date command fails (I know this in part because I enabled set -x on the receiving script). Hmm... I wonder if this answer to this question: Running commands stored in shell variables can help.
    – Amelio Vazquez-Reina
    Dec 28 '14 at 21:07





    1




    1




    I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
    – bbaja42
    Dec 29 '14 at 0:40




    I'm afraid there is no nice way around the single quote problem. Bash will parse single quotes, which means those quotes will not exist in your wrapper script. You would need to escape the quotes in date +'%d'
    – bbaja42
    Dec 29 '14 at 0:40










    up vote
    1
    down vote













    I was having I think a similar issue with dash options and I came across this question here in my searching so I wanted to share what helped me. I was using the following crontab:



    0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt


    And inside the bash script I was using this to get the -f option:



    while getopts ":f" opt; do
    case $opt in
    f)
    force_full=1
    ;;
    ?)
    echo "Invalid option: -$OPTARG" >&2
    ;;
    esac
    done


    So I noticed that the option wasn't being honored when I ran this through cron for some reason. Well, adding /bin/bash to the cronjob fixed it right up. The new crontab is:



    0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt





    share|improve this answer








    New contributor




    Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.





















      up vote
      1
      down vote













      I was having I think a similar issue with dash options and I came across this question here in my searching so I wanted to share what helped me. I was using the following crontab:



      0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt


      And inside the bash script I was using this to get the -f option:



      while getopts ":f" opt; do
      case $opt in
      f)
      force_full=1
      ;;
      ?)
      echo "Invalid option: -$OPTARG" >&2
      ;;
      esac
      done


      So I noticed that the option wasn't being honored when I ran this through cron for some reason. Well, adding /bin/bash to the cronjob fixed it right up. The new crontab is:



      0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt





      share|improve this answer








      New contributor




      Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



















        up vote
        1
        down vote










        up vote
        1
        down vote









        I was having I think a similar issue with dash options and I came across this question here in my searching so I wanted to share what helped me. I was using the following crontab:



        0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt


        And inside the bash script I was using this to get the -f option:



        while getopts ":f" opt; do
        case $opt in
        f)
        force_full=1
        ;;
        ?)
        echo "Invalid option: -$OPTARG" >&2
        ;;
        esac
        done


        So I noticed that the option wasn't being honored when I ran this through cron for some reason. Well, adding /bin/bash to the cronjob fixed it right up. The new crontab is:



        0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt





        share|improve this answer








        New contributor




        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        I was having I think a similar issue with dash options and I came across this question here in my searching so I wanted to share what helped me. I was using the following crontab:



        0 23 * * * sudo -u myname /home/myname/bin/buildme.sh -f >> /home/myname/log.txt


        And inside the bash script I was using this to get the -f option:



        while getopts ":f" opt; do
        case $opt in
        f)
        force_full=1
        ;;
        ?)
        echo "Invalid option: -$OPTARG" >&2
        ;;
        esac
        done


        So I noticed that the option wasn't being honored when I ran this through cron for some reason. Well, adding /bin/bash to the cronjob fixed it right up. The new crontab is:



        0 23 * * * sudo -u myname /bin/bash /home/myname/bin/buildme.sh -f >> /home/myname/log.txt






        share|improve this answer








        New contributor




        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered yesterday









        Eradicatore

        1112




        1112




        New contributor




        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        Eradicatore is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f176226%2fpassing-a-command-with-arguments-to-a-script%23new-answer', 'question_page');

            );

            Post as a guest













































































            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