引数を拡張せずにBashコマンドを含む文字列を分割する方法は?

引数を拡張せずにBashコマンドを含む文字列を分割する方法は?

シェルのコマンドラインを含む文字列があります。この文字列に特定のパラメータがある場合は、それらを削除して有効なシェルコマンドを保持しながら結果を印刷する必要があります。どうすればいいですか?

私は2つの異なるアプローチを試しました。

ただし、両方のソリューションはパラメータ置換を実行します。つまり、コマンドがある場合、パラメーターはコマンドdocker run --name $boxid$boxidパッチされたときの値に置き換えられます。パラメータを拡張しないでください。

より完全な例を提供するには、次のコマンド文字列を検討してください。

docker run -v /foo:/foo:ro --name "$boxid" container bash -c "some shell string"

そして、Bashが同じ方法で解析できるように、他のすべてのパラメータを維持しながら、次の3つの結果がすべて許可されるように、どこにでも存在する可能性のあるパラメータを-v /foo…削除する必要があります。docker run

docker run --name "$boxid" container bash -c "some shell string"
docker run --name "$boxid" container bash -c some\ shell\ string
"docker" "run" "--name" "$boxid" "container" "bash" '-c' "some shell string"

これは真剣に間違った要求/XY質問のように聞こえるので、いくつかの背景知識を提供します。

launchコマンド()を実行するシェル関数()を含む大規模ソフトウェア(Nextflow)の一部であるBashスクリプトがありますdocker run …。コマンドには特定の状況でエラーが発生するため、削除する必要があるパラメーターを含めることができます。1

私はスクリプト自体を制御することはできませんが、ソフトウェアを使用すると、関数が呼び出されるlaunch前(しかし関数が定義された後)、ユーザーは任意のBashコードをスクリプトに挿入できます。だから私の考えは、基本的にlaunch関数を動的にオーバーライドする次のコードスニペットを挿入することです。

eval "$(declare -f launch | sed '/docker run/s/OFFENDING ARGUMENT//')"

これはうまくいきます。しかし、残念ながら、これは将来的には利用できません。スクリプトを少し変更すると、単純なテキストの置き換えが中断される可能性があります。パッチをより強力にする必要があります。また、Bashだけがインストールされた状態でベアメタルで実行されることもあるため、他のプログラミング言語に変換することはできません。


1これはソフトウェアのバグではありません。私のユースケースはソフトウェアの仕様から少し外れました。

ベストアンサー1

おすすめ記事