Welcome back 👋🏽 As usual, if you find my ramblings interesting and want to read more, or think they're rubbish and want to tell me about it, remember to scroll down to leave a comment before, during, or after your read. tl;drIf you're here to see the smallest Bash script, look no further. Here it is: #!/bin/bash Read on if you're wondering why it's not just an empty file like 10-years-ago-me. The Smallest Kinda Sorta Bash Script in the UniverseI'll let you in on a little secret. Back in the day I had this misconception that a Bash script was any text file with execute permission. In other words, I thought that # Create an empty file$ : >shell_script# Mark that file as executable$ chmod u+x shell_script# Run that file$ ./shell_script$ To explain why fork and execveMost programs running on Linux run at least some code from the C programming language. If they're not directly written in C, they're very likely either running code from the C runtime or are running in an interpreter that uses the C runtime. And BTW, for the purposes of this post you can think of the C runtime as a bunch of functions that have already been written for C programmers. This code sits in a shared library, ready to run. The two functions we'll be focusing on are ones you wouldn't ever want to implement yourself as they interact with the kernel to do fun and exciting things that you don't want to get wrong. Whoever had to review my implementations of these functions in that university operating systems course can attest to that. I'm sorry for subjecting you to that, professor I Forgot What your Name Is. Let's follow a C program named Process Splitting with fork
So after Process Replacement with execve
It asks the kernel to replace the program running in the current process with some other program. Since no remnants of
Arguments usually describe what a process should call itself and what precisely it should do. Environment variables usually describe the system that a process is running in or other software systems that a process may need to work with. Since the environment of a process will very likely be the same as its children, that set of key-value pairs is usually just copied from the already running program to Arguments are usually invocation-specific, and so are instead passed to What does execve actually do?
It does this by asking the kernel to identify the type of program in an executable file and to run the appropriate kernel code to load it and set it executing. The kernel has handlers for programs in a handful of different binary formats, but the handler we're interested in is right here. Scripts Must Begin with #!Here's the beginning of the real magic of executing a script file: The most important code (highlighted) checks the first two characters of the first line of the program file. If these characters are With these values in hand, the kernel repeats what it was asked to do with a few changes:
Running the Actual Smallest Bash Script in the UniverseSo let's say $ cat shell_script#!/bin/bash$ Even if The Smallest Bash ScriptAnd that's why the smallest Bash script is: #!/bin/bash ...and why it's important to always begin shell scripts with The end. Um...really?You may notice that if you list a bunch of commands in a text file and run it in Bash, those commands still execute as if the file were a Bash script: # Create a file containing two lines of shell$ cat > shell_script I haven't been lying to you. Attempts to ask the kernel to execute a text file that doesn't start in Don't believe me? Take a peek at the source: Your script may not always be executed by Bash (e.g. from a cron job, by the backend of a web service, or by a continuous integration system) so it's important to always start scripts with Further ReadingHope you found that interesting and helpful. If it was, be sure to click Recommend below and may be even leave a comment. For further reading on how Bash scripts are executed, see:
|
|
来自: imnobody2001 > 《Linux pgm》