What is a good default PATH to use if none is defined by the environment? [closed] - shell

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 9 years ago.
Improve this question
I'm making a small shell for a school project and I was searching about default PATHs. Say there is no PATH in the global environ variable, the various shells I tested always managed to search some default paths (sometimes unknown) to find the executable to run [ls is chosen as an example]:
Bash Shell behaves like so:
dflt-zsh > env -i bash
bash-3.2$ echo $PATH
/usr/gnu/bin:/usr/local/bin:/bin:/usr/bin:.
bash-3.2$ ls
Makefile shell.c src includes
bash-3.2$ export PATH=
bash-3.2$ ls
bash: ls: No such file or directory
C Shell seems to be lost when no PATH is defined but found the ls executable nonetheless:
dflt-zsh > env -i csh
% echo $PATH
PATH: Undefined variable.
% ls
Makefile shell.c src includes
Z Shell has the most elements in $PATH but it may be reading some of my default zsh configuration files (not very trustworthy example):
dflt-zsh > env -i zsh
achedeuzot% echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/texbin
achedeuzot% ls
Makefile shell.c src includes
achedeuzot% PATH=
achedeuzot% ls
zsh: command not found: ls
TC Shell behaves as C shell.
dflt-zsh > env -i tcsh
> echo $PATH
PATH: Undefined variable.
> ls
Makefile shell.c src includes
What is a good "default PATH" to search even if none is set ? I was going for something along the lines of PATH=/usr/local/bin:/bin:/usr/bin:.
How can I choose which directories to include by default ? Are there some crucial directories to search ? Main question: Is it "choose what you like" or are there any basic rules that all the shells follow ?
Thanks for your help !

There is no universal solution. On some systems, /bin is a symlink to /usr/bin, so adding just /usr/bin to PATH will get you most of the programs. Adding /usr/gnu/bin or /usr/local/bin is optional; not all systems have either or both of those. Sometimes people add /sbin and /usr/sbin. The list of variations goes on. The basic, minimal PATH setting is usually:
/bin:/usr/bin
Anything extra is precisely that — extra. (And, as noted, on some systems, that is not a minimal PATH.)

Related

In macOS, how can I get the manual (man) page of the original (BSD) command when I have installed a GNU alternative? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
So I have installed GNU coreutils like so : brew install coreutils
Now I have 2 versions of my core utilities.
For example :
$>which -a stat
/usr/local/opt/coreutils/libexec/gnubin/stat
/usr/bin/stat
/usr/local/opt/coreutils/libexec/gnubin/stat is the GNU version that will be executed if I simply invoke stat And if I invoke man stat I will get the manual for that specific version.
Now my question is how can I look at the manual for the /usr/bin/stat version?
Use man -wa to list all paths, then use the specific man page you want as the argument to man.
$ man -wa stat
/usr/share/man/man1/stat.1
[some Xcode cruft deleted]
$ man /usr/share/man/man1/stat.1
Assuming you already knew that the page you wanted was in /usr/share/man, (or having learned that by running the previous command), you can use the -M option to override man's usual search.
$ man -M /usr/share/man stat
In order to retrieve a man page it must be found in the manpath. The directories that are listed by the manpath are set by /etc/manpath.config. This can be overwritten via an environment variable $MANPATH. If the man page you are looking for is in this path already, then you should see a listing like the following:
stat (1)
stat (2)
stat (3p)
stat (3p+2)
That (3p+2) represents a duplicated entry. Since you believe you have two different man pages, you should see something like this. If not, then the man page you want either does not exist on your system, or is outside of the manpath. You can specify a custom manpath with the -M option. This will override the $MANPATH variable. From the man man:
-M path, --manpath=path
Specify an alternate manpath to use. By default, man uses manpath derived code to determine the path to search. This option overrides the $MANPATH environment variable and causes option -m to be ignored.
A path specified as a manpath must be the root of a manual page hierarchy structured into sections as described in the man-db manual (under "The manual page system"). To view manual pages outside such hierarchies, see the -l option.

