-e
предназначен для случаев, когда вам нужна удаленная оболочка отличная от стандартной ssh
. rsync
использует ssh
в качестве транспорта по умолчанию, но может использовать любую удаленную оболочку (с парой ограничений*), ему не важно, как он подключается к удаленному серверу.
* Удаленная оболочка, которую вы используете, должна вести себя как оболочка. Она должна интерпретировать свой нулевой аргумент как место назначения, а каждый следующий аргумент как команду для выполнения; команда, которую rsync передает удаленной оболочке, это команда rsync --server ...
, которая запускает сервер rsync на удаленном конце. Он также должен присоединить свой STDIN к STDIN команды, а STDOUT команды к STDOUT, чтобы rsync и сервер rsync могли общаться через удаленный shell.
Вы можете echo $ LINENO
в сценарии, и он должен выводить любую строку, в которой находится эта команда.
#!/bin/bash
echo $LINENO
$ ./foo.sh
2
#!/bin/bash -x
Добавьте этот «-x» в начало вашего скрипта. Затем каждый раз, когда вы выполняете сценарий, он будет отображать строку, выполняемую вашим сценарием. как дерево выполнения вашего скрипта.
Объединить 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
для определения номера строки;
в отличие от них, я использую ловушку
для запуска отчетов.
команда bash trap
описана в bash(1):
trap [-lp] [[arg] sigspec ...]
Команда arg должна быть прочитана и выполнена когда оболочка получает сигнал(ы) sigspec. … ︙
… Если sigspec является DEBUG, команда arg выполняется перед каждой простой командой,for
команда,case
команда,select
команда, каждая арифметическая командадля
, и до выполнения первой команды в функции оболочки…
Итак, этот скрипт:
$ 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: Wed, Apr 05, 2017 10:16:47 AM 7: 8: Wed, Apr 05, 2017 10:16:58 AM 10: total 4 -rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2 -rw-r--r-- 1 myusername mygroup 132 Apr 5 09:59 myscript2.log -rw-r--r-- 1 myusername mygroup 45 Apr 5 08:34 other_file 11: 13: myscript 14: -rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript 11: 13: myscript2 14: -rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2 11: 13: myscript2.log 14: -rw-r--r-- 1 myusername mygroup 132 Apr 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: 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 $
Примечания:
сон
, который охватывает строки скрипта 6 и 7,
сообщается как строка 7. для f в *
) сообщается один раз
перед каждой итерацией цикла for
. echo "$f"
и ls -ld "$f"
сообщаются правильно
в соответствующих строках (13 и 14). for ((i=0; i<3; i++))
) сообщается дважды
перед каждой итерацией этого цикла for
,
и еще дважды после последней итерации. set -x
, LINENO
и PS4
(которые указаны в стандарте POSIX),
ловушка DEBUG
является расширением bash и не будет работать во всех оболочках.
может запускать любые команды,
и не ограничивается записью в стандартный вывод скрипта
или стандартная ошибка. Вопрос гласит: «Проверьте, какой номер строки сценария 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 total 4 -rwxr-xr-x 1 myusername mygroup 221 Apr 5 10:01 myscript -rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2 -rw-r--r-- 1 myusername mygroup 24 Apr 5 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 Apr 5 10:01 myscript myscript2 -rwxr-xr-x 1 myusername mygroup 252 Apr 5 10:01 myscript2 myscript2.log -rw-r--r-- 1 myusername mygroup 60 Apr 5 10:23 myscript2.log other_file -rw-r--r-- 1 myusername mygroup 45 Apr 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
с другого терминала.
Например, во время второго сна
,
$ tail myscript2.log
3
4
5
7