The shebang line tells the kernel what interpreter to use for your script.
- [Man] Let's look at writing a bash script. Scripts are interpreted, and it's important that the very first two characters in your script file be the hash or pound sign and the exclamation point, sometimes known as bangs, so pound bang should be the very first two characters, not the third and fourth or second and eleventh or something. The kernel actually looks for the very first two characters in a file, and if it sees a bang, that's important.
What follows the pound bang, or what we call shebang, is the path name to the program to run to interpret that script. Some folks like to use user bin ENV, which will go look in your environment for the name of the command you give, so they'll say something like, user bin ENV bash, but pound bang bin bash is very acceptable. So with that pound bang, the kernel will actually execute the program that follows the pound bang, and when it executes that program, it passes to that program, any command line arguments that follow it.
So you could pass options to the shell, plus the kernel passes the path name of the script file. So this pound bang isn't peculiar to shells or bash, so if you run your script like dot slash myscript dot SH, and you have in that pound bin bang bash, then what gets executed is slash bin bash space dot slash myscript dot SH. So this general technique of having the kernel run the interpreter and pass to the interpreter, the path name to your script, works with lots of things, it's not just Bash, Perl, Python, Expect, awk scripts and so forth.
The ENV looks in your path variable to find the path for the program that's sometimes used for other sorts of interpreters that might have some weird path for them. But for Bash, it's usually bin bash works on pretty much any Linux system. So for bash scripts, by far the most common thing is pound bang slash bin slash bash. Because your script is program, and you're going to execute it, you want it to have the execute permission. Normally, you'll add execute permission with change mod u plus x.
U plus x means add execute for the user, and the user is the one that owns the file, and that's usually you. If you don't have execute permission on a script, but you do have read permission, you can still run it, but you can't run it directly as a command, it has to be interpreted by another command, like bash. So if you say bash thescript dot SH, that will run it as well. If you just say the script dot SH, without a dot slash, then your path variable needs to include the directory that has the file, thescript dot SH.
Now if you're working in your own sort of directory, it's common that the path variable doesn't have that directory in it, so you might have to say dot slash. If one of the directories in your path variable is just the dot, that means current directory, then whatever directory you're in, the shell will look for a program, then you can also leave off the dot slash. Now you can call your script files pretty much anything you want, any kind of valid file name, but it is pretty common for folks to name their script files with something dot SH. That's kind of handy for humans to recognize, oh, that's probably a script.
Let's look at some fundamentals of script files. Here we have a file named shebang dot SH. It just has the line in it, PS minus L, a PS command. If we do PS minus L, we get output here, we see the shell and we see PS commands. And if we do a long list, shebang dot SH, we see the permission modes, read write, read write, and read, we don't have execute permission. If we try to run shebang dot SH, like that, we see command not found, because the directory line is not in my path variable.
If I try to run it by giving a path name, it finds it, but I get this permission denied because of no execute permission. If I add execute permission, then I try to run it, then it runs, we see the output. And now we that we had our PS and two bash processes, and if we look at the process ID and the parent process ID, we can see the parent of PS was 45-28, and the parent of 45-28 was 45-20, that was our original shell.
So we see the second bash as a child of the first bash. That should make sense. Our shell was running that shell. But if we look at the file again, notice I didn't use the shebang, and it ran as bash, I just did dot slash shebang dot SH, and on this Linux system, it ran that shell with bash. You can't depend on that. That's why you want to put the shebang in there to make sure that it uses the interpreter that you want, right? If we were trying to use a different shell to interpret this, the C shell or TC shell or something like that, then we'd be getting the wrong one, because on this system, the default is bash, so we should edit that, so we'll go pound bang, and we'll put the name of the shell to run.
Let's do SH instead of bash to see what happens. Just to double check, we have the shebang and bin SH, and if we run it, interestingly, it says the command is shebang dot SH. If we edit it again, we put bash, we still get that, we can't exactly tell. If we just interpret it with the shell, then we see bash.
Now PS minus L should work in pretty much any shell, but if we had some bash peculiar features in our script, then it would be particularly important that we had the pound bang bin bash.
- Exploring the Bash documentation
- Setting the script interpreter and permissions
- Sourcing and aliasing with bash
- Displaying text with echo
- Using the typeset and declare commands for variables
- Reading input
- Defining functions
- Using operators
- Using filters and parameter expansion
- Advanced bash scripting techniques