パラメータとともにコマンドをスクリプトに渡す

パラメータとともにコマンドをスクリプトに渡す

私は文章を書こうとしています。シェルスクリプト入力として受信パラメータ付きコマンドそして実行してください。

cronたとえば、次のように使用したいと思います。

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

詳細はmy_wrapper.sh重要ではありませんが、スクリプトでzshあり、それを受け取って呼び出したいですcommand arg1 arg2 arg3 ...。パラメータには、一重引用符、二重引用符などを含めることができます。

パラメータを含むコマンドをスクリプトに渡して受け取る正しい方法は何ですか?

修正する:

zshを使用したコマンドラインでは、@Gillesの最初のソリューションはうまく機能します。

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

その後、> my_wrapper.sh date "%Y-%b-%d" コマンドラインから呼び出すとアクションが実行されます。

ただし、次のように使用しようとすると、次のようになりますcron

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

これはうまくいきません。

最終更新(トラブルシューティング):

Gilesの答えは次のとおりです。crontab必要逃げるどんな%印でも。上記を次のように変更します。

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

効率的。わかりました、わかりました。

答え1

2つのオプションがあります。実行するパラメータの一部を含むプログラムを渡したり、シェルスクリプトを渡したりできます。どちらの概念も「コマンド」と呼ぶことができます。

一部のパラメータを使用するプログラム文字列リスト形式を取ります。ここで最初のものは、実行可能ファイルへのパス(または環境変数が表すディレクトリのリストにあるスラッシュのない名前PATH)です。これの利点は、ユーザーが引用を心配することなくコマンドに引数を渡すことができることです。sh -c …必要に応じてシェルを明示的に呼び出すことができます。このオプションを選択すると、各文字列(プログラムとその引数)が別々の引数としてスクリプトに渡されます。これは通常スクリプトの最後のパラメータです(より多くのパラメータを渡すには、特殊文字列をプログラム終了パラメータの表示として指定する必要があります。以下を実行しない限りプログラムに渡すことはできません)。構文はより複雑です)

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

スクリプトから:

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

シェルスクリプトsh実行のためにプログラムに渡される文字列です。これにより、ユーザーはシェルを明示的に呼び出すことなくシェルフラグメントを作成でき、単一の文字列であるため、プログラムに対する単一の引数であるため、解析が簡単になります。shスクリプトからは呼び出すことができますが、evalzshでは実行しないでください。これは、sh構文とは少し異なるzsh構文を書く必要がないためです。

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

スクリプトから:

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

答え2

これを処理する最善の方法は、実際のコマンド引数を文字列の代わりに引数としてラッパーに渡すことです。ラッパーを次のように呼び出すことができます。

my_wrapper "task_name" command arg1 arg2 arg3

my_wrapper以下が含まれます:

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

答え3

ダッシュオプションにも同様の問題があると思います。検索でこの問題が見つかったので、役に立つコンテンツを共有する必要があると思いました。私は次のcrontabを使用しています:

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

Bashスクリプトでは、これを使用して-fオプションを取得します。

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

だから何らかの理由でcronを介してこれを実行したときにオプションが実行されないことがわかりました。さて、cronjobに/ bin / bashを追加すると、この問題は解決されます。新しいクローンタブは次のとおりです。

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

関連情報