getline()
awk
GNU関数を使用していくつかのコマンドを実行し、返されたエラー番号()の値を印刷しようとしていますerrno
。ただし、存在しないディレクトリ/ファイルの単純な失敗ケースの場合、変数は埋められないようです。
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
close(cmd); print ENVIRON["ERRNO"]
}'
ls
このステートメントは、上記のエラー文字列が出力されたときにprint
有効なエラー番号を生成しません。私もマニュアルページ使用PROCINFO["errno"]
してPROCINFO["ERRNO"]
動作しないこと。ファイルを閉じる前にファイル記述子を印刷してみましたが、やはり機能しませんでした。ENOENT
この場合、期待は間違っていますか?
答え1
を使用してエラー番号を取得できませんgetline
。コマンドでは、出力はでls
はなく出力されますprint result
。
フォームで実行され、次のcmd | getline result
出力cmd
がにパイプされますgetline
。1
出力がある場合は返し、0
失敗した場合はEOFを返します-1
。問題は、失敗が実行自体のためではgetline
ありませんcmd
。
awk 'BEGIN {
while ( ( getline result < "/etc/shadow") > 0 ) {
print result
}
print "XXX: ", ERRNO
}'
XXX: Permission denied
/etc/shadow
読み取れないためgetline
実行できず、変数エラーが報告されていることがわかりますERRNO
。
cmd
GNU awk は posix モードでない場合は状態を返すので、次のことができます。
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
status=close(cmd);
if (status != 0) {
code=and(rshift(status, 8),0xFF)
printf("Exit status: %d, exit code: %d\n", status, code)
}
}'
ls: cannot access '/non/existing/path': No such file or directory
Exit status: 512, exit code: 2
POSIX モードでは終了状態を取得できません。
POSXILY_CORRECT=1 awk 'BEGIN {
cmd = "ls -lrth /non/existing/path"
while ( ( cmd | getline result ) > 0 ) {
print result
}
status=close(cmd);
if (status != 0) {
code=and(rshift(status, 8),0xFF)
printf("Exit status: %d, exit code: %d\n", status, code)
}
}'
ls: cannot access '/non/existing/path': No such file or directory
答え2
ERRNOはgawkにのみ設定できます(GNU awkただ)getlineまたはcloseが失敗しますが、lsの(空の!)出力を正常に読み取る場合です。 lsは標準エラーチャネル(「ls:アクセスできません...」)にエラーメッセージを表示し、標準出力に何も書き込まず、エラーコードがあるため出力が空です。
GNU awkを使用すると、次のコマンドの終了ステータスを取得できます。
exitstatus=close(cmd)
if (exitstatus) {
# do something
}
コマンドのエラーメッセージが必要な場合は、標準エラーチャネルをいくつかのファイルにリダイレクトして読み取る必要があります。
awk 'BEGIN {
cmd = "ls -lrth /non/existing/path 2>standard-error.txt"
while ( ( cmd | getline result ) > 0 ) {
print result
}
es=close(cmd);
if (es) {
getline errstring < "standard-error.txt"
print "exitstatus "es" error message "errstring;
}
}'