Zshell PATH variable extra paths - macos

I am pretty new to the Mac environment so I have lots of gaps knowledge-wise. I need to edit the order of the PATH variables that my system uses. I have a .zshrc file in my home directory which has the following contents as of now:
export PATH="$PATH:/Users/mehmetsanisoglu/Desktop/Programs/flutter/bin"
export PATH="$PATH:/Users/mehmetsanisoglu/.rbenv/shims"
that's all, just these two lines. But when I type echo $PATH I get:
/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/TeX/texbin:/Library/Apple/usr/bin:/Applications/Postgres.app/Contents/Versions/latest/bin:/Users/mehmetsanisoglu/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/Users/mehmetsanisoglu/Desktop/Programs/flutter/bin:/Users/mehmetsanisoglu/.rbenv/shims
I am guessing the .zshrc file I have crated appends the items I have in there to the actual list of PATH elements. My question is, how do I get there and edit the ordering of these elements, because I need the ".rbenv" to come before "/usr/bin". Thanks

zsh has a special array variable path that's linked to PATH - changing one changes the other. Treating the path as an array of directories is often much handier than treating it as a string of colon-separated directories.
You can append to it with
path+=(/some/path)
# or
path+=(/some/path/1 some/path/2)
and prepend to it with
path[1,0]=/some/path
# or
path[1,0]=(/some/path/1 /some/path2)

Related

clang:how can fdebug-prefix-map use new path relative to user home path `~`?

I try rewrite the source file path to ~/src/lib by using fdebug-prefix-map.
I can confirm DW_AT_decl_file is rewritten to something like ~/src/lib/path.
But the result is lldb can't find the source file. If I change to a absolute path, it works fine.
How can I solve this?
You can use the target.source-map setting to remap location of source files. From (lldb) apropos source-map:
Source path remappings are used to track the change of location between a source file when built, and where it exists on the current system. It consists of an array of duples, the first element of each duple is some part (starting at the root) of the path to the file when it was built, and the second is where the remainder of the original build hierarchy is rooted on the local system. Each element of the array is checked in order and the first one that results in a match wins.
The usage looks something like:
(lldb) settings append target.source-map /foo /bar
Note that you use append here instead of set, because otherwise you'd overwrite the mapping every time you add an entry. You can check the mapping with:
(lldb) settings show target.source-map

Bash/shell/OS interpretation of . and .. — can I define ...?

