TODO #!/usr/bin/env bash # Provides an "atexit" mechanism for scripts. # Array of commands to eval. declare -a __atexit_cmds = '' # Helper for eval'ing commands. proc __atexit { for cmd in [$(__atexit_cmds[@])] { eval $(cmd) } } # Usage: atexit command arg1 arg2 arg3 proc atexit { # Determine the current number of commands. var length = $(#__atexit_cmds[*]) # Add this command to the end. __atexit_cmds[$(length)]="$(*)" # Set the trap handler if this was the first command added. if [[ ${length} -eq 0 ]] { trap __atexit EXIT } } (CommandList children: [ (Assignment keyword: Assign_Declare flags: ["'-a'"] pairs: [(assign_pair lhs:(LhsName name:__atexit_cmds) op:Equal spids:[15])] spids: [11] ) (FuncDef name: __atexit body: (BraceGroup children: [ (ForEach iter_name: cmd iter_words: [ { (DQ (BracedVarSub token: bracket_op: (WholeArray op_id:Lit_At) spids: [35 40] ) ) } ] do_arg_iter: False body: (DoGroup children:[(C {(eval)} {(${ VSub_Name cmd)})] spids:[4454]) spids: [33 42] ) ] spids: [25] ) spids: [21 24] ) (FuncDef name: atexit body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:length) op: Equal rhs: { (BracedVarSub token: prefix_op: VSub_Pound bracket_op: (WholeArray op_id:Arith_Star) spids: [76 82] ) } spids: [75] ) ] spids: [73] ) (C {(__atexit_cmds) (Lit_Other "[") (${ VSub_Name length) (Lit_Other "]") (Lit_Other "=") (DQ (${ VSub_Star "*")) } ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_eq left: {(${ VSub_Name length)} right: {(0)} ) ) terminator: ) ] action: [(C {(trap)} {(__atexit)} {(EXIT)})] spids: [-1 124] ) ] spids: [-1 134] ) ] spids: [66] ) spids: [62 65] ) ] )