6

Commands And Arguments

 2 years ago
source link: https://guide.bash.academy/commands/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

What are bash commands and how do I write and issue them?

We learned a great deal about how bash and other processes work together in the terminal. Let's refocus on bash and start figuring out how exactly we get stuff done with it.

As mentioned earlier, bash waits for instructions from you and then executes them to the best of its abilities. To get the most out of bash, and especially to avoid damage due to bash misunderstanding your intentions, it's important that you pay close attention to these basics of the bash shell language. There are many people that consider themselves fluent in bash but fail to understand even these most basic concepts. As a result, they create programs that can inflict extensive damage to unsuspecting users and systems. Don't be that person.

So what are bash commands?

At the core of the bash shell language are its commands. Your commands tell bash what you need it to do, step-by-step, command-by-command.

Bash generally takes one command from you at a time, executes the command, and when completed returns to you for the next command. We call this synchronous command execution. It is important to understand that while bash is busy with a command that you give it, you cannot interact with bash directly: you'll have to wait for it to be ready with executing its command and return to the script. For most commands, you'll barely notice this: they get executed so fast bash will be back for the next command before you realize.

Some commands can take a long time to complete, though. In particular, commands that start other programs with which you can interact. For instance, a command might start a file editor. While you're interacting with the file editor, bash takes a back-seat and waits for the file editor to end (which generally means you quit it). When the file editor program stops running, the command ends and bash resumes operation by asking you for the next thing to do. You'll notice that while your editor is running, you are no longer at the bash prompt. As soon as your editor exits, your bash prompt re-appears:

$ exbash command to run the "ex" program.
: iex command to "insert" some text.
Hello!
.A line with just a dot tells ex to stop inserting text.
: w greeting.txtex command to "write" the text to a file.
"greeting.txt" [New] 1L, 7C written
: qex command to "quit" the program.
$ cat greeting.txtAnd now we're back in bash!
Hello!The "cat" program shows the contents of the file.
$ 

Notice how in this session, we started out by giving bash the command to start the ex file editor. After issuing this command, our prompt changed: any text we enter now is sent to ex, not to bash. While ex is running, bash is asleep waiting for your ex session to end. When you quit ex using the q command, the ex bash command ends and bash is ready to receive a new command. To tell you this, it shows you its prompt again, allowing you to enter the next bash command. We finish the example with a cat greetings.txt bash command which tells bash to run the cat program. The cat program is great for outputting file contents (its name is short for concatenate, because its purpose is to output the contents of all the files you give it, one after the other, effectively concatenating the contents in its output). The cat command in the example is used to find out what is in our greetings.txt file after we're done editing it with the ex program.

A bash command is the smallest unit of code that bash can independently execute. While executing a command, you cannot interact with the bash shell. As soon as bash is done executing a command, it returns to you for the next command to execute.

How do I give bash a command?

We've been showing quite a few examples now of running commands in bash, so you probably already have a good idea about how one issues basic commands in bash at the prompt.

Bash is mostly a line-based language. Accordingly, when bash reads your commands, it does so line-by-line. Most commands will only constitute one line and, unless the syntax of your bash command explicitly indicates that your command is not yet complete, as soon as you end that line, bash will immediately consider that to be the end of the command. As a result, typing a line of text and hitting the ⏎ key will generally cause bash to start performing the command described by your line of text.

Some commands however, span multiple lines. These are usually block commands or commands with quotes in them:

$ read -p "Your name? " nameThis command is complete and can be started immediately.
Your name? Maarten Billemont
$ if [[ $name = $USER ]]; thenThe "if" block started but wasn't finished.
>     echo "Hello, me."
> else
>     echo "Hello, $name."
> fiNow the "if" block ends and bash knows enough to start the command.
Hello, Maarten Billemont.

