We can accomplish a self-executing script with a special syntax, #!, called a shebang, or sometimes hash-bang, as the first line of the script. This syntax is treated specially by the kernel, and specifies the program that should be used to run the rest of the script—the interpreter.
We edit hello.bash to put the shebang as the very first line of the script:
#!/bin/bash printf 'Hello, %s!\n' "$USER"
The preceding syntax assumes that your Bash shell is in the common location of /bin/bash. You can find out where yours is by checking the value of the BASH variable:
bash$ declare -p BASH declare -p BASH="/usr/local/bin/bash"
We also need to use the chmod system program to make the script executable:
bash$ chmod +x hello.bash
This sets the executable bit for all users of the script, allowing it to be executed directly as its own program, without needing to specify bash on the command line:
bash$ ./hello.bash Hello, bashuser!
Now that the script knows its own interpreter, we don't need the .bash extension anymore, so we can use mv to rename the program to just hello:
bash$ mv hello.bash hello bash$ ./hello Hello, bashuser!
This has the effect of making our script into a program that knows how to run itself, and instructs the kernel on what to do when a user executes it. The user of our program is able to run it without needing to think about what language the program is written in. We can even release a new version later with the same name and that does the same thing, but written in an entirely different language!
It's very likely that many of your most-used programs on a GNU/Linux or other Unixlike system are in fact scripts with shebang lines—not compiled from languages such as C, but scripts, interpreted each time you run them. The file tool can help you identify them; for example, the ldd program on Debian GNU/Linux turns out to be a Bash script:
bash$ file /usr/bin/ldd Bourne-Again shell script, ASCII text executable