Чи є спосіб , щоб перевірити , яку лінію номер з bash
сценарію виконуються «прямо зараз»?
Використання bash -x script.sh
виглядає перспективно; однак мені потрібно отримати номер поточного рядка.
Чи є спосіб , щоб перевірити , яку лінію номер з bash
сценарію виконуються «прямо зараз»?
Використання bash -x script.sh
виглядає перспективно; однак мені потрібно отримати номер поточного рядка.
Відповіді:
Об'єднати 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
Так, спосіб є.
Існує масив номерів рядків, де викликана функція.
Визначте цю функцію:
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 у цьому випадку).
Ось рішення, яке запозичує частини відповідей l0b0 та відповідей DopeGhoti (і, в меншій мірі, соронтар ). Як і ці відповіді, моя використовує $LINENO
для виявлення номера рядка; На відміну від них, я використовую trap
для запуску звітності. trap
Команда bash описана в bash (1) :
trap [-lp] [[arg] sigspec ...]
Команда Arg повинна бути прочитана і виконана , коли оболонка приймає сигнал (и) sigspec . … ︙
… Якщо знаком є DEBUG , команда arg виконується перед кожною простою командою ,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"
команду перед кожною командою в скрипті і виробляє цей вихід:
$ ./script 3: Ср, 05 квітня 2017 10:16:17 4: 5: ср, 05 квітня 2017 10:16:47 ранку 7: 8: ср, 05 квітня 2017 10:16:58 10: всього 4 -rwxr-xr-x 1 myusername mygroup 221 5 квітня 10:01 таємниця -rwxr-xr-x 1 myusername mygroup 252 квітня 5 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 132 5 квітня 09:59 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 квітня 08:34 other_file 11: 13: таємниця 14: -rwxr-xr-x 1 myusername mygroup 221 5 квітня 10:01 таємниця 11: 13: таємниця2 14: -rwxr-xr-x 1 myusername mygroup 252 квітня 5 10:01 myscript2 11: 13: myscript2.log 14: -rw-r - r-- 1 myusername mygroup 132 5 квітня 09:59 myscript2.log 11: 13: other_file 14: -rw-r - r-- 1 myusername mygroup 45 5 квітня 08:34 other_file 17: 17: 19: i = 0 19: ср, 05 квітня 2017 10:16:59 17: 17: 19: i = 1 19: ср, 05 квітня 2017 10:16:59 17: 17: 19: i = 2 19: ср, 05 квітня 2017 10:16:59 17: 17: 22: 42 $
Примітки:
sleep
, який охоплює рядки 6 та 7 сценарію, повідомляється як рядок 7.for f in *
) повідомляється один раз перед кожною ітерацією цього for
циклу.echo "$f"
і ls -ld "$f"
правильно повідомляються у відповідних рядках (13 та 14).for ((i=0; i<3; i++))
) повідомляється двічі
перед кожною ітерацією цього for
циклу та ще двічі після останньої ітерації.set -x
, LINENO
і PS4
(які вказані в стандарті POSIX), то DEBUG trap
є розширення баш і не буде працювати у всіх оболонках.trap
може виконувати будь-які команди (и), і не обмежується записом до стандартного виводу або стандартної помилки сценарію.Питання говорить: «перевірте, який номер рядка bash-сценарію виконується« прямо зараз »», не вказуючи користувальницький інтерфейс. Інший підхід полягає в тому, щоб постійно записувати поточний номер рядка в файл журналу:
$ diff myscript myscript2 2c2 <trap 'printf "% 3d:" "$ LINENO"' DEBUG --- > exec 6> myscript2.log && trap 'printf "% 3d \ n" "$ LINENO"> & 6' DEBUG $ ./myscript2 Ср, 05 квітня 2017 10:23:50 Ср, 05 квітня 2017 10:24:20 Ср, 05 квітня 2017 10:24:31 всього 4 -rwxr-xr-x 1 myusername mygroup 221 5 квітня 10:01 таємниця -rwxr-xr-x 1 myusername mygroup 252 квітня 5 10:01 myscript2 -rw-r - r-- 1 myusername mygroup 24 квітня 5 10:23 myscript2.log -rw-r - r-- 1 myusername mygroup 45 5 квітня 08:34 other_file таємницю -rwxr-xr-x 1 myusername mygroup 221 5 квітня 10:01 таємниця таємниця2 -rwxr-xr-x 1 myusername mygroup 252 квітня 5 10:01 myscript2 myscript2.log -rw-r - r-- 1 myusername mygroup 60 5 квітня 10:23 myscript2.log other_file -rw-r - r-- 1 myusername mygroup 45 5 квітня 08:34 other_file i = 0 Ср, 05 квітня 2017 10:24:31 i = 1 Ср, 05 квітня 2017 10:24:31 i = 2 Ср, 05 квітня 2017 10:24:31 42 $
Ми можемо стежити за виконанням цього сценарію, відстежуючи вміст myscript2.log
файлу з іншого терміналу. Наприклад, у другому sleep
,
$ tail myscript2.log
3
4
5
7
#!/bin/bash -x
Додайте цей "-x" на початку вашого сценарію. Тоді кожен раз, коли ви виконуватимете скрипт, він буде відповідати лінії, яку виконує ваш сценарій. як дерево виконання вашого сценарію.