#!/bin/sh
execute_cmd()
{
$($@)
}
execute_cmd export MY_VAR=my_val
echo ${MY_VAR}
$()
サブシェルで実行されるため、$MY_VAR
スクリプトが実行されるシェルでは正しく設定されません。
私の質問は、エクスポートコマンドを関数に渡し、スクリプトが実行されている現在のシェルでどのように実行しますか?
答え1
何をしたいのか明確ではありません。$($@)
話すことはできませんが、あなたは何をしたいですか?
何$($@)
ですか:
- 関数のパラメータを取得します。これは文字列のリストです。
- スペースを含む各セクションをさらに分割します。
- 各分割を取得し、ワイルドカードパターンとして解釈します。パターンがファイルと一致する場合、この部分は一致するファイル名のリストに置き換えられます。
- 最初の部分を実行するコマンド名(関数、シェル組み込み、または実行可能ファイル)として使用し、他の部分を引数として渡します。
- コマンドの出力を取得し、スペースを含む場所ごとに分割します。
- 各分割を取得し、ワイルドカードパターンとして解釈します。パターンがファイルと一致する場合、この部分は一致するファイル名のリストに置き換えられます。
- 最初の部分を実行するコマンド名(関数、シェル組み込み、または実行可能ファイル)として使用し、他の部分を引数として渡します。
これが複雑に聞こえるなら、そうだからです。
execute_cmd export MY_VAR=my_val
あなたがそれを実装したいのであればexport MY_VAR=my_val
、なぜ面倒になりますかexecute_cmd
?
これを合理的に説明する方法は2つあります。
パラメータとともにコマンドを関数に渡そうとします。引数を持つコマンドは文字列のリストで、最初のものは関数名、シェル組み込み、または実行可能ファイルです。指定されたパラメータを使用してこのコマンドを呼び出す構文は次のとおりです
"$@"
。execute_cmd () { "$@" } execute_cmd export MY_VAR=my_val
二重引用符は、上記の分割とワイルドカードの拡張ステップを防ぎます。変数の置換には常に二重引用符を使用してください。。
export
また、キーワード/組み込み機能の二重特性に注意してください。キーワードの存在により、シェルは構文export MY_VAR=$(seq 10)
解析と同様に出力を割り当てることができますが、コマンドはここにないため、シェルはそれを割り当てとして解析しません。したがって、通常のコマンドの引数として解析され、分割されます。 +glob は で実行されるので、以下が必要です。seq 10
$MY_VAR
MY_VAR=$(seq 10)
export
MY_VAR=$(seq 10)
execute_cmd export MY_VAR=$(seq 10)
export
execute_cmd
MY_VAR=$(seq 10)
$(seq 10)
execute_cmd export MY_VAR="$(seq 10)"
シェルピースを実行したいです。シェルフラグメントは、単一の引数として渡される単一の文字列です。シェルコードを含む文字列を実行するには、
eval
組み込み関数を使用します。execute_cmd () { eval "$1" } execute_cmd 'export MY_VAR=my_val'
デフォルトでは1と仮定されますIFS
。これを知っていれば、この段落を読む必要はありません。