Logically, bash cannot execute a command until it has enough information to do its job. The first line of the if command in the example above (we'll cover what these commands do in more detail later on) doesn't contain enough information for bash to know what to do if the test succeeds or if it fails. As a result, bash shows a special prompt: >. This prompt essentially means: the command you gave me is not yet at an end. We keep on providing extra lines for the command, until we reach the fi construct. When we end that line, bash knows that you're done providing conditional result cases. It immediately begins running all the code in the entire block, from if to fi. We will soon see the different kinds of commands defined in bash's grammar, but the if command we just saw is called a Compound Command, because it compounds a bunch of basic commands into a larger logical block.

In each of these cases, we're passing our commands to an interactive bash session. As we explained before, bash can also run in non-interactive mode where it reads commands from a file or stream rather than asking you for them. In non-interactive mode, bash doesn't have a prompt. Aside from that, it operates pretty much the same. We could copy the bash code from the example above and put it in a text file instead:

read -p "Your name? " name
if [[ $name = $USER ]]; then
    echo "Hello, me."
else
    echo "Hello, $name."
fi

It doesn't matter much what you name the file in which you save the code. Let's say you saved it in a file called hello.txt, we can now run the commands from that file using bash without it having to ask us for instructions:

$ bash hello.txtThis starts a new "bash" process.
Your name? Maarten Billemont
Hello, Maarten Billemont.Our new "bash" process ends when there is no code left in the file.
$ Now that the "bash" command is done, our interactive bash comes back.

Notice that two bash processes are involved in this example. The bash process we start off from is our regular interactive shell. We tell that bash process to run a command which will cause it to start a new bash process. This second bash process will execute all the commands it finds in the file hello.txt, non-interactively. When it's done (there are no commands left in the file), the non-interactive bash process ends and the interactive bash process is ready with your bash hello.txt command; it shows a new prompt asking you for the next command to run.

It's only a small step from a file with a list of commands in it to a veritable bash script. Open your hello.txt file again using your favourite text editor and add a hashbang to the top of it, as the first line of the script: #!/usr/bin/env bash

#!/usr/bin/env bash
read -p "Your name? " name
if [[ $name = $USER ]]; then
    echo "Hello, me."
else
    echo "Hello, $name."
fi

Congratulations! You've created your first bash script. What's a bash script? It's a file with bash code in it that can be executed by the kernel just like any other program on your computer. In essence, it is a program in itself, although it does need the bash interpreter to do the work of translating the bash language into instructions the kernel understands. That's where this "hashbang" line we've just added to the file comes in: It tells the kernel what interpreter it needs to use to understand the language in this file, and where to find it. We call it a "hashbang" because it always begins with a "hash" # followed by a "bang" !. Your hashbang must then specify an absolute pathname to any program that understands the language in your file and can take a single argument. Our hashbang is a little special, though: We reference the program /usr/bin/env, which isn't really a program that understands the bash language. It's a program that can find and start other programs. In our case, we use an argument to tell it to find the bash program and use that for interpreting the language in our script. Why do we use this "inbetween" program called env? It has everything to do with what comes before the name: the path. We know with relative certainty that the env program lives in the /usr/bin path. Given the large variety of operating systems and configurations, however, we don't have any good certainty about where the bash program is installed. Which is why we use the env program to find it for us. That was a little complicated! But now, what's the difference between our file before and after adding the hashbang?

$ chmod +x hello.txtMark hello.txt as an executable program.
$ ./hello.txtTell bash to start the hello.txt program.

Most systems require you to mark a file as executable before the kernel is willing to allow you to run it as a program. Once we do that, we can start the hello.txt program like we would any other program. The kernel will look inside the file, find the hashbang, use that to track down the bash interpreter, and finally use the bash interpreter to start running the instructions in the file. You have your first real bash program!

Bash gets commands by reading lines. As soon as it's read enough lines to compose a complete command, bash begins running that command. Usually, commands are just a single line long. An interactive bash session reads lines from you at the prompt. Non-interactive bash processes read their commands from a file or stream. Files with a hashbang as their first line (and the executable permission) can be started by your system's kernel like any other program.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK