diff --git a/doc/bash.1 b/doc/bash.1 index 5af7d42..33ba307 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -2112,6 +2112,12 @@ minimum, and there is a maximum value (currently 8192) that this may not exceed. The minimum value is system-dependent. .TP +.B CMD +Is set before a command is run, each array field corresponds to one argument +of the command line. It is intended to be used in PREEXEC_COMMAND scripts. +In case of pipe-commands the command line of the last command in the +pipe-chain is stored in CMD. +.TP .B COLUMNS Used by the \fBselect\fP compound command to determine the terminal width when printing selection lists. @@ -2476,6 +2482,13 @@ had been executed. When the shell enters \fIposix mode\fP, it sets this variable if it was not already set. .TP +.B PREEXEC_COMMAND +If this variable is set, and is an array, +the value of each set element is executed as a command +prior to issuing each entered commands in interactive mode. +If this is set but not an array variable, +its value is used as a command to execute instead. +.TP .B PROMPT_COMMAND If this variable is set, and is an array, the value of each set element is executed as a command diff --git a/doc/bashref.texi b/doc/bashref.texi index 9e23f58..3103f57 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -5595,6 +5595,12 @@ In some cases, Bash assigns a default value to the variable. A colon-separated list of directories used as a search path for the @code{cd} builtin command. +@item CMD +Is set before a command is run, each array field corresponds to one argument +of the command line. It is intended to be used in @env{PREEXEC_COMMAND} scripts. +In case of pipe-commands the command line of the last command in the +pipe-chain is stored in @env{CMD}. + @item HOME The current user's home directory; the default for the @code{cd} builtin command. @@ -6289,6 +6295,13 @@ not already set. The process @sc{id} of the shell's parent process. This variable is readonly. +@item PREEXEC_COMMAND +If this variable is set, and is an array, +the value of each set element is executed as a command +prior to issuing each entered commands in interactive mode. +If this is set but not an array variable, +its value is used as a command to execute instead. + @item PROMPT_COMMAND If this variable is set, and is an array, the value of each set element is interpreted as a command to execute diff --git a/eval.c b/eval.c index 1d967da..97002bd 100644 --- a/eval.c +++ b/eval.c @@ -50,6 +50,8 @@ static void send_pwd_to_eterm PARAMS((void)); static sighandler alrm_catcher PARAMS((int)); +static void process_variable_command PARAMS((char *)); +static void export_command PARAMS((COMMAND *)); /* Read and execute commands until EOF is reached. This assumes that the input source has already been initialized. */ @@ -165,6 +167,8 @@ reader_loop () current_command_number++; executing = 1; + export_command (current_command); + process_variable_command ("PREEXEC_COMMAND"); stdin_redir = 0; execute_command (current_command); @@ -287,31 +291,31 @@ execute_array_command (a, v) #endif static void -execute_prompt_command () +process_variable_command (char *varname) { char *command_to_execute; - SHELL_VAR *pcv; + SHELL_VAR *cv; #if defined (ARRAY_VARS) ARRAY *pcmds; #endif - pcv = find_variable ("PROMPT_COMMAND"); - if (pcv == 0 || var_isset (pcv) == 0 || invisible_p (pcv)) + cv = find_variable (varname); + if (cv == 0 || var_isset (cv) == 0 || invisible_p (cv)) return; #if defined (ARRAY_VARS) - if (array_p (pcv)) + if (array_p (cv)) { - if ((pcmds = array_cell (pcv)) && array_num_elements (pcmds) > 0) - execute_array_command (pcmds, "PROMPT_COMMAND"); + if ((pcmds = array_cell (cv)) && array_num_elements (pcmds) > 0) + execute_array_command (pcmds, varname); return; } - else if (assoc_p (pcv)) + else if (assoc_p (cv)) return; /* currently don't allow associative arrays here */ #endif - command_to_execute = value_cell (pcv); + command_to_execute = value_cell (cv); if (command_to_execute && *command_to_execute) - execute_variable_command (command_to_execute, "PROMPT_COMMAND"); + execute_variable_command (command_to_execute, varname); } /* Call the YACC-generated parser and return the status of the parse. @@ -337,7 +341,7 @@ parse_command () #if defined (READLINE) if (no_line_editing || (bash_input.type == st_stdin && parser_will_prompt ())) #endif - execute_prompt_command (); + process_variable_command ("PROMPT_COMMAND"); if (running_under_emacs == 2) send_pwd_to_eterm (); /* Yuck */ @@ -351,7 +355,6 @@ parse_command () return (r); } - /* Read and parse a command, returning the status of the parse. The command is left in the globval variable GLOBAL_COMMAND for use by reader_loop. This is where the shell timeout code is executed. */ @@ -398,3 +401,44 @@ read_command () return (result); } + +/* export_command makes an array "CMD" and fills its fields + with the command line of "command" (only for cm_simple, + for cm_connection the last command in the chain is used */ + +void +export_command (COMMAND *command) +{ + int i = 0; + SHELL_VAR *cmd_var; + ARRAY *cmd_array; + WORD_LIST *list; + + if (command->type == cm_simple) + list = command->value.Simple->words; + else if (command->type == cm_connection) + { + if (!command->value.Connection->second) + return; + while (command->type == cm_connection) + command = command->value.Connection->second; + if (command->type == cm_simple) + list = command->value.Simple->words; + else + return; + } + else + return; + + cmd_var = make_new_array_variable ("CMD"); + cmd_array = array_cell (cmd_var); + + while (list) + { + array_insert (cmd_array, i, list->word->word); + list=list->next; + i++; + } + + VSETATTR (cmd_var, (att_exported)); +}