7 ms·
If you set $CDPATH, then for goodness’ sake don’t export it. It changes the behaviour of the cd command to make it output the absolute path of the directory cha
by robinhouston 7y ago
If you set $CDPATH, then for goodness’ sake don’t export it. It changes the behaviour of the cd command to make it output the absolute path of the directory changed to, which breaks a common shell-scripting pattern for converting relative directory paths to absolute paths, viz:
absolute=$(cd "$relative" && pwd)
Conversely, if you’re writing a bash script and it needs to be robust against people who do export CDPATH, you can do it like this instead:
absolute=$(CDPATH=. cd "$relative")
- jsjohnst 7y agoOr just learn the right method to do that and use `readlink` or `realpath` or similar solution.
- robinhouston 7y agoThat’s a very Linux-centric view. Neither of these works on BSD. It’s probably fine if you’re writing scripts that only need to run on Linux, but I wouldn’t call it the “right method”.
- jsjohnst 7y agoReadlink is available on FreeBSD, OpenBSD, and NetBSD. https://www.freebsd.org/cgi/man.cgi?query=readlink&sektion=1 https://www.freebsd.org/cgi/man.cgi?query=readlink&sektion=1 So how is that a Linux-centric view again?
- robinhouston 7y agoSure, readlink exists. And it lets you read symlinks. But it can’t be used to convert relative to absolute directory paths, which I thought was the use you were proposing.
- jsjohnst 7y agoFrom the man page: > if the -f option is specified, the output is canonicalized by following every symlink in every component of the given path recursively. readlink will resolve both absolute and relative paths, and return the absolute pathname corresponding to file. In this case, the argument does not need to be a symbolic link. This is the case for *BSD, GNU/Linux, and Irix. If macOS would prioritize being consistent with the other Nix OSs, it would be supported too, but alas Apple doesn’t.
- stephenr 7y agoNeither of those is portable, they can't be used in POSIX shell.
- jsjohnst 7y agoNeither is GP’s solution portable either.
- stephenr 7y ago`$()` `cd` and `pwd -P` are all part of the POSIX spec. While that doesn't guarantee they're implemented in all shells, it's a lot more likely than things like readlink which are known to not be portable with the flags required to resolve a symlink.
- jsjohnst 7y ago`readlink -f` while not POSIX proper, works on FreeBSD, OpenBSD, NetBSD, and most Linux distros. If you really need to support a wider range than that, reality says you will likely have conditional OS checks in your script anyway, so I’m not sure your point other than being pedantic?
- stephenr 7y ago`readlink -f` on GNU canonicalises the path. `readlink -f` on a *BSD is for formatting the output `readlink -f` on macOS throws an error because it's an supported option.
- jsjohnst 7y agoFrom the FreeBSD man page [0] on readlink: > if the -f option is specified, the output is canonicalized by following every symlink in every component of the given path recursively. readlink will resolve both absolute and relative paths, and return the absolute pathname corresponding to file. In this case, the argument does not need to be a symbolic link. [0] https://www.freebsd.org/cgi/man.cgi?query=readlink&sektion=1 https://www.freebsd.org/cgi/man.cgi?query=readlink&sektion=1 Update: And here’s the OpenBSD man page from 1997 refuting your claim it’s for formatting as well: https://man.openbsd.org/OpenBSD-2.2/readlink.1 https://man.openbsd.org/OpenBSD-2.2/readlink.1 Update 2: OpenBSD (1997): http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/readlink/readlink.c?rev=1.10 http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/readlink/r... GNU/Linux (2003): https://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg00008.html https://lists.gnu.org/archive/html/bug-gnu-utils/2003-02/msg... So it definitely did exist in at least one *BSD before Linux.
- mceachen 7y agoMany years ago I discovered CDPATH, and months later, I determined, never again will I walk into that valley of madness. It breaks so many things.
- everybodyknows 7y agoFor quick directory switching, consider the alternative approach of the built-in directory stack commands: dirs, pushd, popd. A bit of scripting is then wanted to coerce the output of 'dirs' into a readable format.
- kekebo 7y agoOr some directory bookmarking functionality like ohmyzsh's jump plugin or fasd[0] https://github.com/clvv/fasd https://github.com/clvv/fasd
- mceachen 7y agoNice. I actually KISSed and just added a bunch of aliases that start with 'cd' to hop into common directories, like alias cdp='cd ~/src/photostructure' for example. I found I only really needed < 10 directories aliases in this fashion.
- everybodyknows 7y agoTo tidy up dirs's output: d () { dirs -p | nl -v 0; } The numbers in the left-hand column correspond to offsets from top-of-stack. So, if you see $ d 0 ~ 1 /var/log/apt to switch back to /var/log/apt, you could type: $ pushd +1
- deleted 7y ago[deleted]