どの行かを確認する方法はありますか?数字スクリプトはbash
「今」実行されていますか?
ただし、ルックスを使用すると、bash -x script.sh
現在の行番号を取得する必要があります。
答え1
答え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 -x
LINENO
、PS4
および(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」を追加します。次に、スクリプトが実行されるたびにスクリプトが実行されている行をエコーします。スクリプトの実行ツリーと同じです。