web-dev-qa-db-ja.com

bashスクリプトのどの行が実行されているかを確認する方法

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

bash -x script.shの使用は有望に見えます。ただし、現在の行番号を取得する必要があります。

16
user224371

スクリプト内で xtracePS4 と組み合わせます。

$ 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
21
l0b0

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

この関数を定義します。

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)。

10
Isaac

l0b0'sDopeGhoti’s の一部を借りる(そして、より少ない程度に sorontar's )ソリューションを以下に示します。これらの回答と同様に、私の場合も_$LINENO_を使用して行番号を検出しています。それらとは異なり、私はtrapを使用してレポートをトリガーします。 bashのtrapコマンドについては bash(1) で説明しています:

_trap [-lp] [[arg] sigspec ...]_

    コマンド argシェルが信号を受信したときに読み取られて実行されます sigspec。 …⁠︙
    … もし sigspecです デバッグ、 コマンド argすべての前に実行されます 簡単なコマンドforcommand、casecommand、selectcommand、すべての算術forcommand、および最初のコマンドがシェル関数で実行される前…

したがって、このスクリプト:

_$ 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 AM 
 4:5:2017年4月5日水曜日10:16:47 AM 
 7 :8:2017年4月5日水曜日10:16:58 AM 
 10:合計4 
-rwxr-xr-x 1 myusername mygroup 221 4月5日10:01 myscript 
-rwxr-xr-x 1 myusername mygroup 252 4月5日10:01 myscript2 
-rw-r--r-- 1 myusername mygroup 132 Apr 5 09:59 myscript2.log 
-rw-r--r-- 1 myusername mygroup  4月5日45 08:34 other_file 
 11:13:myscript 
 14:-rwxr-xr-x 1 myusername mygroup 221 4月5日10:01 myscript 
 11:13:myscript2 
 14:-rwxr-xr-x 1 myusername mygroup 252 4月5日10:01 myscript2 
 11:13:myscript2.log 
 14:-rw-r--r-- 1 myusername mygroup 132 4月5日09:59 myscript2.log 
 11:13:other_file 
 14:-rw-r--r-- 1 myusername mygroup  45 Apr 5 08:34 other_file 
 17:17:19:i = 0 
 19:水曜日、2017年4月5日10:16:59 AM 
 17:17:19 :i = 1 
 19:水曜日、2017年4月5日10:16:59 AM 
 17:17:19:i = 2 
 19:2017年4月5日水曜日10:16:59 AM 
 17:17:22:42 
 $

ノート:

  • l0b0の答え と同様に、これは最小限の侵襲性です。2行目を追加するだけです。
  • l0b0の答え とは異なり、これはコマンド自体を表示しませんが、それを実行するように要求しませんでした。
  • スクリプトの行6と7にまたがる2番目のsleepは、行7として報告されます。
  • 11行目(_for f in *_)は、そのforループの各反復の前に1回報告されます。
  • _echo "$f"_および_ls -ld "$f"_は、それぞれの行(13および14)で正しく報告されます。
  • 17行目(for ((i=0; i<3; i++)))が報告されるtwiceその反復の前にforループ、および最後の反復のあと2回。
  • _set -x_、LINENOおよび_PS4_(POSIX標準で指定されている)とは異なり、DEBUG trapはbash拡張であり、すべてのシェルで機能するわけではありません。
  • DEBUG trapは任意のコマンドを実行でき、スクリプトの標準出力または標準エラーへの書き込みに限定されません。

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

$ diff myscript myscript2 
 2c2 
 <trap 'printf "%3d:" "$ LINENO"' DEBUG 
 --- 
> exec 6> myscript2.log && trap 'printf "%3d\n" "$ LINENO">&6' DEBUG 
 $ ./myscript2
Wed、Apr 05、2017 10:23:50 AM 
 Wed 、2017年4月5日10:24:20 AM 
 2017年4月5日水曜日10:24:31 AM 
合計4 
-rwxr-xr-x 1 myusername mygroup 221 4月5日10:01 myscript 
-rwxr-xr-x 1 myusername mygroup 252 4月5日10:01 myscript2 
-rw-r--r-- 1 myusername mygroup  4月24日10:23 myscript2.log 
-rw-r--r-- 1 myusername mygroup  45 Apr 5 08:34 other_file 
 myscript 
-rwxr-xr-x 1 myusername mygroup 221 4月5日10:01 myscript 
 myscript2 
-rwxr-xr-x 1 myusername mygroup 252 4月5日10:01 myscript2 
 myscript2.log 
-rw-r--r-- 1 myusername mygroup  4月60日10:23 myscript2.log 
 other_file 
-rw-r--r-- 1 myusername mygroup  45 Apr 5 08:34 other_file 
 i = 0 
 2017年4月5日水曜日10:24:31 AM 
 i = 1 
 4月5日水曜日2017 10:24:31 AM 
 i = 2 
 2017年4月5日水曜日10:24:31 AM 
 42 
 $

別の端末から_myscript2.log_ファイルの内容を監視することにより、このスクリプトの実行を監視できます。たとえば、2番目のsleepの間、

_$ tail myscript2.log
  3
  4
  5
  7
_

あなたはできる echo $LINENOをスクリプトに追加すると、コマンドが実行されている行が出力されます。

#!/bin/bash
echo $LINENO

$ ./foo.sh
2
6
DopeGhoti