Fullpath in OS X - macos

I am a few steps before starting my first real programming project and I am preparing my machine. I noticed that my fullpath (what I get when I "echo $PATH" in the terminal) does not look like a "normal" one (as I see "usr/bin" quite a lot of times). What does it mean? How does it affect my use of the terminal? And how, if, can I change it back to the default one?
EDIT: I can change it just by typing "PATH=the_name_of_the_path" but it's not permanent, if I quit the session I am running and start terminal again, what I get is "/Applications/lejos_nxj/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin" (and that's because I changed it some months ago so I could usel lejos_nxj, for a course at university). Is it better I change it back to the "normal" again or should I stop worrying about it? How can I change it anyway, in case I had to?

$PATH is a variable specifying a set of directories where executable programs are located. It's normal to see /usr/bin there.
Basically, if you type a command on the terminal, like cat for example, it's going to look for cat in those directories. This way, you don't have to specify the full path to all your frequently used commands.

Here is an example of a "normal" path on a new OS X 10.6 install:
/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/local/git/bin:/usr/X11/bin

If you see the same entries repeated again and again, then you probably have a mixup with your .bashrc vs. .bash_profile. You should set the PATH in the .bash_profile, not .bashrc, to avoid this.

$PATH under all *nixes is actually a list of colon-separated directories. Unless you see several times the /usr/bin entry, nothing's wrong (and even if you see it several times, it doesn't mean it's broken either).
At any rate, you should post what you get.

My path looks like this:
frak:~ seth$ echo $PATH
/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin
Yours should look pretty much the same. Each directory is separated by ':'. However, even if you do have /usr/bin more than once, it won't make any difference.
Observe:
frak:~ seth$ whereis units
/usr/bin/units
frak:~ seth$ units attoparsecs/s m/s
* 0.030856776
/ 32.407793
Add a /usr/bin again:
frak:~ seth$ PATH=$PATH:/usr/bin
frak:~ seth$ echo $PATH
/usr/local/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/bin
And everything still works fine:
frak:~ seth$ whereis units
/usr/bin/units
frak:~ seth$ units attoparsecs/s m/s
* 0.030856776
/ 32.407793

PATH is a shell variable specifying where to find executables. For example, if you do a ftp (file transfer), the shell will look for the command ftp in those directories in your PATH variable before executing it. There's nothing wrong with that. If /usr/bin is not specified in your PATH, then everytime you need to use ftp, you need to give full path name , eg /usr/bin/ftp
Note that for a normal user, /usr/sbin should not be in PATH because those in /usr/sbin are mostly administrative commands.

Related

Replace $PATH with string/file? Set $PATH to null and append?

