Co to jest polecenie „dzwoniącego”?

12

Używam Ubuntu 10.10 z otwartym openboxem. Zauważyłem dzisiaj komendę o nazwie caller, jednak nie ma strony podręcznika, nie reaguje ona na żadne dane wejściowe (lub --help) i whereis jej nie znajduje.

Wiesz co to jest?

Gilles „SO- przestań być zły”
źródło

Odpowiedzi:

16

Biegać

type caller

i zobaczysz, że jest to wbudowana powłoka. Bieganie

help caller

pokaże swoją funkcję, również zgłoszoną na stronie podręcznika bash. Krótko

Return the context of the current subroutine call.

enzotib
źródło
3
Niesamowite. Nie tylko nauczyłem się, co robi to polecenie, ale także nauczyłem się polecenia „typ”. Dzięki :)
2
TIL bash ma wbudowane helppolecenie
nibot
Który mógłbym dwukrotnie głosować za nauczenie nie tylko odpowiedzi, ale i całego procesu.
dmckee --- były moderator kociak
@Muu, @nibot, @dmckee: również type type, type help, help typei help helpmoże być zabawa, aby uruchomić :)
enzotib
10

callerTo polecenie wbudowane (niewymienione przez POSIX) pojawiła się w wersji 3.0 bash i zwraca kontekst dowolnego aktywnego połączenia podprogramu. Zobacz: Wbudowane bash, by przeczytać więcej.

Składnia:

caller [FRAMENUMBER]

Jeśli numer ramki jest podany jako nieujemna liczba całkowita, wyświetla numer linii, nazwę podprogramu i plik źródłowy odpowiadający tej pozycji w stosie bieżącego wywołania wykonania.

Bez parametrów parametr wywołujący wyświetla numer linii i nazwę pliku źródłowego bieżącego wywołania podprogramu.

Sprawdź następujący prosty ślad stosu na Bash Hackers Wiki :

#!/bin/bash

die() {
  local frame=0
  while caller $frame; do
    ((frame++));
  done
  echo "$*"
  exit 1
}

f1() { die "*** an error occured ***"; }
f2() { f1; }
f3() { f2; }

f3

Wynik:

12 f1 ./callertest.sh
13 f2 ./callertest.sh
14 f3 ./callertest.sh
16 main ./callertest.sh
*** an error occured ***

Oto przykład przyzwoitej diefunkcji do śledzenia błędów w średnio skomplikowanych skryptach:

{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'

Dla bardziej zaawansowanych debugowania dostępne są rozszerzone funkcje debugowania Bash oraz szereg specjalnych parametrów, które dają więcej szczegółów niż osoba dzwoniąca (np BASH_ARG{C,V}.). Narzędzia takie jak Bashdb mogą pomóc w korzystaniu z niektórych bardziej zaawansowanych funkcji debugowania Bash.

kenorb
źródło
2

Jest to wbudowane polecenie powłoki: man bash(Następnie wyszukaj „caller”).
Może być użyte do wydrukowania śladu stosu.

smoking
źródło
Dzięki, że wybrałem odpowiedź enzotiba, ponieważ nauczył mnie również „pisania”. Bardzo dziękuję :)
0

Zauważ, że możesz readwyprowadzać dane wyjściowe callerna zmienne, aby kontrolować sposób formatowania danych wyjściowych:

stacktrace() {
  local frame=0 LINE SUB FILE
  while read LINE SUB FILE < <(caller "$frame"); do
    echo "${SUB} @ ${FILE}:${LINE}"
    ((frame++))
  done
}

Próbny:

$ cat /tmp/caller.sh 
#!/bin/bash

stacktrace() {
  local frame=0 LINE SUB FILE
  while read LINE SUB FILE < <(caller "$frame"); do
    printf '  %s @ %s:%s' "${SUB}" "${FILE}" "${LINE}"
    ((frame++))
  done
}

die() {
  echo "$*"
  stacktrace
  exit 1
}

f1() { die "*** an error occured ***"; }
f2() { f1; }
f3() { f2; }

f3

$ bash /tmp/caller.sh
*** an error occured ***
  die @ /tmp/caller.sh:13
  f1 @ /tmp/caller.sh:17
  f2 @ /tmp/caller.sh:18
  f3 @ /tmp/caller.sh:19
  main @ /tmp/caller.sh:21
dimo414
źródło