Есть ли способ , чтобы проверить , какую линию номер из 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 (и, в меньшей степени, ответов sorontar ). Как и те ответы, мой использует, $LINENO
чтобы узнать номер строки; в отличие от них, я использую trap
для запуска отчетности. trap
Команда bash описана в bash (1) :
trap [-lp] [[arg] sigspec ...]
Команда arg должна быть прочитана и выполнена, когда оболочка получает сигнал sigspec . ... ︙
... Если sigspec является DEBUG , команда агд выполняется перед каждой простой команды ,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: ср, 5 апреля 2017 г. 10:16:17 4: 5: ср, 5 апреля 2017 г. 10:16:47 7: 8: ср, 5 апреля 2017 г., 10:16:58 10: всего 4 -rwxr-xr-x 1 myusername mygroup 221 5 апреля 10:01 myscript -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: myscript 14: -rwxr-xr-x 1 myusername mygroup 221 5 апреля 10:01 myscript 11: 13: myscript2 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: другой_файл 14: -rw-r - r-- 1 myusername mygroup 45 апр. 5 08:34 other_file 17: 17: 19: я = 0 19: ср, 5 апреля 2017 г. 10:16:59 17: 17: 19: я = 1 19: ср, 5 апреля 2017 г. 10:16:59 17: 17: 19: я = 2 19: ср, 5 апреля 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"' ОТЛАДКА --- > 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 myscript -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 MyScript -rwxr-xr-x 1 myusername mygroup 221 5 апреля 10:01 myscript myscript2 -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 я = 0 Ср, 05 апреля 2017 10:24:31 я = 1 Ср, 05 апреля 2017 10:24:31 я = 2 Ср, 05 апреля 2017 10:24:31 42 $
Мы можем контролировать выполнение этого скрипта, отслеживая содержимое myscript2.log
файла с другого терминала. Например, во втором sleep
,
$ tail myscript2.log
3
4
5
7
Вы можете сделать echo $LINENO
это в скрипте, и он должен вывести любую строку, в которой находится эта команда.
#!/bin/bash
echo $LINENO
$ ./foo.sh
2
#!/bin/bash -x
Добавьте этот «-x» в начале вашего скрипта. Затем каждый раз, когда вы выполняете скрипт, он повторяет строку, которую исполняет ваш скрипт. как дерево выполнения вашего скрипта.