30

What does set command without arguments do?

As I can see it prints out my environment variables just like env command but in alphabetical order. And further it prints some different information (variables? functions?) like:

__git_printf_supports_v=yes
__grub_script_check_program=grub-script-check
...
quote () 
{ 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}
quote_readline () 
{ 
    local quoted;
    _quote_readline_by_ref "$1" ret;
    printf %s "$ret"
}

What is it and where does it come from?

I cannot find information about set command without arguments. Actually I don't have a man page for set in my Linux distribution at all.

JMW
  • 131
  • 6
Aleksandr Kovalev
  • 403
  • 1
  • 4
  • 7
  • 1
    "This builtin is so complicated that it deserves its own section." See [the docs](https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html) – galath Feb 17 '17 at 10:16

5 Answers5

22

set is a shell built-in that displays all shell variables, not only the environment ones, and also shell functions, which is what you are seeing at the end of the list.

Variables are displayed with a syntax that allow them to be set when the lines are executed or sourced.

From bash manual page:

If no options or arguments are supplied, set displays the names and values of all shell variables and functions, sorted according to the current locale, in a format that may be reused as input for setting or resetting the currently-set variables.

On different shells, the behavior is not necessarily the same; for example, ksh set doesn't display shell functions.

Jeff Schaller
  • 66,199
  • 35
  • 114
  • 250
jlliagre
  • 60,319
  • 10
  • 115
  • 157
11

set is a shell builtin, used to set and unset shell options and positional parameters.

Without arguments, set will print all shell variables (both environment variables and variables in current session) sorted in current locale.

You can also read bash documentation.


There're a few caveats.

set "$var" will assign var value to $1. If $var starts with - or +, then $var content will be treated as sequences of shell options. If $var contains any invalid options, most POSIX shells will print the error. yash and zsh in sh, ksh emulation are not only printing the error, but also setting valid options. While yash stops setting options on the first invalid option, zsh will assign all of them. In yash:

var=-fxd; set "$var"

f and x will be present in $-, while:

var=fdx; set "$var"

only f is present in $-. In both cases, f and x will be present in $- with zsh in sh and ksh emulation.

To protect you from that situation, you can pass -- as the first argument to set a positional parameter even if it starts with - or +:

var=-fdx; set -- "$var"

will assign $var to $1, regardless of its content.

set -- without any further arguments will unset all positional parameters.

If the first argument is -, the behavior is unspecified. All known POSIX shells will unset x and v options (except posh), and assign anything after - to positional parameters:

set -xv - -f

will assign -f to $1. set - also did not unset positional parameters. Schily osh also behaves like that. Heirloom sh does not unset v and x options.

The only POSIX shell exception is yash, which treats - as the first positional parameter:

$ yash -c 'set -xv - -f; printf "%s\n" "$@"; printf "%s\n" "$-"'
+ printf %s\n - -f
-
-f
+ printf %s\n cvx
cvx

Schily sh even doing nothing if - is present in arguments:

$ schily-sh -c 'set -v - -f; printf "%s\n" "$@"; printf "%s\n" "$-"'
<blank line>
s

$ schily-sh -c 'set -v -- -f; printf "%s\n" "$@"; printf "%s\n" "$-"'
-f
vs
JMW
  • 131
  • 6
cuonglm
  • 150,973
  • 38
  • 327
  • 406
  • i never understand why people would link to anywhere but the first one... you might like to mention the different between `set -- $unset`, `set - $unset`, `set $unset`, and `set "$unset"` and so on - it's usually those discrepancies that get people into that kind of trouble in the first place. – mikeserv Jan 15 '16 at 19:02
  • @mikeserv: Well, I added further details, but I didn't got what do you mean when used `$unset`. – cuonglm Jan 16 '16 at 03:27
  • @cuonglm The command `set $unset` will act exactly equal as `set` for an unset variable. But `set "$unset"` will do noting, if `unset` is actually an unset variable. A `set - $unset` removes the `-v` and `-x` set options (in bash). –  Jan 16 '16 at 08:41
  • @BinaryZebra: Ah, of course, for me, it's better to use `unset_var`. And also note that `set "$unset"` is actually set `$1` to empty. That's about shell expansion, not strictly to `set`, so I don't mention it. – cuonglm Jan 16 '16 at 09:50
  • @mikeserv: Ah right, updated answer. Actually, I mean in case of treating arguments after `-`. – cuonglm Jan 16 '16 at 16:30
  • 1
    @mikeserv: The behavior of `posh` and `yash` are different when `-` appear. You can read my updated (and feel free to improve it). – cuonglm Jan 16 '16 at 17:42
  • yeah - `yash` is a wildcard. – mikeserv Jan 16 '16 at 17:44
8

Because set has output and which set returns nothing you know it's part of the shell you are using, likely bash.

man bash mentions it many times but it's easier to link to in the online documentation.

This builtin is so complicated that it deserves its own section. set allows you to change the values of shell options and set the positional parameters, or to display the names and values of shell variables.

set has the call specification of:

set [--abefhkmnptuvxBCEHPT] [-o option-name] [argument …]
set [+abefhkmnptuvxBCEHPT] [+o option-name] [argument …]

so if you want to find it in man on the command line you can search with

/set.*abef
user1133275
  • 5,488
  • 1
  • 19
  • 37
  • `which set` depends on your shell. At least `zsh` will report it for you. You can also read [this](http://unix.stackexchange.com/q/85249/38906) for more details. – cuonglm Jan 16 '16 at 03:50
  • It's unlikely the question is about anything but bash as it has a large market dominance, and anyone using the non default shell would not need to ask this question. – user1133275 Jan 17 '16 at 04:56
3

If you are working inside a bash shell, type help set.

At the end of the help printed, read:

If no ARGs are given, all shell variables are printed.

So, a no arguments set prints all variables known to the shell.

0

I cannot find information about set command without arguments. Actually I don't have a man page for set in my Linux distribution at all.

Actually since set is builtin bash itself, you have access bash's help manual instead of man page. For that you can use help or in this case help set.