GNU awkの使用

GNU awkの使用

Bashには$0スクリプト名がありますが、awkは次の内容でmyscript.awkというスクリプトを生成します。

#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }

実行すると、「awk」のみが印刷されます。また、i> 0のARGV [i]は、コマンドラインのスクリプト引数にのみ使用されます。それでは、スクリプト名(この場合は「myscript.awk」)を印刷するにはどうすればよいですか?

答え1

CygwinのbashでGNU awk 4.1.3を使用する:

$ cat tst.sh
#!/bin/awk -f
BEGIN { print "Executing:", ENVIRON["_"] }

$ ./tst.sh
Executing: ./tst.sh

携帯性がどれほど良いのか全く知らなかった。しかし、いつものように、awkスクリプトを実行するためにシェルスクリプトでshebangを使用するわけではありません。なぜなら、これは可能な機能を奪うだけだからです。簡単に次のようにしてください。

$ cat tst2.sh
awk -v cmd="$0" '
BEGIN { print "Executing:", cmd }
' "$@"

$ ./tst2.sh
Executing: ./tst2.sh

最後は、すべてのプラットフォームのすべてのシェルで最新のawkで動作します。

答え2

awkからコマンド名を取得する直接的な方法がわかりません。しかし、サブシェルを通して見つけることができます。

愚かな

GNU awkとpsコマンドを使用すると、プロセスIDを使用してPROCINFO["PID"]回避策としてコマンド名を取得できます。たとえば、

cmdname.awk

#!/usr/bin/gawk -f

BEGIN {
  ("ps -p " PROCINFO["pid"] " -o comm=") | getline CMDNAME
  print CMDNAME
}

モックアンドノック

同じアプローチを使用できますが、awk特別なシェル変数(親のPID)からPIDを派生させることができます。$PPID

cmdname.awk

#!/usr/bin/mawk -f

BEGIN { 
  ("ps -p $PPID -o comm=") | getline CMDNAME
  print CMDNAME
}

テスト

次のようにスクリプトを実行します。

./cmdname.awk

どちらの場合も出力:

cmdname.awk

答え3

不可能だと思います。gawk 文書:

ARGV[0]最後に(セクション7.5の組み込み変数を参照)の値は、オペレーティングシステムによって異なります。一部のシステムはそれをawk置き、一部のシステムはawkのフルパス名(たとえば/bin/awk)を入れ、一部のシステムはスクリプト名( "advice")を入れます。ARGV[0]スクリプト名を提供するために値に依存しないでください。

コメントで指摘したように、試してみることができるlinux汚れたハッキン​​グがあります。スティーブン・チャジェラスawk実装が NUL バイトをサポートしている場合は可能です。

#!/usr/bin/awk -f

BEGIN { getline t < "/proc/self/cmdline"; split(t, a, "\0"); print a[3]; }

答え4

GNU awkの使用

調査するGNU awkユーザーガイド - 7.5.2情報伝達のための組み込み変数私は偶然次のことを見つけました:

番組情報#

この配列の要素は、実行中のawkプログラムに関する情報へのアクセスを提供します。次の要素(アルファベット順に記載)の使用が保証されています。

PROCINFO["pid"]

現在のプロセスのプロセスID。

これは、実行時にプログラムのPIDを知ることができることを意味します。次に、この指定されたPIDを使用してsystem()プロセスを見つける必要があります。

#!/usr/bin/gawk -f
BEGIN{ pid=PROCINFO["pid"]
       system("ps -ef | awk '$2==" pid " {print $NF}'")
}

を使用すると、ps -ef2番目の列にPIDが表示されます。実行が完了し、追加のawk -f <script>パラメータがないと仮定すると、行の最後のフィールドに必要な情報が含まれていると想定できます。

いくつかのパラメータがある場合は、行を別々に解析する必要があります。あるいは、より良い方法は、いくつかのオプションを使用してps興味のある列だけを印刷することです。

テスト

$ awk -f a.awk 
a.awk
$ cp a.awk hello.awk
$ awk -f hello.awk 
hello.awk

また、GNU awkユーザーガイドの他の章では、ARGVが正しい選択ではないと言います。

1.1.4 実行可能なawkプログラム

最後に、ARGV [0]の値(組み込み変数を参照)はオペレーティングシステムによって異なります。一部のシステムでは「awk」と入力し、一部のシステムではawkのフルパス名(/bin/awkなど)、一部のシステムではスクリプト名(「advice」)を入力します。 (DC)スクリプト名を提供するためにARGV [0]の値に依存しないでください。

関連情報