Как проверить, какая строка скрипта bash выполняется

Есть ли способ проверить, какой номер строки сценария bash выполняется «прямо сейчас»?

5 Solutions collect form web for “Как проверить, какая строка скрипта bash выполняется”

Объедините 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).

Вы можете echo $LINENO в скрипте, и он должен выводить любую строку, в которой эта команда echo $LINENO .

 #!/bin/bash echo $LINENO $ ./foo.sh 2 

Вот решение, которое заимствует части ответов l0b0 и DopeGhoti (и, в меньшей степени, sorontar's ). Как и те ответы, $LINENO использует $LINENO чтобы узнать номер строки; в отличие от них, я использую trap для запуска отчетности. Команда trap bash описана в bash (1) :

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

    Команда arg должна считываться и выполняться, когда оболочка получает сигнал (ы) sigspec . … ⁠ ︙
    … Если sigspec является DEBUG , команда arg выполняется перед каждой простой командой , командой command, case command, командой 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: Wed, Apr 05, 2017 10:16:17 AM
   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 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: other_file
  14: -rw-r - r-- 1 myusername mygroup 45 Апр 5 08:34 other_file
  17: 17: 19: i = 0
  19: Wed, Apr 05, 2017 10:16:59 AM
  17: 17: 19: i = 1
  19: Wed, Apr 05, 2017 10:16:59 AM
  17: 17: 19: i = 2
  19: Wed, Apr 05, 2017 10:16:59 AM
  17: 17: 22: 42
 $ 

Заметки:

  • Как и ответ l0b0 , это минимально инвазивное – просто добавьте строку 2.
  • В отличие от ответа l0b0 , это не отображает сами команды, но вы не просили об этом.
  • Второй sleep , который охватывает строки сценариев 6 и 7, сообщается как строка 7.
  • Строка 11 ( for f in * ) сообщается раз перед каждой итерацией этого цикла.
  • echo "$f" и ls -ld "$f" корректно отображаются в соответствующих строках (13 и 14).
  • Строка 17 ( for ((i=0; i<3; i++)) ) сообщается дважды перед каждой итерацией цикла for и еще дважды после последней итерации.
  • В отличие от set -x , LINENO и PS4 (которые указаны стандартом POSIX), trap DEBUG является расширением bash и не будет работать во всех оболочках.
  • trap DEBUG может запускать любую команду (ы) и не ограничивается записью на стандартный вывод сценария или стандартную ошибку.

В вопросе говорится: «Проверьте, какой номер строки сценария 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, Apr 05, 2017 10:24:20 AM
 Wed, Apr 05, 2017 10:24:31 AM
 всего 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
 i = 0
 Wed, Apr 05, 2017 10:24:31 AM
 i = 1
 Wed, Apr 05, 2017 10:24:31 AM
 i = 2
 Wed, Apr 05, 2017 10:24:31 AM
 42
 $ 

Мы можем контролировать выполнение этого скрипта, контролируя содержимое файла myscript2.log с другого терминала. Например, во время второго sleep ,

 $ tail myscript2.log 3 4 5 7 
 #!/bin/bash -x 

Добавьте, что «-x» в начале вашего скрипта. Затем каждый раз, когда вы выполняете скрипт, он будет повторять строку, выполняемую вашим скриптом. как дерево выполнения вашего скрипта.

  • Shell Script - перенаправленный вывод в файл и результаты не ожидаются в первом запуске
  • Как передать несколько строк параметру без цикла for?
  • Проверка того, может ли парольная фраза расшифровывать симметрично зашифрованные файлы
  • Почему я не могу напечатать переменную, которую я вижу на выходе env?
  • Как ответить grep, чтобы выяснить, сколько звонков было рассчитано на время?
  • Как разобрать CSV-файл на основе групп из определенного количества строк?
  • Баш ограничен оболочкой с использованием rbash
  • Соединения SSH, работающие в фоновом режиме, не выводятся, если несколько соединений были запущены одной и той же оболочкой
  • Я случайно вышел из vim с: x! ~, И теперь моя ~ появляется по другому пути
  • Регулярное выражение, как получить значение в сценарии оболочки?
  • Проблема с булевыми тестами && и || в bash
  • Использование переменной для выполнения команды curl
  • Linux и Unix - лучшая ОС в мире.