bash trap Frage

XioniX

Blog Benutzer
Ich habe hier folgenden Code:

Bash:
#!/bin/bash

set -Eeuo pipefail
shopt -s inherit_errexit

trap 'catch' ERR

function catch () {
    echo "Trapped in Subshell #$BASH_SUBSHELL" >&2
    echo "BASH_LINENO: ${BASH_LINENO[@]}" >&2
    echo "BASH_SOURCE: ${BASH_SOURCE[@]}" >&2
    echo "FUNCNAME: ${FUNCNAME[@]}" >&2
    echo "------------------------" >&2
}

function sub_test () {
    bla
    echo "Should not print"
}

function main_test() {
   sub_test
   echo "Should not print as well"
}

echo "Choose case 1-3"
read c
case "$c" in
   1) main_test
      ;;
   2) J=$(main_test)
      ;;
   3) J=$($($($(main_test))))
      ;;
   *) echo "unknown_case!"
      ;;
esac

echo "Should also not print"

Als Output erhalte ich für die Fälle 1-3

Code:
$ bash ssftest.bash
Choose case 1-3
1
ssftest.bash: line 17: bla: command not found
Trapped in Subshell #0
BASH_LINENO: 17 22 29 0
BASH_SOURCE: ssftest.bash ssftest.bash ssftest.bash ssftest.bash
FUNCNAME: catch sub_test main_test main
------------------------
Code:
$ bash ssftest.bash
Choose case 1-3
2
ssftest.bash: line 17: bla: command not found
Trapped in Subshell #1
BASH_LINENO: 17 22 31 0
BASH_SOURCE: ssftest.bash ssftest.bash ssftest.bash ssftest.bash
FUNCNAME: catch sub_test main_test main
------------------------
Trapped in Subshell #0
BASH_LINENO: 31 0
BASH_SOURCE: ssftest.bash ssftest.bash
FUNCNAME: catch main
------------------------

Code:
$ bash ssftest.bash
Choose case 1-3
3
ssftest.bash: line 17: bla: command not found
Trapped in Subshell #4
BASH_LINENO: 17 22 33 0
BASH_SOURCE: ssftest.bash ssftest.bash ssftest.bash ssftest.bash
FUNCNAME: catch sub_test main_test main
------------------------
Trapped in Subshell #3
BASH_LINENO: 33 0
BASH_SOURCE: ssftest.bash ssftest.bash
FUNCNAME: catch main
------------------------
Trapped in Subshell #2
BASH_LINENO: 33 0
BASH_SOURCE: ssftest.bash ssftest.bash
FUNCNAME: catch main
------------------------
Trapped in Subshell #1
BASH_LINENO: 33 0
BASH_SOURCE: ssftest.bash ssftest.bash
FUNCNAME: catch main
------------------------
Trapped in Subshell #0
BASH_LINENO: 33 0
BASH_SOURCE: ssftest.bash ssftest.bash
FUNCNAME: catch main
------------------------

Wie verhindere ich im Fall 2&3, dass die Trap mehrfach aufgerufen wird?
  • Die 'set' und 'shopt' Optionen sollten beibehalten werden.
  • Einen Umweg über temporäre Dateien würd ich gern vermeiden.
Da der erste Aufruf bereits alle Informationen für einen Backtrace enthält, benötige ich die übrigen Calls nicht.
 

XioniX

Blog Benutzer
Schon probiert, allerdings wird dann das Skript weiter ausgeführt:

Code:
$ bash ssftest.bash
Choose case 1-3
3
ssftest.bash: line 20: bla: command not found
Trapped in Subshell #4
BASH_LINENO: 20 25 36 0
BASH_SOURCE: ssftest.bash ssftest.bash ssftest.bash ssftest.bash
FUNCNAME: catch sub_test main_test main
------------------------
Should also not print
 

DeaD_EyE

Blog Benutzer
Verwende einfach eine Sprache mit besserem Excpetion-Handling. Das hält doch kein Mensch aus!
Wahrscheinlich verhält sich Trap von shell zu shell auch noch unterschiedlich.
 

d4f

Kaffee? Wo?
Stimmt, ich bin für das generell mittlerweile vorinstallierte Python. Das "ask foregiveness, not permission" Modell ist genial Exception-orientiert so dass es im ganzen Stack nur davon hagelt. Exception-Freunde kommen so sicherlich auf ihren Genuss ... wenngleich etwas mehr als erwünscht.

Das Trap-Konzept stammt aus POSIX, ist aber wohl unklar formuliert. Ist halt keine DIN-Norm ;)

Imho ist "Shell" keine Sprache, höchstens meist äquivalent mit bash genau wie /bin/sh meistens /bin/bash entspricht. Theoretisch gibt es die Bourne-Shell "sh" aber ausser auf embedded-Devices mit Busybox-Umgebung ist mir die seit Jahren nicht mehr untergekommen. ksh unter AIX ist bereits schrecklich genug :p P
 

GwenDragon

Registered User
Wer unbedingt ne Shell will, bitte. Aber ehrlich, Exceptions abfangen ist da eine Selbstquälerei für IT-Nerds. Wer drauf steht…
Es gibt höhere Skriptsprachen dafür, die das besser, nachvollzienbarer können, Exceptions abfangen, nicht Quälen.
Bei mir erzeugt *sh nur ein Bild für das Geräusch wenn man was Grässliches wegscheuchen will.
 

XioniX

Blog Benutzer
Wer unbedingt ne Shell will, bitte. Aber ehrlich, Exceptions abfangen ist da eine Selbstquälerei für IT-Nerds. Wer drauf steht…
Es gibt höhere Skriptsprachen dafür, die das besser, nachvollzienbarer können, Exceptions abfangen, nicht Quälen.
Bei mir erzeugt *sh nur ein Bild für das Geräusch wenn man was Grässliches wegscheuchen will.

Ich hab das mittlerweile auch in Python am Ostermontag geschrieben. Dachte halt am Anfang, dass die bash dafür reicht, ist aber in der Tat zu unflexibel dafür.
 

marce

Well-Known Member
Die Wahl des richtigen Werkzeuges gehört schon seit Jahren zur Kernkompetenz (nicht nur) eines Informatikers.
 

d4f

Kaffee? Wo?
Die Wahl des richtigen Werkzeuges gehört schon seit Jahren zur Kernkompetenz (nicht nur) eines Informatikers.
und trotzdem werden viele Arbeitgeber Bash-Skripte zumindest in einigen Teilbereichen der Informatik verlangen, schlicht weil es der kleinte gemeinsame Nenner vieler Betriebssysteme und Administratoren ist. Sofern die Systeme am Internet hängen sind die bash-lib übrigens eine sehr gute Basis für vereinfachten Aufbau.
 

marce

Well-Known Member
Klar. Und völlig berechtigt. Aber es gibt nunmal Dinge, die würde ich im Traum nicht mit einem Bash-Script erledigen und auch niemand würde fordern, daß dies mit einem Bash-Script umgesetzt würde (außer evtl. im Rahmen einer Übung :) )

... dann wiederum gibt es Dinge, die man völlig problemlos mit einem Bash-Script erledigen kann und wo das auch das angesagte Mittel der Wahl ist, ohne daß man gleich mit irgendwelchen Hochsprachen um's Eck kommem muss, deren jeweilige Portabilität sich auch immer noch erst erweisen muss.
 
Top