Bashスクリプトが実行されている行を確認する方法

Bashスクリプトが実行されている行を確認する方法

どの行かを確認する方法はありますか?数字スクリプトはbash「今」実行されていますか?

ただし、ルックスを使用すると、bash -x script.sh現在の行番号を取得する必要があります。

答え1

結合するxtraceそしてPS4スクリプト内部:

$ cat test.sh 
#!/usr/bin/env bash
set -x
PS4='+${LINENO}: '

sleep 1m
sleep 1d
$ timeout 5 ./test.sh
+3: PS4='+${LINENO}: '
+5: sleep 1m

または親シェルから:

$ cat test.sh 
sleep 1m
sleep 1d
$ export PS4='+${LINENO}: '
$ timeout 5 bash -x ./test.sh
+1: sleep 1m

答え2

はい、方法があります。
呼び出された関数の行番号の配列があります。

この関数を定義します。

f(){ echo "${BASH_LINENO[-2]}"; }

行番号が必要なすべての行から呼び出しますf。たとえば、次のようになります。

#!/bin/bash


f(){ echo "${BASH_LINENO[-2]}"; }

f

echo next1
f

echo next2
f

echo next 3
f

以下を印刷します。

6
next 1
9
next 2
12
next 3
15

次の関数のトレースを表示するように拡張できます。

#!/bin/bash

