4

Say I connected to a Linux system as root.

What exactly happens when I type unset *?

Lunartist
  • 375
  • 2
  • 13

1 Answers1

13

I will assume that your shell is Bash, although the following should apply to most Bourne/POSIX-like shells as well.

In short, the command doesn't make sense.

The shell will first replace the asterisk * by the names of all files and directories in the current directory, except those that start with a dot .. Then it will call the unset command on that list.

The purpose of unset is to remove shell variables, not to process files. If a file or directory name happens to correspond to a currently defined shell variable, that variable will be removed. Names that don't correspond to a shell variable will either have no effect at all, or if they contain characters that are illegal for shell variables, they will generate an error message like not a valid identifier.

In reality, the unset command is a bit more complex; for example, variables can be marked as readonly, in which case they can't be unset. It also works with functions, not just variables. However, this doesn't change anything to the summary that the command doesn't make sense in normal situations.

Also, as Stéphane Chazelas' commented, like all builtins that take variable names, unset has potentially dangerous side effects, mostly with data that looks like array indexing. E.g. if a file HOME[$(some command)] existed, unset * would run the command substitution when trying to evaluate the array index. See: Security Implications of using unsanitized data in Shell Arithmetic evaluation

ilkkachu
  • 133,243
  • 15
  • 236
  • 397
berndbausch
  • 3,477
  • 2
  • 15
  • 21
  • 4
    If there was a file called `HOME[$(reboot)]` in the current directory, `unset *` could also attempt to reboot the system. `unset` in `bash` and other Korn-like shells is one of those builtins that can ran arbitrary commands, so should only be passed known and sanitised data. – Stéphane Chazelas Feb 18 '21 at 07:25
  • @StéphaneChazelas That's interesting, but I don't find anything in the Bash reference manual. Does the shell perform command substitution after expanding the asterisk? But then that would apply to any use of wildcards, not just with `unset`. Any pointers? Yes I know this could derail the discussion of the original question. – berndbausch Feb 18 '21 at 07:59
  • 3
    That's to do with the arithmetic evaluation in array indices. So any builtin that takes a variable name as argument (`[ -v var ]`, `getopts`, `read`, `printf -v`...) has a problem. See [Security Implications of using unsanitized data in Shell Arithmetic evaluation](//unix.stackexchange.com/q/172103) – Stéphane Chazelas Feb 18 '21 at 08:35
  • @berndbausch, it's not exactly clearly put, but e.g. Bash's manual says that [indexes of (regular, non-associative) arrays are arithmetic expressions](https://www.gnu.org/software/bash/manual/html_node/Arrays.html), and elsewhere that [tokens in an arithmetic expansion go through various substitutions, incl. command substitution](https://www.gnu.org/software/bash/manual/html_node/Arithmetic-Expansion.html). – ilkkachu Feb 18 '21 at 13:25
  • (There is a slight question about the difference between an arithmetic _expression_ and _expansion_ -- the arrays page only uses the former phrase, and refers [Shell Arithmetic](https://www.gnu.org/software/bash/manual/html_node/Shell-Arithmetic.html), which only mentions that _parameter expansion_ is done inside an arithmetic expression, with no reference to other expansions, so one could argue that the manual is unclear enough to be wrong.) – ilkkachu Feb 18 '21 at 13:27
  • 4
    one learns more by answering questions than by asking them. Thanks. – berndbausch Feb 18 '21 at 14:21