Oh-My-ZSH PATH has locations that aren't in .zshrc but are still in path upon echo [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
EDIT:
I have now deleted the $HOME/bin:/usr/local/bin: portion from line 1 of my .zshrc file. So now that line reads as export PATH=$PATH. This got rid of the duplicates, but it still doesnt explain where Mono and Postgres are being added to the path.
Here is what the path outputs in readable formatting:
/usr/local/bin:
/usr/bin:
/bin:
/usr/sbin:
/sbin:
/Library/Frameworks/Mono.framework/Versions/Current/Commands:
/Applications/Postgres.app/Contents/Versions/latest/bin
Is there another file that is handling the exportation of these paths?
ORIGINAL:
So I really couldn't come up with a very good title, so if anyone has any suggestions please leave them in the comments.
So heres my problem. I just reset my .zshrc file to the default template by using the following command.
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
So here is my file contents for .zshrc
export PATH=$HOME/bin:/usr/local/bin:$PATH
export ZSH=$HOME/.oh-my-zsh
ZSH_THEME="agnoster"
plugins=(
git
)
source $ZSH/oh-my-zsh.sh
The following files are either completely empty or have everything commented out: .zprofile, .bash_profile, .bashrc.
After running the source .zshrc command in my terminal followed by the echo $PATH command, this is my output.
/Users/jrobinson/bin:/usr/local/bin:/Users/jrobinson/bin:/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Frameworks/Mono.framework/Versions/Current/Commands:/Applications/Postgres.app/Contents/Versions/latest/bin
Let's format this a little better so we can see what's going on:
/Users/jrobinson/bin:
/usr/local/bin:
/Users/jrobinson/bin:
/usr/local/bin:
/usr/local/bin:
/usr/bin:
/bin:
/usr/sbin:
/sbin:
/Library/Frameworks/Mono.framework/Versions/Current/Commands:
/Applications/Postgres.app/Contents/Versions/latest/bin
As you can see, some things are repeating such as /usr/local/bin & /Users/jrobinson/bin.
Also I had at one point Postgres installed on my computer, but no longer have it installed. Mono I still have and use, but I have no idea where it's being added to my path.
The only thing I'm defining in my path is: export PATH=$HOME/bin:/usr/local/bin:$PATH
So why am I getting these repeat things? I'm assuming it's because of some repeating code somewhere in some file, and I can't pin point where these repeats are occurring so I can delete them and clean up my PATH.
ALSO which is really weird, I have Composer installed on my computer as well, and I can use the composer command even though I haven't defined Composer in my path with /.composer/vendor/bin.
path_helper is a helper for constructing PATH environment variable. It's macOS exclusive.
man path_helper
Files in these directories should contain one path element per line.
Prior to reading these directories, default PATH and MANPATH values are
obtained from the files /etc/paths and /etc/manpaths respectively.
A GUI app could put files into these paths. When a shell starts up, values within will be added into PATH, or MANPATH by path_helper. The whole point seems to be avoiding polluting /usr/bin or /usr/local/bin by creating symlink into them.
For bash, path_helper is called in /etc/profile on shell startup. For zsh, path_helper is called in /etc/zprofile.
Content of /etc/profile:
# System-wide .profile for sh(1)
if [ -x /usr/libexec/path_helper ]; then
eval `/usr/libexec/path_helper -s`
fi
if [ "${BASH-no}" != "no" ]; then
[ -r /etc/bashrc ] && . /etc/bashrc
fi
path_helper -s
-s Generate Bourne shell commands on stdout. This is the default if
SHELL does not end with "csh".
References
man path_helper
After a fresh ubuntu 20.04 install and arranging my .zshrc file, I was seeing locations in my $path even after commenting out them in .zshrc file. Further to my surprise, those were showing in bash $path as well where none were declared there (check DJANGO_HOME in image below). Used source command several times after each change with no result.
It wasted precious 10 mins of time. Then figured things were fine on a new terminal window. So killing the previous terminal and moving to a new one solved it.

