RosettaCodeページで次の種類のシバンを見つけました。
--() { :; }; exec db2 -txf "$0"
Db2で動作し、Postgresでも同様です。ただ、全体がわかりません。
二重ダッシュがSQLのコメントであることは知っています。その後、ファイル自体をファイルとして渡すいくつかのパラメーターを指定してDb2実行可能ファイルを呼び出します。しかし、括弧、中かっこ、コロンとセミコロン、そして実際のシバン#をどのように置き換えることができるのでしょうか。 ?
関連: どのシェルインタープリターがシバンなしでスクリプトを実行しますか?
二重ダッシュが#!
ではないという理由だけで、スクリプトにはShebang/hashbang/#!
行がありません。
ただし、スクリプトはシェルによって実行され(上記のリンクされた質問と回答を参照)、そのシェルで、-
が関数名の有効な文字である場合、行は--
と呼ばれるシェル関数を宣言します(これは:
、 何もしない )を実行し、呼び出されることはありません。
より一般的な複数行表記の関数(奇妙な名前が実際には関数であるという事実を覆い隠すため、見た目をより明確にするため):
-- () {
:
}
関数定義の唯一の目的は、シェルスクリプトで有効な行を作成すると同時に、有効なSQLコマンド(コメント)を作成することです。この種のコードは polyglot と呼ばれます。
偽のシェル関数を宣言した後、スクリプトは、シェルスクリプトインタープリターによって実行されると、exec
を使用して、現在のシェルをdb2 -txf "$0"
を実行した結果のプロセスで置き換えます。これは、db2 -txf
のパス名での使用と同じです。コマンドラインからのスクリプト。
このトリックは、dash
またはその他のash
ベースのシェル、yash
、Bourneシェル、ksh88
またはksh93
がこれらのシェルと同じように/bin/sh
として使用されているシステムではおそらく確実に機能しません名前にダッシュが含まれる関数は受け入れないでください。
関連もあります:
以下も機能すると思います(実際にはテストされていません)。
--() { exec db2 -txf "$0"; }; --
@Kusalanandaがすでに述べたように、そのトリックは壊れており、すべてのシェルで機能するわけではありません。
これを移植性の高い方法で実行する場合の私の見解を次に示します。
--/.. 2>/dev/null; exec db2 -txf "$0"
--
という名前のファイル/ディレクトリが現在のディレクトリに存在する場合でも、最初のコマンドは失敗し、エラーは2>/dev/null
によってシャットダウンされます。その後、シェルは2番目のコマンドexec
を続行します。