スクリプトの配布:シバンには/ bin / gawkまたは/ usr / bin / gawkを使用する必要がありますか?


12

gawkは通常/ binまたは/ usr / binにありますか?私は一緒に行きます#!/usr/bin/env gawkが、引数は使用できません。現在、私はを使用してい#!/bin/gawk -fます。スクリプトは非常に長く、多数の単一引用符が含まれており、stdinで動作します。

GNU Awkマニュアルのセクション1.1.4実行可能awkプログラムでは、例では#!/ bin / awkを使用していますが、次のように続けています。

多くのシステムでawkは、/usr/binではなくにあることに注意してください/bin。買い手責任負担。

ほとんどの人は何をしますか?私は、sedは/ binで標準化されていると思われるのに対し、perlは/ usr / binで標準化されていると読みました(sedリンクと同じページですが、この投稿に3つ目のリンクを作成することはできません)。awk / gawkはどうですか?どちらがより一般的または人気があるか知っていますか?


なぜ使うの-f/bin/gawk十分ではありませんか?また、これは関連があるかもしれません。
terdon

回答:


7

シバンはそんなに柔軟であるように意図されていませんでした2番目のパラメーターが機能する場合もありますが、FreeBSDはその1つだと思います。

OSに付属するgawkとほとんどのユーティリティはに含まれていると予想されます/usr/bin/

UNIXの昔は、/usr/ローカルディスクのスペースとワークステーションあたりのコストを節約するために、NFSまたはいくつかの安価なメディアを介してマウントするのが一般的でした。シングルユーザーモードで/bin/起動するために必要なすべてのものを持っているはずでした。以来信頼性の高いメディア上に取り付けられていなかった、それは一般的な管理とトラブルシューティングのためのやさしい十分にするために十分なユーティリティが含まれています。/usr//bin/

これは最初はLinuxで継承されましたが、ディスク領域はもはや問題ではなく、ほとんどの場合/usr/ルートファイルシステムにあるため、現在の傾向はすべてを/usr/bin(少なくともLinuxの世界では)移動することです。したがって、ディストリビューションによってインストールされるほとんどのユーティリティは、そこにあると予想されます。最も基本的なユーティリティ、のようなcprmlsなど(まあ、まだ)。

シバン選択について。従来、これは管理者またはユーザーが環境に応じて編集する必要があるものです。開発者が知っているすべての人にとって、他の人のシステムでは、インタプリタはファイルシステム内のどこにでも配置できます(たとえば/usr/local/bin/opt/gawk-4.0.1/bin)。適切にパッケージ化されたスクリプト(rpm、debなど)には、ディストリビューションパッケージへの依存関係(つまり、インタープリターが既知の場所を持っている)、またはインストール中に適切なハッシュバンをセットアップする構成スクリプトが付属しています。


14

コマンドに引数を渡す必要がない場合#!/usr/bin/env gawkは、その方法ですが、多くのカーネル(Linuxを含む)は、shebangプログラムに単一の引数しか受け入れません。

それ以外の場合は、シェルラッパーとawkスクリプトの両方であるポリグロットプログラムを作成できます。これがawkの1つです。

#!/bin/sh
true + /; exec gawk -f "$0"; exit; / {}
# awk script starts here

シェルの解析:

  • true + /;true2つの無効な引数+とを使用したコマンド(何も実行しません)/
  • への呼び出しgawk。これは、改行を含まず、スラッシュが書き込まれるシェルスニペットである可能性があります\/(シェルは引用符の内側を除いて気にしません)。
    呼び出しはexec、サブプロセスとしてgawkを実行する代わりに、シェルをgawkに置き換えるために使用します。
  • exit;— gawkが見つからなかった場合は、シェルを終了します。シェルが実行を開始する前に行全体を解析しようとした場合に有効なシェル構文であることを除いて、それ以降はすべて無視されます。

awk解析:

  • スラッシュの間のビットは正規表現です。
  • true + /REGEX/- 一つの条件。true未定義の変数であるため、その数値は0であり、重要ではありません。
  • {} —上記の条件が満たされている場合は、何もしません。

5

Gillesの提案する解決策は確かに非常に優れたアプローチです(最終的に彼の投稿で投票するという評判があります:))。

いずれにせよ、私がexecコマンドを理解している限りexit、シェルプロセスがに置き換えられているため、コマンドの直後は不要になり、実際には到達できなくなりますawk

さらに、awkスクリプトがその呼び出しパラメーターにアクセスできるようにするために、提案されたソリューションにいくつかの変更を加えることをお勧めします。

#!/bin/sh
true + /; exec -a "$0" gawk -f "$0" -- "$@"; / {}
# awk script starts here

-a "$0"それ以外の場合は常に取得します、スクリプトはその呼び出し名へのアクセスを持つことができますawkまたはgawkアクセスしたときにARGV[0]変数を。同様に、"$@"はスクリプトがARGV[1...N]配列内の残りのパラメーターにアクセスできるようにし、その--前のスクリプト-<something>はgawk が引数を解釈することなく引数を受け取ることができるようにします。

覚えて/考慮すべきことの1つは、スクリプトプログラムのブロックのexit(0);最後にステートメントを追加することです。そうしないと、入力ファイルとしてスクリプトに渡されるすべてのパラメーターが脅かされます。(行から削除したステートメントでは何もする必要がないことに注意してください。これは、この提案された出口がawkコードにある間、到達できないシェルステートメントでした)。BEGIN { ... }awkawkexittrue + ...


exit(0)非常に便利でした!また、macosユーザーの場合は、次の要点を参照してください。優れたポータブルawkシバンを見つけるのは簡単ではありません。
Seamus
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.