Backup, first.
Before attempting to resolve this, people are worried about $PATH changes breaking things. Backup your path with echo $PATH > $HOME/bak/conf/path.bak and remember (don't put any raw files into the bak dir). Confirm your backup with cat $HOME/bak/conf/path.bak.
A minimal $PATH!
My desired path is /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin.
This is a minimalist path that should break nothing on most default Linux installs (Backup, first).
I have a huge $PATH that is completely useless (like 120 lines of $PATH--caused by WSL [more later]). So far, I only know how to add to path and remove single directories from $PATH via seg.
Sounds like it should pop right up on search engines. I have a headache in my eye--:
how do I set $PATH to a raw string or purge it so I can append from null?.
Bonus points for anyone who can tell me how to set $PATH from the contents of a file!?
Best guess:
import sys, sys.path.insert(0, '/your/path')--!NO This did not work!
Temporary workaround:
You can move the path to a neutral file (or use whatever means you know) and replace / with / and then use sed to cut the unwanted part out:
PATH=$(echo "$PATH" | sed -e 's/:\/tons:\/of:\/unwanted:\/garbage$//')
Make sure you put everything you don't want between s/ and $//').
Where is this long $PATH coming from?
Related question: How to remove the Win10's PATH from WSL --$PATH is inherited every time you re-launch or perform some other actions such as possibly changing users or environments.
Why is this question different:
As if there isn't enough typing, S.O. has a nuisance dialog that asks me to write and explain why purging $PATH is different from removing one directory/path from $PATH.
Because a punch in the face isn't a kick in the butt.
If I'm understanding your question, you simply want to know how to set your Bash PATH to a fixed string (or erase it completely) and have it persist across restarts of the shell?
If so, then I'll start off by saying that this isn't recommended as it will break other things. If not now, then later.
But if you really want to set the PATH to a fixed value every time Bash starts ...
Short answer first:
Assuming fairly "default" startup files (where ~/.profile sources ~/.bashrc):
Edit your ~/.profile (or ~/.bash_profile in the rare case it exists) and add:
# Remove entirely
unset PATH
export -n PATH
# Optionally
export PATH=/new/pathItem1:/new/path/Item2
Adding this to the bottom of the file should override any other PATH modifications done previously. However, future application installations can make modifications below that, therefore overriding it.
In a very rare case where you have an interactive Bash session that isn't startup by a login shell, you could also make the same modifications to ~/.bashrc.
(Not necessarily required if the modification is the last thing called during startup, but) make sure that there are no other PATH adjustments in your ~/.bashrc or ~/.bash_profile.
More explanation:
Where is this long $PATH coming from?
Your path in Bash in WSL can potentially come from a few sources:
WSL's init process sets a default PATH for the starting application (shell). This is currently (in WSL 0.70.8):
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/usr/lib/wsl/lib
Since this is done before your ~/.profile runs, there's no need to worry about disabling it.
As you've pointed out, WSL automatically appends the Windows path to the Linux path so that you can launch Windows executables. This can be disabled using the method in the question you linked, but it's not necessary if you simply want to override the entire PATH. Setting the PATH in your ~/.profile comes after WSL sets it for the initial process (your shell).
Bash itself has a built-in, default path that is hardcoded into it for "fallback" in case no other path is passed in. This rarely ever takes effect. Most Linux systems are going to set the PATH through some other mechanism, meaning the fallback never gets activated. A typical Linux system will set the default PATH via /etc/environment, but this isn't used under WSL since the init mechanism mentioned above is needed instead.
If using Systemd or another init system in WSL, then Bash (and other POSIX shells) will process /etc/profile and files in /etc/profile.d when starting. These files may contain PATH modifications. Again, since these come before your ~/.profile, (re)setting the PATH to a fixed value will override any of these settings.
Finally, your ~/.profile or ~/.bash_profile (for login shells) and ~/.bashrc (for interactive shells are read. Typically, PATH modifications in these files look something like:
export PATH="/new/path/item:$PATH"
This prepends to the path, making that new item take priority over the previous items.
However, leaving out the existing :$PATH part will simply set it to a string literal.
It should be obvious, but if you do this without including the "normal" OS paths, you will be unable to call any command that isn't built in to Bash already with specifying its fully qualified path. For instance, ls will fail. Note that you can still:
$ ls
ls: command not found
$ /usr/bin/ls
# works
Also note that ~/.profile is called for login shells. It is possible, however, to tell WSL to launch Bash without reading ~/.profile:
wsl ~ -e bash --noprofile
The resulting shell will still have the default WSL path in this case.

zsh: command not found - only works when I change path, but on restarting terminal, path changes back

I have 4 files in my bin. Funnily, two of them work when I call them in the terminal - the other (newer) two don't.
My bin file looks like this: https://ibb.co/bsj00jG
When I type 'which chd-project' in terminal (chd-project is one of the bash scripts which works), it says /usr/local/bin/chd-project - however I can't find a local file on my Mac.
When I type which id-project (the bash script that can't be found), it just says id-project not found.
If I set PATH=$HOME/bin, I can then call the id-project file. However, whenever I restart my terminal, it resets again. This can sometimes be buggy, though, as later commands in that same bash script can sometimes not be found.
When I type echo $PATH I get /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
However, like previously stated, I can call chd-project in my terminal (although it says usr/local/bin if i use 'which') but I can't call id-project.
Any help would be greatly appreciated.
Thanks
Your PATH variable is "reset" for every session you start. That's because the current session doesn't set environmental variables persistently. However, before a session is started it executes files that, for example, hold the value of PATH.
If you want to add this for every terminal you open, you should extend your path in your bash profile.
$ echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
Please take not that you shouldn't overwrite your PATH variable, because it's used to find commands like mv, cp, etc.
EDIT:
I don't know Atom that well, but if you would open a regular (not an in-IDE) terminal it should work. It could be that Atom doesn't execute .bashrc for whatsoever reason. You could try to add it to to your profile.
$ echo "export PATH=$PATH:$HOME/bin" >> $HOME/.profile

in which order will ubuntu search bin-folders for executables?

So I learned that in order to be able to execute a program from everywhere in the shell I have to put a reference file looking something like
#!/bin/bash
path/to/my/original/executable
in my bin-directory and make it executable.
On my current linux system (provided by my workplace) there are multiple bin-directories like
/usr/local/bin
/home/MyUsername/bin/
/home/otherUsername/bin/
For my work I have to alter a c++ program which is supposed to be usable for every user on the computer (hence I used /usr/local/bin/ sofar). But I realized that my changes to the original program do not come through... So my questions are:
Where could other bin-folders be, that I need to check for old executables?
How does my operating system (ubuntu 16.04) choose between executables in different bin-locations but with the same name?
Thanks in advance!
The PATH shell variable contains a colon separated list of paths to look for executables in. The list is processed left to right, the shell executes the first executable binary it finds (make sure to chmod +x the binary you are providing). If you want an easier printout you can use: echo $PATH | tr ":" "\n". Also keep in mind that a program might have been started with a different PATH than your shell and that users can customize their PATH variable. Systemwide PATH settings can usually be found in /etc/profile or /etc/profile.d/. You can use which file to display the full path expansion of file.

Bash issue when open terminal [duplicate]

This question already has an answer here:
How to restore .bash_profile on a mac? None of my unix terminal are working [closed]
(1 answer)
Closed 2 years ago.
I receive this error message each time I launch terminal:
-bash: =/usr/local/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin: No such file or directory
You have recently edited one of your shell's startup files and introduced an error.
Probably, ls -lart ~/.bashrc ~/.bash_profile ~/.profile will indicate which one -- if one or more is missing, that's no concern, we just want to see which one out of these you have edited recently. Examine the time stamps and try to remember what you did to change one of these files.
The error probably looks something like
$oopsPATH=/usr/local/bin:$PATH
where you meant to say
PATH=/usr/local/bin:$PATH
but without access to your files, we can't know what exactly is supposed to be there, or how you messed it up.
See also https://askubuntu.com/questions/198730/how-to-restore-bashrc-file/198740#198740
In the common case where you have messed up your PATH so that ls and other commands are unavailable (bash: ls: command not found), you can use the full path (/bin/ls pro ls, etc; though obviously, you have to know the correct path) at least until you can restore your configuration.
PATH=/usr/local/bin:/usr/bin:/bin
is probably a good crutch until you can find the correct default for your OS. You can type that at the prompt, or put it in one of your shell's startup files and start a new shell.
On many platforms, you can find the default user dot files in /etc/skel so if that's present (which unfortunately will not be true for Mac OS, but should be there on most Linuxes):
cp -b /etc/skel/.bash_profile $HOME/
will replace your (presumably broken beyond repair) .bash_profile with the system default one. (Omit the -b option if your OS doesn't have it, but then you'll want to back up your file manually before replacing it.)
Update: This fragment near the top of your .bash_profile is erroneous:
#loginPath
=/usr/local/bin:$PATH
Just take it out; it doesn't seem to do anything useful. There seem to be multiple additional fragments from the MacPorts installer which look wrong, too, but they are just comments. (Perhaps somehow they shouldn't be?)
It seems that you are missing a necessary PATH and that is why it is saying no such file or directory. If, for example, you get this error message when typing in python, it would mean either that (1) python isn't installed; or (2) python isn't on your system path.

How can I debug $PATH?

There is a directory in my $PATH that I want removed.
But I cannot figure out how it got there.
I've looked at all the places I can think of where $PATH gets set: .profile, .bashrc, .bash_profile, et cetra
but I cannot find who is putting this particular directory into $PATH.
Clearly, I do not know all the things that change $PATH when my system starts.
Is there a way to debug the startup sequence?
Ideally I just want to set a trap on anything that touches $PATH.
Or may there is a log file (or ordered set of log files) I can scan.
How can I find how each directory gets set in $PATH among all the things that run when my system starts?
There are two ways to do this:
Try bash --login -x in a terminal window. This will print every line of the setup scripts as they are executed (kudos go to kojiro).
Alternatively, you could add set -x near the top of /etc/profile or $HOME/.profile. The danger here is that if you make a mistake, your system may become unusable (if you can't start a new shell anymore) plus you need to be root. If you want to try this, I suggest to create two terminal windows, keep them open at all cost, make the changes and then start new terminal windows to see the effects.
Use grep -r PATTERN / (replace PATTERN with the path that you look for). That should search your whole hard disk for this pattern and can take a long time. Maybe start with your home directory. If you want to search just the . files, use this trick: grep -r PATTERN .??*
If you are using BASH, the way the login loading works is this order:
/etc/profile is first read in.
$HOME/.bash_profile is read in.
If $HOME/.bash_profile doesn't exist, then $HOME/.bash_login is read in.
If $HOME/.bash_login doesn't exist, then $HOME/.profile is read in.
NOTE: That $HOME/.bashrc is not read in by default. However, many people do source in their .bashrc file at login.
When a shell is invoked, and it's not a login shell, then the $HOME/.bashrc file is loaded.
By default, the Mac's PATH is /bin:/usr/bin:/usr/sbin:/sbin. This is set via /etc/profile which executes /usr/libexec/path_helper. This takes the initial paths from /etc/paths.d/... and from /etc/paths. The /etc/paths.d only adds in the /opt/X11/bin directory if X11 is installed. Otherwise, /etc/paths is used and it contains the default paths.
Mine is set to:
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin
I use /usr/local/bin for third party tools. or newer versions of already installed tools. For example, /usr/bin/svn is version 1.7.17 while /usr/local/bin/svn is set to version 1.8.10. Me invoking svn will invoke the version of Subversion I installed, and not the native version.
In this case, the 1.8 version of Subversion is actually installed in /opt/subversion/bin/svn, but I create a symbolic link to it in /usr/local/svn. I do this for any tool that I install: The tool gets installed in /opt and I link the binaries and scripts to /usr/local/bin, so they're in my $PATH.
Place these 2 lines at top of your ~/.bash_profile (create it if it doesn't exist):
set -o functrace
trap '[[ "$BASH_COMMAND" == *" PATH="* ]] && echo "$BASH_COMMAND"' DEBUG
Then exit the current shell and start a new shell.
It will print every time PATH variable is set in your environment.

Resources