osx bash force case sensitivity - macos

Me:~ me$ cd desktop
Me:desktop me$ pwd
/Users/me/desktop
What is the correct way to force case sensitivity (so that cd desktop fails but cd Desktop goes to the correct directory)? I would assume there was a shopt for that but the manpage doesn't suggest any obvious option.

Sounds like filesystem in question is not case-sensitive -- see the first answer here to verify.

Case-sensitivity is an option of the file system, not of the shell. Therefore you cannot change this with a shell option.
(To understand why, just consider that it is possible to have case-sensitive and case-insensitive filesystems mounted at the same time. How would you handle this with a single shell option?)

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.

How to expand $PWD when using tab to autocomplete?

When I was using my Ubuntu system, I could type cd $PWD/ and when I hit TAB, the $PWD would change to the actual working directory I was in; for example, cd /home/daverbuj/.
Now that I've changed computers and no longer using Ubuntu, I can't replicate this feature. Is there some way to configure my .bashrc or something similar to autocomplete/expand my paths that I use?
Add shopt -s direxpand to your rc files.

Mysterious phantom rm -i alias

I'm using zsh on Mac OS 10.6.8.
So, all of a sudden one of my machines asks me for confirmation every time I rm.
Frankly, I hate this with an abiding passion. I've never had a problem with rm, and I don't need to debate the potentialities.
First thing I did was which rm, which reports rm: aliased to rm -i.
Now, I've hunted high and low for this alias. zshrc, .config (which I don't have), the default zshrc files: everywhere I can think of. No mention of aliasing rm anywhere.
Is there a simple way to determine where this alias is being configured? Or to list all locations where zsh might be looking for config lines?
Nope, there's no way to know which startup file an alias has been configured from, sort of searching them yourself.
The Z-shell startup files can be found here.
A comment for the question suggests /etc/profile; this is incorrect (unless you're sourcing it yourself), as /etc/profile is a Bourne-type shell startup file.
If you can't find the place it's sourced, you could unset the alias [bottom paragraph] in ~/.zshrc: unset rm. That should work provided it's done after the alias is set.

Faster use of the cli - setting a variable for current project

I'm frequently using the cli (terminal) on Linux and Mac.
How can I save time by setting a variable to the current project folder instead of
cd path/to/folder/over/and/over/again
Something like
cd the-current-project
(with tab completion)
?
Depending on your shell, you can set a cdpath with directories you regularly cd to, and so you can do just what you want:
cd the-current-project
from anywhere. See here for more details.
Alternatively you can just set a shell variable and
cd $CURRENT_PROJECT
Again, your shell will determine whether you can tab-complete this (I know zsh will do this. I'm not sure about bash).

How can I make the "find" Command on OS X default to the current directory?

I am a heavy command line user and use the find command extensively in my build system scripts. However on Mac OS X when I am not concentrating I often get output like this:
$ find -name \*.plist
find: illegal option -- n
find: illegal option -- a
find: illegal option -- m
find: illegal option -- e
find: *.plist: No such file or directory
Basically, I forgot to add the little dot:
$ find . -name \*.plist
Because BSD find requires the path and GNU find doesn't (it assumes the current directory if you don't specify one). I use Linux, Mac OS X and Cygwin often all at the same time, so it's of great benefit to me to have all my tools behave the same. I tried writing a bash find function that added "./" if I forgot, but I failed. Thanks for your help. :)
Install GNU find instead.
$ brew install findutils
$ alias find=gfind
Yay, it works!
If you can't discipline yourself to use find 'correctly', then why not install GNU find (from findutils) in a directory on your PATH ahead of the system find command.
I used to have my own private variant of cp that would copy files to the current directory if the last item in the list was not a directory. I kept that in my personal bin directory for many years - but eventually removed it because I no longer used the functionality. (My 'cp.sh' was written in 1987 and edited twice, in 1990 and 1997, as part of changes to version control system notations. I think I removed it around 1998. The primary problem with the script is that cp file1 file2 is ambiguous between copying a file over another and copying two files to the current directory.)
Consider writing your own wrapper to find:
#!/bin/sh
[ ! -d "$1" ] && set -- . "$#"
exec /usr/bin/find "$#"
The second line says "if argument 1 is not a directory, then adjust the command line arguments to include dot ahead of the rest of the command. That will be confusing if you ever type:
~/bin/find /non-existent/directory -name '*.plist' -print
because the non-existent directory isn't a directory and the script will add dot to the command line -- the sort of reason that I stopped using my private cp command.
If you must call it 'find', then you want:
alias find=/usr/bin/find\ .
in your .profile or .bash_profile or …. Substitute the real path (if not /usr/bin/find) on your Mac OSX. Enter the full path to avoid cycles (bash normally would interpret alias find=find without issues, but better be sure).
But you better not name the alias find (findl, myfind etc), because it will become a habit and trouble for you if you try it on another system.
find ./ -name "*.plist"
edit: hmm, i may have misunderstood the question! if you were crazy, how about emulating it via a shell script? i routinely keep random utility scripts in ~/.bin, and that's the first thing in my PATH. if you had a similar setup perhaps you could do something like: (untested!)
#!/bin/sh
# remapping find!
CMD=`echo $1 | cut -c 1`
if [ $CMD = '-' ]
then
# pwd search
/usr/bin/find ./ $*
else
# regular find
/usr/bin/find $*
fi
I would suggest that if you're writing scripts (which are more likely to be migrated from one system to another sometime in the future) that you should try to use the more specific form of the command, that is specifying the "." instead of relying on a default. For the same reason, I might even suggest writing sh scripts instead of relying on bash which might not be installed everywhere.
This is probably not what you want but how about: alias find="find ."
or choose a new name (findl for find local?)
You may want to run the commands found in this link: https://www.topbug.net/blog/2013/04/14/install-and-use-gnu-command-line-tools-in-mac-os-x/
It is a bit outdated, for example I found I did not have to add many commands to my path at all.
This covers your problem by having your system use the Non-BSD find utility from the findutils package, while also installing other tools you may want as well.

Resources