f(){
    for ((i=${#BASH_LINENO[@]}-1;i>=0;i--)); do
    printf '<%s:%s> ' "${FUNCNAME[i]}" "${BASH_LINENO[i]}";
    done
    echo "$LINENO"
 }

SomeOtherFunction(){ echo -n "test the line numbering:  "; f; }

f

echo next 1
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 2
echo -n "    This line numbering:  "; f
SomeOtherFunction

echo next 3
echo -n "    This line numbering:  "; f

以下を印刷します。

$ ./script
<main:0> <f:12> 7
next 1
    This line numbering:  <main:0> <f:15> 7
test the line numbering:  <main:0> <SomeOtherFunction:16> <f:10> 7
next 2
    This line numbering:  <main:0> <f:19> 7
test the line numbering:  <main:0> <SomeOtherFunction:20> <f:10> 7
next 3
    This line numbering:  <main:0> <f:23> 7

上記の出力はecho "$LINENO"常に同じです(この場合は7)。

答え3

部品を借りるソリューションがありますl0b0'sそしてゴーゴー答えは(そしてある程度は、ソロンタ)。この答えと同様に、私はそれを使用して$LINENO行番号を検索し、trapレポートを実行するために使用します。 bashtrapコマンドについては後述します。大きな打撃(1):

trap [-lp] [[arg] sigspec ...]

    注文するアルギニンシェルがシグナルを受信すると、読み込み実行します。信号仕様。 … ⁠︙
    …もし信号仕様はいデバッグ、注文するアルギニンそれぞれ前に実行簡単なコマンドforコマンド、caseコマンド、selectコマンド、すべての算術forコマンド、およびシェル関数の最初のコマンドを実行する前に...

したがって、このスクリプトは次のようになります。

$ cat -n myscript
     1  #!/bin/bash
     2  trap 'printf "%3d: " "$LINENO"' DEBUG
     3  date
     4  sleep 30
     5  date
     6  sleep \
     7        11
     8  date
     9
    10  ls -l
    11  for f in *
    12  do
    13          echo "$f"  &&
    14                         ls -ld "$f"
    15  done
    16
    17  for ((i=0; i<3; i++))
    18  do
    19          echo "i = $i"; date
    20  done
    21
    22  echo $((5+25+12))
$

printf "%3d: " "$LINENO"このコマンドはスクリプト内のすべてのコマンドの前に実行され、次の出力を生成します。

$ ./myscript
  3: 2017年4月5日水曜日午前10:16:17
  4:5: 2017年4月5日水曜日 10:16:47
  7:8: 2017年4月5日水曜日 10:16:58
 10:4銃
-rwxr-xr-x 1マイユーザー名マイグループ221年4月5日 10:01
-rwxr-xr-x 1マイユーザー名マイグループ252 4月5日 10:01 myscript2
-rw-r--r-- 1マイユーザー名マイグループ132 4月5日 09:59 myscript2.log
-rw-r--r-- 1マイユーザー名マイグループ  45年4月5日 08:34 other_file
 11:13: 私のスクリプト
 14:-rwxr-xr-x 1マイユーザー名マイグループ221年4月5日 10:01
 11:13:myscript2
 14:-rwxr-xr-x 1マイユーザー名マイグループ252 4月5日 10:01 myscript2
 11:13: myscript2.log
 14:-rw-r--r--1マイユーザー名マイグループ132 4月5日 09:59 myscript2.log
 11:13: その他の文書
 14:-rw-r--r--1マイユーザー名マイグループ  45年4月5日 08:34 other_file
 17:17:19:i=0
 19: 2017年4月5日水曜日午前10時16分59秒
 17:17:19:私=1
 19: 2017年4月5日水曜日午前10時16分59秒
 17:17:19:私=2
 19: 2017年4月5日水曜日午前10時16分59秒
 17:17:22:42
$

メモ:

  • 良いl0b0の答え、最小侵襲的です。 2行目を追加するだけです。
  • 同じではないl0b0の答え、コマンド自体を表示しませんが、そうするように要求しませんでした。
  • 2番目はsleepスクリプトの6行と7行にまたがり、7行として報告されます。
  • 11行目(for f in *)は、ループが繰り返される前に1回報告しますfor
  • echo "$f"ls -ld "$f"その行(13と14)に正しく報告されます。
  • 行17(for ((i=0; i<3; i++)))が報告されます。二重 このループの各繰り返しの前とfor最後の繰り返しの後に2回。
  • set -xLINENOPS4 および(POSIX標準で指定されている)とは異なり、DEBUGtrapはbash拡張であり、すべてのシェルでは機能しません。
  • DEBUG はtrap任意のコマンドを実行でき、スクリプトの標準出力や標準エラーに書き込むことに限定されません。

問題は、ユーザーインターフェイスを指定せずに「今実行しているbashスクリプトの行番号を確認してください」です。別の方法は、現在の行番号をログファイルに継続的に書き込むことです。

$diff myscript myscript2
2c2
< トラップ 'printf "%3d:" "$LINENO"' デバッグ中
---
> exec 6> myscript2.log && トラップ 'printf "%3d\n" "$LINENO" >&6' デバッグ
$ ./myscript2
2017年4月5日水曜日午前10時23分50分
2017年4月5日水曜日午前10時24分20分
2017年4月5日水曜日10:24:31
合計4個
-rwxr-xr-x 1マイユーザー名マイグループ221年4月5日 10:01
-rwxr-xr-x 1マイユーザー名マイグループ252 4月5日 10:01 myscript2
-rw-r--r-- 1マイユーザー名マイグループ  4月5日、24日、10:23 myscript2.log
-rw-r--r-- 1マイユーザー名マイグループ  45年4月5日 08:34 other_file
スクリプト
-rwxr-xr-x 1マイユーザー名マイグループ221年4月5日 10:01
スクリプト2
-rwxr-xr-x 1マイユーザー名マイグループ252 4月5日 10:01 myscript2
myscript2.log
-rw-r--r-- 1マイユーザー名マイグループ  60年4月5日 10:23 myscript2.log
その他のファイル
-rw-r--r-- 1マイユーザー名マイグループ  45年4月5日 08:34 other_file
私=0
2017年4月5日水曜日10:24:31
I = 1
2017年4月5日水曜日10:24:31
I = 2
2017年4月5日水曜日10:24:31
42
$

myscript2.log他の端末でファイルの内容を監視することで、このスクリプトの実行を監視できます。たとえばsleep、2回目の間

$ tail myscript2.log
  3
  4
  5
  7

答え4

#!/bin/bash -x

スクリプトの先頭に「-x」を追加します。次に、スクリプトが実行されるたびにスクリプトが実行されている行をエコーし​​ます。スクリプトの実行ツリーと同じです。

関連情報