web-dev-qa-db-ja.com

bashスクリプトの実行時に行番号を表示する方法

たくさんのコマンドがあり、大量の出力を生成するテストスクリプトがあります。set -xまたはset -vset -eを使用しているため、エラーが発生するとスクリプトが停止します。ただし、問題を特定するために、どの行が実行を停止したのかを特定することは依然としてかなり困難です。各行が実行される前にスクリプトの行番号を出力できる方法はありますか?または、set -xによって生成されたコマンド展示の前に行番号を出力しますか?または、スクリプト行の場所の問題に対処できる方法であれば、非常に役立ちます。ありがとう。

68
dspjm

既に-xを使用していると言います。変数PS4は、-xオプションが設定され、デフォルトで:にスペースが続くときに、コマンドラインがエコーされる前に出力されるプロンプトであることを示します。

PS4を変更して、LINENO(現在実行中のスクリプトまたはシェル関数の行番号)を出力できます。

たとえば、スクリプトが次の場合:

$ cat script
foo=10
echo ${foo}
echo $((2 + 2))

したがって、実行すると行番号が出力されます。

$ PS4='Line ${LINENO}: ' bash -x script
Line 1: foo=10
Line 2: echo 10
10
Line 3: echo 4
4

http://wiki.bash-hackers.org/scripting/debuggingtips は、トレースに必要なすべてを出力する究極のPS4を提供します。

export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
128
devnull

Bashでは、$LINENOには、スクリプトが現在実行されている行番号が含まれます。

関数が呼び出された行番号を知る必要がある場合は、$BASH_LINENO。この変数は配列であることに注意してください。

例えば:

#!/bin/bash       

function log() {
    echo "LINENO: ${LINENO}"
    echo "BASH_LINENO: ${BASH_LINENO[*]}"
}

function foo() {
    log "$@"
}

foo "$@"

Bash変数の詳細については、 here をご覧ください。

27
Deqing

LINENOを使用しないシェルの回避策

かなり洗練されたスクリプトでは、すべての行番号を見たくありません。むしろ、出力を制御したいと思います。

関数を定義する

echo_line_no () {
    grep -n "$1" $0 |  sed "s/echo_line_no//" 
    # grep the line(s) containing input $1 with line numbers
    # replace the function name with nothing 
} # echo_line_no

次のような引用符で使用します

echo_line_no "this is a simple comment with a line number"

出力は

16   "this is a simple comment with a line number"

ソースファイル内のこの行の数が16の場合.

これは基本的に質問に答えます bashスクリプトの実行時に行番号を表示する方法LINENOのないashまたは他のシェルのユーザー向け。

追加するものはありますか?

承知しました。なぜこれが必要なのですか?これをどのように使いますか?これで何ができますか?このシンプルなアプローチは本当に十分ですか、それとも便利ですか?なぜこれをいじくり回したいのですか?

もっと知りたい? デバッグのリフレクションを読む

0
kklepper

シンプルな(しかし強力な)ソリューション:問題の原因と思われるコードの周りにechoを配置し、画面にメッセージが表示されなくなるまでechoを1行ずつ移動します-スクリプトが停止するため以前のエラーのため。

さらに強力なソリューション: bashdb bashデバッガーをインストールし、スクリプトを1行ずつデバッグします

0
hek2mgl