How to remove the need of "./" in every shell script in MacOS?

What's Wrong with Your Code

The reason your example doesn't work is because PATH is a variable, and you need to expand it by prefixing it with the dollar sign to access its value, e.g. PATH=$PATH:. rather than just PATH=PATH:.. However, there are some other considerations too.

Prepending, Appending, and Exporting PATH

It's generally not recommended to treat your current working directory as part of your PATH for security reasons, but you can do it in any Bourne-like shell by prepending or appending . (which means any current working directory) to your PATH. Depending on where you call it and how you've initialized your shell, you may also need to export the PATH variable to your environment.

Some examples include:

# find the named executable in the current working directory first
export PATH=".:$PATH"

# find the named executable in the current working directory
# only if it isn't found elsewhere in your PATH
export PATH="$PATH:."

# append only the working directory you're currently in when you
# update the PATH variable, rather than *any* current working 
# directory, to your PATH
export PATH="$PATH:$PWD"

Note that it's also generally a good idea to quote your variables, since spaces or other characters may cause problems when unquoted. For example, PATH=/tmp/foo bar:$PATH will either not work at all or not work as expected. So, wrap it up for safety (with quotes)!

Use Direnv for Project-Based PATH Changes

You might also consider using a utility like direnv that would enable you to add the current working directory to your PATH when you enter known-safe directories, and remove it from the PATH when leaving the directory. This is commonly used for development projects, including shell scripting ones.

For example, you could create the following ~/dev/foo/.envrc file that would only prepend the current working directory when in ~/dev/foo, and remove it again when you move above the current .envrc in your filesystem:

# ~/dev/foo/.envrc
#
# prepend "$HOME/dev/foo:$HOME/dev/foo/bin" to your 
# existing PATH when entering your project directory,
# and remove it from your PATH when you exit from the
# project

PATH_add "$PWD/bin"
PATH_add "$PWD"

Because direnv uses whitelisting and ensures that your items are prepended to PATH, it's often a safer and less error-prone way to manage project-specific modifications to your PATH or other environment variables.

Use "$HOME/bin" to Consolidate Scripts

Another option is to create a directory for shell scripts in your home directory, and add that to your PATH. Then, any script placed there will be accessible from anywhere on your filesystem. For example:

# add this line to .profile, .zprofile, .zshrc, or
# whatever login script your particular terminal calls;
# on macOS, this should usually be .zprofile, but YMMV
export PATH="$HOME/bin:$PATH"

# make a ~/bin directory and place your
# executables there
mkdir -p ~/bin
cp helloworld.sh ~/bin/

Assuming the shell scripts in your bin directory already have their executable bit set (e.g. chmod 755 ~/bin/*sh), you can run any shell script in that directory from anywhere on your filesystem.


You need PATH=$PATH:. -- the $ to expand the (old) value of PATH is important.