1 This file is set.def, from which is created set.c.
2 It implements the "set" and "unset" builtins in Bash.
4 Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
6 This file is part of GNU Bash, the Bourne Again SHell.
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 1, or (at your option) any later
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING. If not, write to the Free Software
20 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include "bashgetopt.h"
30 extern int interactive;
31 extern int noclobber, no_brace_expansion, posixly_correct;
32 #if defined (READLINE)
33 extern int rl_editing_mode, no_line_editing;
36 #define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
40 $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
41 -a Mark variables which are modified or created for export.
42 -b Notify of job termination immediately.
43 -e Exit immediately if a command exits with a non-zero status.
44 -f Disable file name generation (globbing).
45 -h Locate and remember function commands as functions are
46 defined. Function commands are normally looked up when
47 the function is executed.
48 -i Force the shell to be an "interactive" one. Interactive shells
49 always read `~/.bashrc' on startup.
50 -k All keyword arguments are placed in the environment for a
51 command, not just those that precede the command name.
52 -m Job control is enabled.
53 -n Read commands but do not execute them.
55 Set the variable corresponding to option-name:
57 braceexpand the shell will perform brace expansion
58 #if defined (READLINE)
59 emacs use an emacs-style line editing interface
62 #if defined (BANG_HISTORY)
64 #endif /* BANG_HISTORY */
65 ignoreeof the shell will not exit upon reading EOF
67 allow comments to appear in interactive commands
69 noclobber disallow redirection to existing files
76 posix change the behavior of bash where the default
77 operation differs from the 1003.2 standard to
81 #if defined (READLINE)
82 vi use a vi-style line editing interface
85 -p Turned on whenever the real and effective user ids do not match.
86 Disables processing of the $ENV file and importing of shell
87 functions. Turning this option off causes the effective uid and
88 gid to be set to the real uid and gid.
89 -t Exit after reading and executing one command.
90 -u Treat unset variables as an error when substituting.
91 -v Print shell input lines as they are read.
92 -x Print commands and their arguments as they are executed.
93 -l Save and restore the binding of the NAME in a FOR command.
94 -d Disable the hashing of commands that are looked up for execution.
95 Normally, commands are remembered in a hash table, and once
96 found, do not have to be looked up again.
97 #if defined (BANG_HISTORY)
98 -H Enable ! style history substitution. This flag is on
100 #endif /* BANG_HISTORY */
101 -C If set, disallow existing regular files to be overwritten
102 by redirection of output.
103 -P If set, do not follow symbolic links when executing commands
104 such as cd which change the current directory.
106 Using + rather than - causes these flags to be turned off. The
107 flags can also be used upon invocation of the shell. The current
108 set of flags may be found in $-. The remaining n ARGs are positional
109 parameters and are assigned, in order, to $1, $2, .. $n. If no
110 ARGs are given, all shell variables are printed.
113 /* An a-list used to match long options for set -o to the corresponding
119 { "allexport", 'a' },
121 #if defined (BANG_HISTORY)
122 { "histexpand", 'H' },
123 #endif /* BANG_HISTORY */
128 #if defined (JOB_CONTROL)
130 #endif /* JOB_CONTROL */
133 {"privileged", 'p' },
139 #define MINUS_O_FORMAT "%-15s\t%s\n"
145 char *on = "on", *off = "off";
147 printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
148 printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
150 if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
151 printf (MINUS_O_FORMAT, "ignoreeof", on);
153 printf (MINUS_O_FORMAT, "ignoreeof", off);
155 printf (MINUS_O_FORMAT, "interactive-comments",
156 interactive_comments ? on : off);
158 printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
160 #if defined (READLINE)
163 printf (MINUS_O_FORMAT, "emacs", off);
164 printf (MINUS_O_FORMAT, "vi", off);
168 /* Magic. This code `knows' how readline handles rl_editing_mode. */
169 printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
170 printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
172 #endif /* READLINE */
174 for (i = 0; o_options[i].name; i++)
176 int *on_or_off, zero = 0;
178 on_or_off = find_flag (o_options[i].letter);
179 if (on_or_off == FLAG_UNKNOWN)
181 printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
185 set_minus_o_option (on_or_off, option_name)
189 int option_char = -1;
191 if (STREQ (option_name, "braceexpand"))
193 if (on_or_off == FLAG_ON)
194 no_brace_expansion = 0;
196 no_brace_expansion = 1;
198 else if (STREQ (option_name, "noclobber"))
200 if (on_or_off == FLAG_ON)
201 bind_variable ("noclobber", "");
203 unbind_variable ("noclobber");
204 stupidly_hack_special_variables ("noclobber");
206 else if (STREQ (option_name, "ignoreeof"))
208 unbind_variable ("ignoreeof");
209 unbind_variable ("IGNOREEOF");
210 if (on_or_off == FLAG_ON)
211 bind_variable ("IGNOREEOF", "10");
212 stupidly_hack_special_variables ("IGNOREEOF");
215 #if defined (READLINE)
216 else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
218 if (on_or_off == FLAG_ON)
220 rl_variable_bind ("editing-mode", option_name);
223 with_input_from_stdin ();
228 int isemacs = (rl_editing_mode == 1);
229 if ((isemacs && STREQ (option_name, "emacs")) ||
230 (!isemacs && STREQ (option_name, "vi")))
233 with_input_from_stream (stdin, "stdin");
237 builtin_error ("not in %s editing mode", option_name);
240 #endif /* READLINE */
241 else if (STREQ (option_name, "interactive-comments"))
242 interactive_comments = (on_or_off == FLAG_ON);
243 else if (STREQ (option_name, "posix"))
245 posixly_correct = (on_or_off == FLAG_ON);
246 unbind_variable ("POSIXLY_CORRECT");
247 unbind_variable ("POSIX_PEDANTIC");
248 if (on_or_off == FLAG_ON)
250 bind_variable ("POSIXLY_CORRECT", "");
251 stupidly_hack_special_variables ("POSIXLY_CORRECT");
257 for (i = 0; o_options[i].name; i++)
259 if (STREQ (option_name, o_options[i].name))
261 option_char = o_options[i].letter;
265 if (option_char == -1)
267 builtin_error ("%s: unknown option name", option_name);
268 return (EXECUTION_FAILURE);
270 if (change_flag (option_char, on_or_off) == FLAG_ERROR)
272 bad_option (option_name);
273 return (EXECUTION_FAILURE);
276 return (EXECUTION_SUCCESS);
279 /* Set some flags from the word values in the input list. If LIST is empty,
280 then print out the values of the variables instead. If LIST contains
281 non-flags, then set $1 - $9 to the successive words of LIST. */
285 int on_or_off, flag_name, force_assignment = 0;
291 vars = all_shell_variables ();
294 print_var_list (vars);
298 vars = all_shell_functions ();
301 print_var_list (vars);
305 return (EXECUTION_SUCCESS);
308 /* Check validity of flag arguments. */
309 if (*list->word->word == '-' || *list->word->word == '+')
312 WORD_LIST *save_list = list;
314 while (list && (arg = list->word->word))
318 if (arg[0] != '-' && arg[0] != '+')
321 /* `-' or `--' signifies end of flag arguments. */
323 (!arg[1] || (arg[1] == '-' && !arg[2])))
328 if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
331 s[0] = c; s[1] = '\0';
334 printf ("usage: %s\n", USAGE_STRING);
335 return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
343 /* Do the set command. While the list consists of words starting with
344 '-' or '+' treat them as flags, otherwise, start assigning them to
348 char *string = list->word->word;
350 /* If the argument is `--' or `-' then signal the end of the list
351 and remember the remaining arguments. */
352 if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
356 /* `set --' unsets the positional parameters. */
357 if (string[1] == '-')
358 force_assignment = 1;
360 /* Until told differently, the old shell behaviour of
361 `set - [arg ...]' being equivalent to `set +xv [arg ...]'
362 stands. Posix.2 says the behaviour is marked as obsolescent. */
365 change_flag ('x', '+');
366 change_flag ('v', '+');
372 if ((on_or_off = *string) &&
373 (on_or_off == '-' || on_or_off == '+'))
376 while (flag_name = string[i++])
378 if (flag_name == '?')
380 printf ("usage: %s\n", USAGE_STRING);
381 return (EXECUTION_SUCCESS);
383 else if (flag_name == 'o') /* -+o option-name */
392 list_minus_o_opts ();
396 option_name = opt->word->word;
398 if (!option_name || !*option_name || (*option_name == '-'))
400 list_minus_o_opts ();
403 list = list->next; /* Skip over option name. */
405 if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
406 return (EXECUTION_FAILURE);
410 if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
417 return (EXECUTION_FAILURE);
429 /* Assigning $1 ... $n */
430 if (list || force_assignment)
431 remember_args (list, 1);
432 return (EXECUTION_SUCCESS);
436 $FUNCTION unset_builtin
437 $SHORT_DOC unset [-f] [-v] [name ...]
438 For each NAME, remove the corresponding variable or function. Given
439 the `-v', unset will only act on variables. Given the `-f' flag,
440 unset will only act on functions. With neither flag, unset first
441 tries to unset a variable, and if that fails, then tries to unset a
442 function. Some variables (such as PATH and IFS) cannot be unset; also
449 int unset_function = 0, unset_variable = 0, opt;
453 reset_internal_getopt ();
454 while ((opt = internal_getopt (list, "fv")) != -1)
465 return (EXECUTION_FAILURE);
471 if (unset_function && unset_variable)
473 builtin_error ("cannot simultaneously unset a function and a variable");
474 return (EXECUTION_FAILURE);
479 name = list->word->word;
481 if (!unset_function &&
482 find_name_in_list (name, non_unsettable_vars) > -1)
484 builtin_error ("%s: cannot unset", name);
492 var = unset_function ? find_function (name) : find_variable (name);
494 /* Posix.2 says that unsetting readonly variables is an error. */
495 if (var && readonly_p (var))
497 builtin_error ("%s: cannot unset: readonly %s",
498 name, unset_function ? "function" : "variable");
504 /* Unless the -f option is supplied, the name refers to a
507 (name, unset_function ? shell_functions : shell_variables);
509 /* This is what Posix.2 draft 11+ says. ``If neither -f nor -v
510 is specified, the name refers to a variable; if a variable by
511 that name does not exist, a function by that name, if any,
513 if ((tem == -1) && !unset_function && !unset_variable)
514 tem = makunbound (name, shell_functions);
518 else if (!unset_function)
519 stupidly_hack_special_variables (name);
525 return (EXECUTION_FAILURE);
527 return (EXECUTION_SUCCESS);