Modifying PATH with fish shell [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question 8 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I'm currently playing around with the fish shell and I'm having some trouble wrapping my head around how the PATH variable is set. For what it's worth, I'm also using oh-my-fish.
If I echo my current path I get:
➜ fish echo $PATH
/usr/local/bin /usr/bin /bin /usr/sbin /sbin /usr/local/bin /opt/X11/bin /usr/texbin /Users/myname/.opam/system/bin
Looking at ~/.config/fish/config.fish I see the following line
set PATH /usr/local/bin $PATH /Users/myname/.opam/system/bin
My question is (and this phrasing will probably reflect my lack of knowledge on the subject): prior to config.fish being processed, where is the PATH variable set? ie: where do all of the paths between /usr/local/bin and /Users/myname/.opam/system/bin come from?
As stated in the official fish tutorial, you can modify the $fish_user_paths universal variable.
Run the following once from the command-line:
set -U fish_user_paths /usr/local/bin $fish_user_paths
This will prepend /usr/local/bin permanently to your path, and will affect the current session and all future instances too because the -U argument will make the variable universal.
From the fish documentation:
... (Note: you should NOT add this line to config.fish. If you do, the variable will get longer each time you run fish!)
fish_user_paths, a list of directories that are prepended to PATH. This can be a universal variable.
Current answer
As of fish 3.2.0, released in March 2021, the canonical approach is:
fish_add_path /opt/mycoolthing/bin
This works both one-off interactively, and in config.fish — it won't produce duplicates in the config.fish case.
Previous answer for fish < 3.2.0:
The recommended commands for modifying PATH from fish's maintainers are:
If you want to run the command once:
set -Ua fish_user_paths /path
If you want to add a command to a startup script, this is idempotent:
contains /path $fish_user_paths; or set -Ua fish_user_paths /path
Like all shells, fish inherits its PATH from the environment it is started in. How this is set for login shells differs between operating systems - on Linux, for example, /etc/login.defs controls the initial PATH set for all login shells. I don't know how this is set on OS X.
Next, like bash or csh, the initialisation files for the shell may alter the path. For fish on OS X, there is code in share/fish/config.fish to load paths from the standard OS X path configuration files /etc/paths and /etc/paths.d/*. There is alternative code to set a useful path on Solaris.
There is also code to pick up paths from the universal variable $fish_user_paths, which is the right way to add something to your PATH and have it reflected across all shells.
1. Enumerate user paths:
echo $fish_user_paths | tr " " "\n" | nl
2. Append a new bin path, permanently:
set -ga fish_user_paths my_appended_path
3. Remove 7th bin search path by index: (see #1):
set —eg fish_user_paths[7]
The way that worked with me :
in your ~/.config/fish/config.fish add the following line:
set -gx PATH /path/to/dir1 /path/to/dir2 $PATH
This will append those directories to your $PATH Environment variable.
In order to set variables for shell config file, I did as follows:
The main command to set any user specific variable is
set -Ua fish_user_paths /path/to/bin/directory/
set -Ux fish_user_paths /usr/local/bin
Run touch ~/.config/fish/config.fish, unless it exists.
RUST: set -Ua fish_user_paths $HOME/.cargo/bin
JAVA: set -Ua fish_user_paths /path/to/java/bin
Node & nvm: make sure you have installed nvm properly then
omf install nvm
set -gx NVM_DIR /path/to/nvm
Go: set -Ua fish_user_paths /path/to/go/bin/
Scala: set -Ua fish_user_paths /path/to/scala/bin/
Groovy: set -Ua fish_user_paths /path/to/groovy/bin/
Maven: set -Ua fish_user_paths /path/to/mvn/bin/
Gradle: set -Ua fish_user_paths /path/to/groovy/bin/
Finally, refresh your terminal.
PS in some operating system (eg OpenSuse), drop a.
Above solutions do not work well with python virtual environment. The path to virtual environment will not be the first one in the list.
In order to set path once and do not override it every time you start python virtual environment
You need to change the path conditionally in ~/.config/fish/config.fish, like this:
contains /home/$USER/.pyenv/bin $PATH; or set -x PATH "/home/$USER/.pyenv/bin" $PATH
contains /home/$USER/.local/bin $PATH; or set -x PATH "/home/$USER/.local/bin" $PAT
contains /home/$USER/.asdf/bin $PATH; or source ~/.asdf/asdf.fish
This will ensure that you have new paths in $PATH but wnen you spawn new shell for virtual environment you'll will not add these paths again.
Unfortunately paths set with set -Ua fish_user_paths would endup in the beginning of the $PATH, pushing your virtual environment path away from the first place.
You may use a script like the one below to ease adding or removing paths:
#!/usr/bin/env fish
#remove PHP72
for argv in /usr/local/opt/php#7.2/bin /usr/local/opt/php#7.2/sbin;
while contains $argv $fish_user_paths
set -l index (contains -i $argv $fish_user_paths)
set –erase –universal fish_user_paths[$index]
end
end
#add PHP74
for argv in /usr/local/opt/php#7.4/bin /usr/local/opt/php#7.4/sbin;
if contains $argv $fish_user_paths
echo "Path already contains $argv"
else
fish_add_path $argv
end
end
echo $fish_user_paths | tr " " "\n" | nl
brew services stop php#7.2
brew services start php#7.4
Copied from https://www.tai.ro/2021/10/22/how-to-switch-path-in-fish-shell-with-example-script/

Got "permission denied" when emulating sh under zsh [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
I just switched to zsh as my default Mac OS terminal shell. However, I found it won't automatically hit the ~/.profile file. After researching on Google, it looks like it can be solved by adding the following command in ~/.zprofile to emulate whatever in ~/.profile:
emulate sh -c '~/.profile'
However, I got the follwoing error when terminal starting up:
zsh:1: permission denied: /Users/XXX/.profile
Any idea why this is happening?
To accomplish your goal, you'd have to use:
emulate sh -c 'source ~/.profile' # Note the `source`; alternatively, use `.`
Without the source, ~/.profile would run in a subshell, which defeats your intent (exports wouldn't "stick"); you have to source that other file.
(The specific error you saw stems from an attempt to execute ~/.profile directly, without its being marked as executable. Note that shell profiles normally needn't be executable, because their only purpose is to be (automatically) read by a shell. It's a moot point, however, given that sourcing from within a shell is needed.)
As for what zsh initialization file to put the command in:
On macOS, if you've made zsh your default shell, then ~/.zprofile works, as all shells you'll open in a terminal will be login (zsh) shells, which will read that file.
Generally, though, ~/.zshrc is the better choice, as that file gets sourced by any interactive zsh shell, whether it's a login shell or not. It's also the file to use with the Oh My Zsh framework.
Sounds like you should be using .zshrc
Add this to ~/.zshrc:
EXPORT JAVA_HOME="whatever"
And type $ source ~/.zshrc in your terminal window, or start a new shell instance.
Follow up:
this article lists the startup files loading order which clarifies the confusion.

cleaning up $PATH in bash [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 11 years ago.
Improve this question
My path has a lot of entries that were added long ago by scripts. They are not in my .bashrc, .bash_profile, or .bash_login.
I'm worried that resetting my path in .bashrc will have undesirable long-term results. Is there a way to find where things have been added to my path and remove them manually? Are things always added by file or is path cached somewhere? If the latter, is it easy to clean that up?
The easiest way to find who modified your PATH is to run:
$ bash --login -i -xv 2>&1 | grep ' \. '
For example I got:
+ . /etc/profile.d/bash_completion.sh
. /etc/bash_completion
++ . /etc/bash_completion
+++ . /etc/bash_completion.d/abook
+++ . /etc/bash_completion.d/ant
+ . /etc/profile.d/lapack0.sh
+ . /etc/profile.d/openssl.sh
+ . /etc/profile.d/qt3-devel.sh
+ . /etc/profile.d/tetex-profile.sh
+ . /etc/profile.d/xinit.sh
+ . /etc/bash.bashrc
...
You shouldn't let some random sysadmin decide what's in your PATH anyway, you should set it to the PATH you need. You begin with
# POSIX way of getting the system's PATH to POSIX tools:
PATH=$(getconf PATH) # Or /usr/bin/getconf PATH.
followed by whatever you require in addition, e.g.
PATH="$PATH:/usr/local/bin"
PATH="$PATH:/usr/local/sbin"
PATH="$PATH:$HOME/bin"
and put this in your shell's .profile or equivalent. Note that you do not want . or world-writable directories in your PATH for security reasons.
You're always at liberty to look at the directory contents for each component of $PATH and decide whether you use the programs therein. If you don't use the programs, the chances are, you won't be hurt by removing the directory from $PATH. If the directory doesn't exist, then you can completely safely remove it.
It is puzzling that the directories show up in your profile and related files. You should check for ~/.profile too. You should also look at material like /etc/profile.
Personally, I consider I am in charge of my PATH. I set it from scratch according to my rules, picking the directories I need. You're not obliged to accept what the system admins set for you, though you should not idly remove PATH components that they've added. But their views on what's desirable may be different from yours.
The only long-term undesirable effect might be that some program you use stops working because it relied on something from the old version of $PATH. So, keep a record of what you had before you started messing with PATH - but don't be afraid to adjust PATH to suit yourself.
Check your /etc/profile file, and, depending on your OS version, /etc/profile.d/ directory.

Resources