blob: a41fcf43e05530ca50698d01c967775cb378b089 [file] [log] [blame]
Michael Walsh4d942992018-02-15 17:18:54 -06001#!/usr/bin/wish
2
3# This file provides shell command procedures cmd_fnc and t_cmd_fnc.
4
5my_source [list print.tcl]
6
7
8proc cmd_fnc { cmd_buf { quiet {} } { test_mode {} } { print_output {} }\
9 { show_err {} } { ignore_err {} } { acceptable_shell_rcs {} } } {
10
11 # Run the given command in a shell and return the shell return code and the
12 # output as a 2 element list.
13
14 # Example usage:
15 # set result [cmd_fnc "date"].
16
17 # Example output:
18
19 # #(CST) 2018/01/17 16:23:28.951643 - 0.001086 - Issuing: date
20 # Mon Feb 19 10:12:10 CST 2018
21 # result:
22 # result[0]: 0x00000000
23 # result[1]: Mon Feb 19 10:12:10 CST
24 # 2018
25
26 # Note: Because of the way this procedure processes parms, the user can
27 # specify blank values as a way of skipping parms. In the following
28 # example, the caller is indicating that they wish to have quiet and
29 # test_mode take their normal defaults but have print_output be 0.:
30 # cmd_fnc "date" "" "" 0
31
32 # Description of argument(s):
33 # cmd_buf The command string to be run in a shell.
34 # quiet Indicates whether this procedure should
35 # run the print_issuing() procedure which
36 # prints "Issuing: <cmd string>" to stdout.
37 # The default value is 0.
38 # test_mode If test_mode is set, this procedure will
39 # not actually run the command. If
40 # print_output is set, it will print
41 # "(test_mode) Issuing: <cmd string>" to
42 # stdout. The default value is 0.
43 # print_output If this is set, this procedure will print
44 # the stdout/stderr generated by the shell
45 # command. The default value is 1.
46 # show_err If show_err is set, this procedure will
47 # print a standardized error report if the
48 # shell command returns non-zero. The
49 # default value is 1.
50 # ignore_err If ignore_err is set, this procedure will
51 # not fail if the shell command fails.
52 # However, if ignore_err is not set, this
53 # procedure will exit 1 if the shell command
54 # fails. The default value is 1.
55 # acceptable_shell_rcs A list of acceptable shell rcs. If the
56 # shell return code is found in this list,
57 # the shell command is considered
58 # successful. The default value is {0}.
59
60 # Set defaults.
61 set_var_default quiet [get_stack_var quiet 0 2]
62 set_var_default test_mode 0
63 set_var_default print_output 1
64 set_var_default show_err 1
65 set_var_default ignore_err 1
66 set_var_default acceptable_shell_rcs 0
67
68 qpissuing $cmd_buf $test_mode
69
70 if { $test_mode } { return [list 0 ""] }
71
72 set shell_rc 0
73
74 if { [ catch {set out_buf [eval exec bash -c {$cmd_buf}]} result ] } {
75 set out_buf $result
76 set shell_rc [lindex $::errorCode 2]
77 }
78
79 if { $print_output } { puts "${out_buf}" }
80
81 # Check whether return code is acceptable.
82 if { [lsearch -exact $acceptable_shell_rcs ${shell_rc}] == -1 } {
83 # The command failed.
84 append error_message "The prior shell command failed.\n"
85 append error_message [sprint_var shell_rc "" "" 1]
86 if { $acceptable_shell_rcs != 0 } {
87 # acceptable_shell_rcs contains more than just a single element equal
88 # to 0.
89 append error_message "\n"
90 append error_message [sprint_list acceptable_shell_rcs "" "" 1]
91 }
92 if { ! $print_output } {
93 append error_message "out_buf:\n${out_buf}"
94 }
95 if { $show_err } {
96 print_error_report $error_message
97 }
98
99 if { ! $ignore_err } {
100 exit 1
101 }
102
103 }
104
105 return [list $shell_rc $out_buf]
106
107}
108
109
110proc t_cmd_fnc { args } {
111
Michael Walsh50146212018-02-22 12:15:34 -0600112 # Call cmd_fnc with test_mode equal to the test_mode setting found by
113 # searching up the call stack. See cmd_fnc (above) for details for all
114 # other arguments.
Michael Walsh4d942992018-02-15 17:18:54 -0600115
Michael Walsh50146212018-02-22 12:15:34 -0600116 # We wish to obtain a value for test_mode by searching up the call stack.
117 # This value will govern whether the command specified actually gets
118 # executed.
Michael Walsh4d942992018-02-15 17:18:54 -0600119 set_var_default test_mode [get_stack_var test_mode 0 2]
Michael Walsh50146212018-02-22 12:15:34 -0600120
121 # Since we wish to manipulate the value of test_mode, which is the third
122 # positional parm, we must make sure we have at least 3 parms. We will now
123 # append blank values to the args list as needed to ensure that we have the
124 # minimum 3 parms.
125 set min_args 3
126 for {set ix [llength $args]} {$ix < $min_args} {incr ix} {
127 lappend args {}
128 }
129
130 # Now replace the caller's test_mode value with the value obtained from the
131 # call stack search. It does not matter what value is specified by the
132 # caller for test_mode. It will be replaced. The whole point of calling
133 # t_cmd_fnc is to allow it to set the test_mode.
Michael Walsh4d942992018-02-15 17:18:54 -0600134 set args [lreplace $args 2 2 $test_mode]
135
136 return [cmd_fnc {*}$args]
137
138}