web-dev-qa-db-ja.com

mawkで独自のスクリプト名を印刷する方法は?

バッシュで$0にはスクリプトの名前が含まれていますが、次の内容でmyscript.awkという名前のスクリプトを作成すると、awkに含まれます。

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

実行すると、「awk」のみが出力されます。さらに、i> 0のARGV [i]は、コマンドラインのスクリプト引数にのみ使用されます。それでは、スクリプトの名前(この場合は "myscript.awk")を出力する方法を教えてください。

13
cipper

CygwinのbashでGNU awk 4.1.3を使用:

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

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

それがどれほどポータブルかわかりません。ただし、いつものように、シェルスクリプトでShebangを使用してawkスクリプトを実行することはありません。これは、可能性のある機能を奪うためです。シンプルにして、代わりに次のようにします。

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

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

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

5
Ed Morton

gawkdocumentation のようにこれは可能ではないと思います:

最後に、ARGV[0](「7.5組み込み変数」を参照)の値は、オペレーティングシステムによって異なります。一部のシステムはawkをそこに配置し、いくつかはawkの完全パス名(/bin/awkなど)を配置し、一部のシステムはスクリプトの名前を配置します(「アドバイス」)。スクリプト名を提供するためにARGV[0]の値に依存しないでください。

linuxでは、一種のダーティーハックを使用してみることができます。コメントで StéphaneChazelas に指摘されているように、awkの実装がNULバイトをサポートしている場合は可能です。

#!/usr/bin/awk -f

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

Awkからコマンド名を直接取得する方法はわかりません。ただし、サブシェルを介してそれを見つけることができます。

ガウク

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

cmdname.awk

#!/usr/bin/gawk -f

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

mawkとnawk

同じアプローチを使用できますが、$PPID特殊シェル変数(親のPID)からawkのPIDを導出します。

cmdname.awk

#!/usr/bin/mawk -f

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

テスト中

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

./cmdname.awk

どちらの場合も出力:

cmdname.awk
5
Thor

GNU awkを使用する

チェック GNU awkユーザーガイド-7.5.2情報を伝える組み込み変数 私は偶然見つけました:

PROCINFO#

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

PROCINFO ["pid"]

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

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

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

私が使う ps -ef、2列目に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など)を配置したり、スクリプトの名前(「アドバイス」)を配置したりします。 (d.c.)スクリプト名を提供するのにARGV [0]の値に依存しないでください。

4
fedorqui

POSIXの場合awk

#!/usr/bin/awk -f

BEGIN {
    print ENVIRON["AWKSCRIPT"]
}

次に:

AWKSCRIPT=test.awk ./test.awk
test.awk
4
cuonglm