2

I'm on Windows 10 and decided to transition from cmd to Git Bash. Say I have a script foo.sh, I'd like to be able to run it with the command foo and not foo.sh. I found this answer, which works in some cases but not all:

  1. It only works if the script is in PATH. If it's just a script in my current directory, all the following forms don't work: foo, ./foo, foo.sh. The only way that works is ./foo.sh (so I still have to type the extension). I would expect ./foo to work, I don't know why it doesn't. It's as if the command not found handler doesn't even run in this case.

  2. I discovered that cd in a bash script doesn't work, you have to source the script like so: . foo.sh. Again, I'd like to be able to run . foo.

  3. It doesn't work in bash scripts that call other bash scripts.

So my question is how do I get rid of the need to type .sh everywhere, not just under specific circumstances.

EDIT: since I was asked, the output for assoc .sh on my machine is:

.sh=sh_auto_file

And the output for ftype sh_auto_file is:

sh_auto_file="C:\Program Files\Git\git-bash.exe" --no-cd "%L" %*

Verpous
  • 131

4 Answers4

2

This requires a couple steps.

  • Add .sh to the PATHEXT environment variable
  • Define an FTYPE for .sh ftype bash.File=c:\somepath\bash.exe "%1" %*
  • Define an assoc for .sh assoc .sh=bash.File

Similar to: https://stackoverflow.com/questions/9037346/making-python-scripts-run-on-windows-without-specifying-py-extension

uSlackr
  • 9,053
0

Bash requires an explicit filename, that's why you needed to perform such an obtuse workaround. It's also case sensitive, unless special consideration is being taken for a Windows environment.

What you're trying to do is shoehorn a Windows shorthand onto a Unix shell where it never existed. Outside of your trusted use case, it is also a security risk, for example, foo.exe could be dropped into the PATH and take priority.

My workaround for this was to adopt a habit of naming all executable shell scripts without the extension and all non-executable scripts (such as those that are includes or dependencies) with an extension. This has the added benefit of being easier to tab complete when there are files of similar, completable names, as it is already explicit without the extension.

Zhro
  • 957
0

As @uSlacr points out, there are three steps.

You may run this .BAT file in an administrative command prompt to do them

:: Make .sh and .bash files executable without extension

:: Append .sh to PATHEXT setx PATHEXT "%PATHEXT%;.SH;.BASH" /M :: Define an FTYPE FTYPE bash.File="C:/Program Files/Git/bin/bash.exe" "%%1" %%* :: Define ASSOC for that FTYPE ASSOC .sh=bash.File ASSOC .bash=bash.File

The path to bash varies by how you installed git-for-windos. You can generate the .bat file in bash using

#!/bin/bash

bash_location="$(git --exec-path | sed 's@(.Git/).@\1bin/bash.exe@')"

printf '%s' ':: Make .sh and .bash files executable without extension

:: Append .sh to PATHEXT setx PATHEXT "%PATHEXT%;.SH;.BASH" /M :: Define an FTYPE FTYPE bash.File="'"$bash_location"'" "%%1" %%* :: Define ASSOC for that FTYPE ASSOC .sh=bash.File ASSOC .bash=bash.File ' > exec-sh-ext.bat

CervEd
  • 187
  • 8
0

Actually, it's just a matter of

  1. making sure your script is a Bash script, for which its first line should be #!/bin/bash
  2. removing the extension altogether, for example mv ./script1.sh ./script1
  3. making the file executable, for example chmod 777 ./script1
  4. (optionally) including the dir of your script in the PATH, for example export PATH="$HOME/my-scripts:$PATH"

If you do all 4 steps, then you can run your script with script1 from wherever.

Ando
  • 121