単純な bash 関数を作成しようとしましたが、予期しないトークン `(' の近くで構文エラーが発生します。

単純な bash 関数を作成しようとしましたが、予期しないトークン `(' の近くで構文エラーが発生します。

現在次のようになっている .bash_profile を変更しようとしています:

alias kx="kubectx"
gcreds () {
gcloud container clusters get-credentials $1 --zone $2;
}

しかし、:wq と source .bash_profile (Mac OS X ターミナルで) を実行しようとすると、次のエラー メッセージが表示されます。

bash: .bash_profile: line 14: syntax error near unexpected token `('
-bash: .bash_profile: line 14: `gcreds (){'

同僚も同様にテストし(itermターミナルで)、エラーなしで関数を実行することができました。

何が間違っているのか、何かアイデアはありますか?

答え1

仮説:あなたの(同僚の)殻の中にgcredsエイリアス問題のある行が解析される前に定義されます。

エイリアスの展開は早い段階で行われ、純粋にテキストベースです(つまりgcreds いくつかに置き換えられる、そこにはロジックがありません。関数の定義は無効になります。おそらく、()が最初の単語の後にないためです。たとえば、gcredsが に置き換えられた場合はgcreds --something、次のようになります。

gcreds --something () { …

これは関数の構文的に有効な定義ではありません。しかし、gcreds他のものに置き換えられる可能性があります。

something-else-than-gcreds whatever and more () { …

()代替品が何であるかは問題ではありません。今、間違った場所にあるという事実が重要なのです。

type gcredsBash では、実際に何が起きているかを確認するために実行できますgcreds。また、試してみてtype -a gcreds(そしてhelp type何が起こっているかを知るために-a) ください。

を使わずに、別の方法で関数を定義することもできます()

function gcreds { …

この構文は持ち運び不可~/.bash_profile. Bash 固有のファイル内で使用するつもりだと理解しているので、問題ありません。

最初の単語は ですfunction。これはエイリアス化されておらず、キーワードとして解釈されていると想定しています ( を確認してくださいtype function)。その場合、定義が解析されるときにエイリアスは展開されず、定義を壊すことはできません。このようにして、エイリアスが既に存在する場合でも、gcredsという名前の関数を定義できます。gcredsgcreds

gcredsエイリアスと関数を定義できたとしますgcreds。 を実行してgcreds foo barエイリアスがgcredsに置き換えられるとgcreds …、エイリアスが最初に展開され、関数は後で実行されます。 しかし、エイリアスがgcredsに置き換えられるとsomething-else-than-gcreds …、エイリアスが最初に展開され、関数は重要ではなくなります (関数名がsomething-else-than-gcredsある場合は重要です)。

おそらくエイリアスは必要ないそして同じ名前の関数。いずれか 1 つを選択します。両方必要な場合は、最初に関数を定義し、後でエイリアスを定義するか、function上記のようにキーワードを使用します。

関連情報