Bash機能をランナー機能でラップする

Bash機能をランナー機能でラップする

私のものスクリプトには、実行できるmysqldump blabla > dump.sql多くのコンテンツが含まれています。mysq balbla < dump.sql試運転モデル。

実際には、ポイントはrun私が要求するすべてを実行する関数を作成することです。

  run echo 'hello world'
  run mysqldump blabla > dump.sql
  run mysql blabla < dump.sql
  run ssh blabla
  # etc


run() {
    if [[ "$(printenv DRY_RUN)" = "yes" ]]
    then
        echo "${@}"
    else
        ${@}
    fi
}

しかし、これはうまくいきません。

run "mysqldump -uuser -ppass dbase > dump.sql"

次のエラーが発生します。

mysqldump: テーブルが見つかりません: ">"

ベストアンサー1

"${@}"代わりに${@}(withのように)を使用する必要がありますecho "${@}"が、これが問題の原因ではありません。

その理由は、パラメータの置換前、コマンドライン解析の初期にリダイレクトが発生するためです。したがって、変数を>コマンドラインに入れた後、シェルはもはやその変数を見つけません>

回答を投稿した後、重要な点が見つかりました。このように電話してください。

run mysqldump blabla > dump.sql

関数は合計を見ることがrunできません。の出力もファイルにリダイレクトされるため、単一の環境変数を使用してすべてのリダイレクトを変更することはできません。したがって、次のようなものを使用する必要があります。下記をご覧ください。>dump.sqlecho "${@}"run --redirect dump.sql mysqldump blabla

2つの可能性があります。

  1. それに固執し"$@"て使用してくださいeval。もちろん、これは引用の悪夢につながる可能性があります。引用符を削除する前に、>シェルがコマンドライン>でデフォルトの内容を表示できるようにする以外のすべての項目を引用符で囲む必要があります。

  2. リダイレクトを個別に処理します。

    run --redirect dump.sql mysqldump blabla
    
    run() {
        if [ "$1" == '--redirect' ]; then
            shift
            redirect_target="$1"
            shift
        else
            redirect_target='/dev/stdout' # works at least with Linux
        fi
    
        if [[ "$(printenv DRY_RUN)" = "yes" ]]
        then
            echo "${@}"
        else
            "${@}" > "$redirect_target"
        fi
    }
    

    redirect_target='/dev/stdout'if [ "$1" == '--redirect' ]の四半期に配置すると、これを回避できます。elseif [[ "$(printenv DRY_RUN)" = "yes" ]]

        if [[ "$(printenv DRY_RUN)" = "yes" ]]
        then
            if [ "$1" == '--redirect' ]; then
                # do not output "--redirect file"
                shift
                shift
            fi
            echo "${@}"
        else
            if [ "$1" == '--redirect' ]; then
                shift
                redirect_target="$1"
                shift
                "${@}" > "$redirect_target"
            else
                "${@}"
            fi
        fi
    

おすすめ記事