How do . and .., as paths (vs. ranges, e.g., {1..10}, which I'm not concerned with), really work? I know what they do, and use them all the time, but don't fully grasp how/where they're interpreted. Does the shell handle them? The interpreting process? The OS?
The reason why I'm asking is that I'd like to be able to use ... to refer to ../.., .... to refer to ../../.., etc. (up to some small finite number; I don't need bash to process an arbitrarily large number of dots). I.e., if my current directory is /tmp/let/me/out, and I call cd ..., my resulting current directory should be /tmp/let. I don't particularly care if ... etc. show up in ls -a output like . and .. do, but I would like to be able to call cat /tmp/let/me/out/..../phew.txt to print the contents of /tmp/phew.txt.
Pointers to relevant documentation appreciated as well as direct answers. This kind of syntax question is very hard to Google.
I'm using bash 4.3.42, by the way, with the autocd and globstar shell options.
. and .. are genuine directory names. They are not "sort-cuts", aliases, or anything fake.
They happen to point to the same inode as the other name you use. A file or directory can have several names pointing to the same inode, these are usually known as hard links, to distinguish them from symbolic (or soft) links.
If you are on Linux or OS X you can use stat to look at most of the inode metadata - it is what ls looks at. You will see there is an inode number. If you stat . and stat current-directory-name you will see that number is the same.
The one thing that is not held in the inode is the filename - that is held in the directory.
So . and .. reside in the directory on the file system, they are not a figment of the shell's imagination. So, for example, I can use . and .. quite happily from C.
I doubt you can change them - personally I have never tried and I never will. You would have to change what these filenames linked to by editing the directory. If you managed it you would probably do irreparable damage to your file system.
I write this to clarify what has already been written before.
In many file systems a DIRECTORY is a file; a special type of file that the file system identifies as being distinctly a directly.
A directory file contains a list of names that map to files on the disk
A file, including a directly does not have an intrinsic name associated with it (not true in all file systems). The name of a file exists only in a directory.
The same file can have an entry in multiple directories (hard link). The same file can then have multiple names and multiple paths.
The file system maintains in every directory entries for "." and ".."
In such file systems there are always directory ENTRIES for the NAMES "." and "..". These entries are maintained by the file system.
The name "." links to its own directory.
The name ".." links to the parent directory EXCEPT for the top level directory where it links to itself (. and .. thus link to the same directory file).
So when you use "." and ".." as in /dir1/dir2/../dir3/./dir4/whatever,
"." and ".." are processed in the exact same way as "dir1" and "dir2".
This translation is done by the file system; not the shell.
cd ...
Does not work because there is no entry for "..." (at least not normally).
You can create a directory called "..." if you want.
You can actually achieve something like this, though this is an ugly hack:
You can run a command before every command entered to bash, and after every command. For that you trap the DEBUG pseudo signal and set a command to PROMPT_COMMAND, respectively.
trap 'ln -s ../.. ... &>/dev/null | true' DEBUG
PROMPT_COMMAND='rm ...'
With this, it seems like there's an additional entry in the current directory:
pwd
# /tmp/crazy-stuff
ls -a
# . .. ... foo
ls -a .../tmp/crazy-stuff
# . .. ... foo
Though this only works in the current directory, because the symbolic links is deleted after each command invokation. Thus ls foo/bar/... won't work this way.
Another ugly hack would be to "override" mkdir such that it populates every new directory with these symbolic links.
See also the comments on the second answer here, particularly Eliah's: https://askubuntu.com/questions/327126/what-is-a-dot-only-named-folder
Much in the same way that when you cd into some directory subdir, you're actually following a pointer that points to that directory, .. is a pointer added by the OS that points to the parent directory, and I'd imagine . works the same way.

OSX Yosemite - invalid characters in path

I'm having trouble installing Homebrew, and it looks like the problem (invalid byte sequence in UTF-8 (ArgumentError) error message) is due to a fault in my PATH. when I run echo $PATH, I get the following (be sure to scroll to the far right in the code block below to see the fault):
/usr/local/mysql/bin:/opt/subversion/bin/:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:PATH=/usr/local/share/python:$PATH:PATH=/usr/local/share/npm/bin:$PATH:export PATH��:/usr/local/git/bin
I have no idea where those strange characters just before the /usr/local/git/bin path are coming from. I'm using bash (tried zshell, same problem). I can't find where this coming from. my .bash_profile file looks clean, too.
Examine your ~/.profile, ~/.bash_profile, and ~/.bashrc files. It is also possible that these values are being set in /etc/profile or other system-wide files, but the nature of the errors is such that I would assume they are the result of your own manual edits of your personal files. You're the best judge to decide what you may have changed and when.
Look for entries such as the following:
PATH='/usr/local/share/python:$PATH'
PATH='PATH=/usr/local/share/npm/bin:$PATH'
PATH='export PATH��:/usr/local/git/bin'
They should instead look like
PATH=/usr/local/share/python:$PATH
PATH=/usr/local/share/npm/bin:$PATH
PATH=$PATH:/usr/local/git/bin
# Not strictly necessary -- PATH is already exported
export PATH
See a pattern? These all add a value to PATH by setting it to prefix:$PATH or $PATH:suffix where the new prefix or suffix is the directory where you have installed a local package. Whether the new value should be a prefix or a suffix is probably of little consequence -- except if you are trying to override a system version (say, your /usr/local/git is installed because /usr/bin/git is too old -- then, it's important that your local version comes first in the PATH). There is also a minuscule speed difference the first time you run a command; the shell has to look in more places before finding it if it's at the end of the PATH.
The difference in quoting is significant -- PATH=$PATH:suffix expands to the old value of PATH with :suffix added on, whereas PATH='$PATH:suffix' replaces the old value of PATH with the literal string $PATH with :suffix added on. You're lucky none of this has ended up replacing your original PATH completely, which would render your shell by and large inoperable (at least until you discover that you have to use /bin/ls instead of just ls).

Placing the semicolon in the Windows PATH environment variable

Where should the trailing semicolon in the Windows PATH environment variable be placed when adding a new folder?
Is it
[oldPATH];C:\My Folder
[oldPATH]C:\My Folder;
[oldPATH];C:\My Folder;
?
I saw different practices.
This is not really a syntax thing, actually. The correct answer here is: Place the semicolon so the result is a valid PATH.
This usually means one of the following:
set PATH=%PATH%;C:\Foo\Bar
set PATH=C:\Foo\Bar;%PATH%
because usually PATH doesn't end in a semicolon, so you have to add one appropriately to not mangle an existing path in it.
Just look at how PATH looks like and consider what you need to do if you add another path. This means you have to add a separator (the semicolon) and the path itself.
The first one. At least thats what Windows does on mine, so if Windows does it that way then that will probably be best :)
The first one:
[oldPATH]; C:\My Folder.
If you want to be sure, you can use the formula:
"%PATH%;C:\My Folder".
If it is only to execute something in, for example, a BAT script, use:
SET PATH "%PATH%;C:\My Folder".
(this one will be working just as a temporal variable)
To add a permanent User Enviroment Variable through command line:
SETX PATH "%PATH%;C:\My Folder".
Your oldPATH may end with semicolon, so when using fourth style [newPath];[OldPath] you don't add double semicolons.
path=%cd%;%path%
Note that windows doesn't care whether you write commands upper- or lowercase.

RUBYLIB Environment Path

So currently I have included the following in my .bashrc file.
export RUBYLIB=/home/git/project/app/helpers
I am trying to run rspec with a spec that has
require 'output_helper'
This file is in the helpers directory. My question is that when I change the export line to:
export RUBYLIB=/home/git/project/
It no longer finds the helper file. I thought that ruby should search the entire path I supply, and not just the outermost directory supplied? Is this the correct way to think about it? And if not, how can I make it so RUBY will search through all subdirectories and their subdirectories, etc?
Thanks,
Robin
Similar to PATH, you need to explicitly name the directory under which to look for libraries. However, this will not include any child directories within, so you will need to list any child sub-directories as well, delimiting them with a colon.
For example:
export RUBYLIB=/home/git/project:/home/git/project/app/helpers
As buruzaemon mentions, Ruby does not search subdirectories, so you need to include all the directories you want in your search path. However, what you probably want to do is:
require 'app/helpers/output_helper'
This way you aren't depending on the RUBYLIB environment variable being set a certain way. When you're deploying code to production, or collaborating with others, these little dependencies can make for annoying debugging sessions.
Also as a side note, you can specify . as a search path, rather than using machine-specific absolute paths.

Resources