2

I have a line in my .zshrc that says:

set env $PATH

Apparently this affects the value of $@. I have read that $@ should be empty and that I should not have any set statements in my .zshrc (at least in Bash some of these statements should actually go in my .inputrcfile).

Is this valid advice, if so why? What does set env $PATH do and why should $@ be empty?

1 Answers1

6

You misread that comment.

In Bourne-style shells such as bash and zsh, the command set is a builtin which does two things:

  • it sets shell options, e.g. set -x turns on the xtrace (print debugging traces) option;
  • when called with non-option arguments, it sets the positional parameters ($1, $2, …, collectively accessed as "$@").
  • As an exception, if the option -A or +A is passed, set assigns to the specified array instead of to the positional parameters.

The command set env $PATH sets the positional parameters to a list of two: env, and the value of the PATH variable. This is not useful.

Calls to set with non-option arguments are only useful inside functions and scripts, not in .zshrc. While you may have calls to set with options, most useful options are set through setopt.

.inputrc is a configuration file for bash and a few other programs that use the readline library. It mainly contains key bindings, and a few option settings of the form set SETTING VALUE (but there is no setting called env). These options are all related to command line editing. Zsh does not use readline, so .inputrc is not relevant to zsh.

I don't know what you were trying to do with the line set env $PATH. If you wanted to export PATH to the environment, the syntax is export PATH; however:

  • PATH is already exported, there is no need to call export again even if you modify the value (exporting a modified environment variable was only needed in the old Bourne shell).
  • You should not modify environment variables in .zshrc, as this file is read by all interactive shells. A variable set in .zshrc would override anything set by the calling program, and would only affect programs started through that shell. The right place to set your environment variables is in ~/.profile, ~/.zprofile, ~/.pam_environment, or other files that are read at the start of your session. See Is there a ".bashrc" equivalent file read by all shells? and the linked posts.

If you want to change the path, you need to assign to it:

PATH=/completely/new:/value/of/PATH
PATH=/directory/to/add/at/the/beginning:$PATH
PATH=$PATH:/directory/to/add/at/the/end

Zsh (like (t)csh where it copied it from) provides a variable called path (all lowercase) which is an array containing the same list of directories as PATH. Any update to PATH automatically affects path and vice versa. So instead of manipulating PATH, you can do things like

path=(/completely/new /value/of/PATH)
path=(/directory/to/add/at/the/beginning $path)
path+=/directory/to/add/at/the/end
path+=(/one/more /and/another)