10

I am wondering if there is a Unix equivalent for the Windows environment variable PATHEXT.

For those with no Windows background: Adding a file suffix to PATHEXT allows me to execute a script without typing that suffix in cmd.exe. For example, on my Windows computer, PATHEXT contains the suffix .pl and when I want to execute a Perl script in cmd.exe, I simply can type my-script and it gets executed. Yet, in order to execute the same script in bash, I need to write the full name: my-script.pl.

Since I work on both Windows and Unix currently, I almost always fall into the trap of forgetting to type the suffix when going to a Unix box again.

7

short: no

longer: shell scripts require a full filename, but you can define aliases for your commands to refer to them by various names. For example

alias my-script=my-script.pl
13

The simplest solution is to just not use extensions for your scripts. They are not necessary and only serve to identify the script's type to you, but not to the computer. While Windows uses extensions to identify the file type, *nix systems (with very few exceptions such as gzip) do not.

Note that binaries have no .exe extension in *nix, they're just called foo, not foo.exe. So, if you want foo.pl to be executable as foo, simply save the file as foo in the first place.

Alternatively, if you really need to have the extensions for some reason, go into whatever directory you save your scripts in and run this:

for f in *.*; do ln -s "$f" "${f%%.*}"; done

That will iterate over all files with extensions and, for each file foo.ext of them, will create a link called foo which points to foo.ext. Note that this will fail if you have multiple scripts with the same name but different extensions.

7

If you really want to do it, there is a way. Add the following at the end of .bashrc in your home directory, and set PATHEXT to extension names with dots separated by :. (Changed to include the dots to match the Windows behavior.) Use it at your own risk.

if declare -f command_not_found_handle >/dev/null; then 
    eval "original_command_not_found_handle() $(declare -f command_not_found_handle|tail -n +2)"
fi
command_not_found_handle(){
    local PATHEXT_EXPANDED i
    IFS=: read -a PATHEXT_EXPANDED<<<"$PATHEXT"
    for i in "${PATHEXT_EXPANDED[@]}"; do
        if type "$1$i" &>/dev/null; then
            "$1$i" "${@:2}"
            return $?
        fi
    done
    if declare -f original_command_not_found_handle >/dev/null; then
        original_command_not_found_handle "$@"
    else
        return 127
    fi
}

Also remember that you can use tab to complete the command name if there isn't another command also starting with my-script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.