Bash Shell 脚本新手指南（一）
Bash 脚本
![](/data/attachment/album/202112/30/101441k82y3n33j5jijn2e.jpg)


如标题所示，本文将涵盖面向初学者的 Bash Shell 脚本知识。虽然本文没有回顾 Bash 的历史，但是有很多资源能够便于读者了解相关内容，读者也可以直接访问 <https://www.gnu.org/software/bash/> 上的 GNU 项目。我们会从了解一些非常基本的概念开始，然后再将相关知识综合起来。


### 创建脚本文件


首先来创建一个脚本文件。我们要确保当前目录为家目录。



```
cd ~

```

在主目录中创建示例文件。文件名可以是任意名称，本文使用 `learnToScript.sh` 作为文件名。



```
touch learnToScript.sh

```

此时家目录中就生成了一个名为 `learnToScript.sh` 的文件。输入以下命令以检验该文件是否存在，还可以注意到其权限是 `-rw-rw-r–`。



```
[zexcon@trinity ~]$ ls -l
total 7
drwxr-xr-x. 1 zexcon zexcon   90 Aug 30 13:08 Desktop
drwxr-xr-x. 1 zexcon zexcon   80 Sep 16 08:53 Documents
drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads
-rw-rw-r--. 1 zexcon zexcon   70 Sep 17 10:10 learnToScript.sh
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Music
drwxr-xr-x. 1 zexcon zexcon  318 Sep 15 13:53 Pictures
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Public
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Videos
[zexcon@trinity ~]$

```

正式开始之前还有一件事要做。可以试一下在没有写入任何内容的情况下执行脚本，命令行输入以下内容：



```
./learnToScript.sh

```


```
[zexcon ~]$ ./learnToScript.sh
bash: ./learnToScript.sh: Permission denied

```

提示权限被拒绝，因为该文件没有执行权限。所以你需要更改文件的权限才能执行脚本。如果你不熟悉权限相关知识，建议阅读 [Paul W. Frields](http://pfrields.id.fedoraproject.org/) 写的 Fedora 杂志文章。


* [命令行小知识：权限](https://fedoramagazine.org/command-line-quick-tips-permissions/)
* [命令行小知识：深入权限](https://fedoramagazine.org/command-line-quick-tips-more-about-permissions/)


假定我们已经了解了权限相关知识，回到终端更改 `learnToScript.sh` 文件，增加执行权限。输入以下内容：



```
chmod 755 learnToScript.sh

```


```
[zexcon@trinity ~]$ ls -l
total 7
drwxr-xr-x. 1 zexcon zexcon   90 Aug 30 13:08 Desktop
drwxr-xr-x. 1 zexcon zexcon   80 Sep 16 08:53 Documents
drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads
-rwxr-xr-x. 1 zexcon zexcon   70 Sep 17 10:10 learnToScript.sh
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Music
drwxr-xr-x. 1 zexcon zexcon  318 Sep 15 13:53 Pictures
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Public
drwxr-xr-x. 1 zexcon zexcon    0 Jul  7 16:04 Videos
[zexcon@trinity ~]$

```

好的，现在一切准备就绪，你已经获得了 `learnToScript.sh` 命令的读取、写入和执行权限 （`-rwxr-xr-x`）。


### 编辑脚本文件


下面的内容需要你熟悉 `vim` 或其他类似的文本编辑器，本文选用 `vim`。在命令提示符下输入以下内容：



```
vim learnToScript.sh

```

这会打开一个空的文本文件，里面有一堆波浪号。键盘输入 `i` 将进入插入模式。通过查看终端窗口的左下角，你可以确认它处于该模式。（友情推荐，[nano](https://fedoramagazine.org/gnu-nano-minimalist-console-editor/) 编辑器也很不错。）


接下来我们要确保文件被正确的解释器识别。因此，输入 `#!` 和 bash 的目录 `/bin/bash`：



```
#!/bin/bash

```

本文教程步骤的最后一件事是保存文档。按 `Esc` 退出输入模式，然后按 `Shift+:`。在冒号处输入 `wq`，按下回车键，就会写入（`w`）文件并退出（`q`）`vim` 编辑器。



> 
> 使用 `vim` 时要记住，要想写入文档，就需要输入 `i`，此时你会在底部看到 `–INSERT–`。要保存文档，就需要按 `Esc` 退出输入模式，然后按 `Shift+:`，输入 `w` 写入文件；或者按 `Esc`，然后 `Shift+:` 输入 `q`，实现退出而不保存；或者将 `wq` 连在一起，可以实现写入并关闭文件。`Esc` 本身就只是退出插入模式。你可以在其 [官方网站](https://www.vim.org/docs.php) 或 [教程网站](https://linuxhandbook.com/basic-vim-commands/) 上找到更多关于 `vim` 的信息。
> 
> 
> 


### 开始正式写脚本


#### echo 命令


`echo` 命令用于向终端返回一些信息，可以使用单引号、双引号或不使用引号。那么让我们用一个传统的 Hello World 来试试它！



```
#!/bin/bash

echo Hello World!
echo 'Hello World!'
echo "Hello World!"

```


```
[zexcon ~]$ ./learnToScript.sh
Hello World!
Hello World!
Hello World!
[zexcon ~]$

```

注意，上述三行得到了相同的结果。使用单引号、双引号或不使用引号的结果不是一定相同的，但在这个基本脚本中确实得到了同样的结果。在某些情况下，引号的类型不同会导致结果差异。至此恭喜你编写了第一个 Bash 脚本。当你继续创建更多脚本并放飞你的想法时，可能会需要了解以下更多的知识。


#### 命令替换 $( ) 和 ` `


命令替换可以实现以下效果：获取在命令行执行命令的结果，并将该结果写入变量。例如，如果在命令提示符下输入 `ls`，可以获得当前工作目录的列表。我们用这个命令来实践一下。命令替换选项有两个，请注意：第一个选项使用键盘左侧 `Tab` 键上方的反引号。它与波浪号 `~` 在一个键位上。第二个选项使用 shell 变量。



```
#!/bin/bash

command1=`ls`
echo $command1

command2=$(ls)
echo $command2

```


```
[zexcon ~]$ ./learnToScript.sh
Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos
Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos
[zexcon ~]$

```

注意变量、等号和命令开头之间不要有空格。使用这两个选项得到的结果是完全相同的。请注意，变量需要以美元符号开头。如果你忘记了，并且回显了不带美元符号的命令变量，会只输出命令的名称，如下所示：



```
#!/bin/bash

command1=`ls`
echo command1

command2=$(ls)
echo command2

```


```
[zexcon ~]$ ./learnToScript.sh
command1
command2
[zexcon ~]$

```

#### 双括号 (())


那么双括号有什么用呢？ 很简单，双括号用于数学方程式。



```
#!/bin/bash

echo $((5+3))
echo $((5-3))
echo $((5*3))
echo $((5/3))

```


```
[zexcon ~]$ ./learnToScript.sh
8
2
15
1
[zexcon ~]$

```

### 结语


至此，我们已经创建了第一个脚本。我们知道了如何执行多个命令：将它们放在一个脚本中并运行，就可以获得结果。下一篇文章会继续讨论，了解输入和输出的重定向、管道命令、使用双括号或者添加注释等知识。




---


via: <https://fedoramagazine.org/bash-shell-scripting-for-beginners-part-1/>


作者：[zexcon](https://fedoramagazine.org/author/zexcon/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[unigeorge](https://github.com/unigeorge) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
As the title implies this article will be covering Bash Shell Scripting at a beginner level. I’m not going to review the history of Bash but there are many resources to fill you in or you can visit the GNU project at [https://www.gnu.org/software/bash/](https://www.gnu.org/software/bash/). We will start out with understanding some very basic concepts and then start to put things together.

### Creating a script file

The first thing to do is create a script file. First make sure the home directory is the current directory.

cd ~

In the home directory, create the example file. This can be named anything but *learnToScript.sh* will be used in this article.

touch learnToScript.sh

From this point there will be a file called *learnToScript.sh* in your home directory. Verify it exists and also notice the privileges for that file are -rw-rw-r– by typing the following.

ls -l

[zexcon@trinity ~]$ ls -l total 7 drwxr-xr-x. 1 zexcon zexcon 90 Aug 30 13:08 Desktop drwxr-xr-x. 1 zexcon zexcon 80 Sep 16 08:53 Documents drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads -rw-rw-r--. 1 zexcon zexcon 70 Sep 17 10:10 learnToScript.sh drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Music drwxr-xr-x. 1 zexcon zexcon 318 Sep 15 13:53 Pictures drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Public drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Videos [zexcon@trinity ~]$

There is one more thing that needs to be done to get started. Let’s try and execute the script with nothing written in it. Type the following:

./learnToScript.sh

[zexcon ~]$ ./learnToScript.sh bash: ./learnToScript.sh: Permission denied

You get permission denied because there are no execute permissions on the file. You need to change the permissions of the file to be able to execute the script. If you are not familiar with permissions I would recommend reading the Fedora Magazine articles written by Paul W. Frields:

[Command line quick tips: Permissions]

[Command line quick tips: More about permissions]

At this point you’ve brushed up on permissions, so back to the terminal and let’s change the *learnToScript.sh* file so it will execute. Type in the following to allow execution of the file.

chmod 755 learnToScript.sh

[zexcon@trinity ~]$ ls -l total 7 drwxr-xr-x. 1 zexcon zexcon 90 Aug 30 13:08 Desktop drwxr-xr-x. 1 zexcon zexcon 80 Sep 16 08:53 Documents drwxr-xr-x. 1 zexcon zexcon 1222 Sep 16 08:53 Downloads -rwxr-xr-x. 1 zexcon zexcon 70 Sep 17 10:10 learnToScript.sh drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Music drwxr-xr-x. 1 zexcon zexcon 318 Sep 15 13:53 Pictures drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Public drwxr-xr-x. 1 zexcon zexcon 0 Jul 7 16:04 Videos [zexcon@trinity ~]$

Okay now you’re ready, you have read, write and execute permissions (-rwxr-x r-x) to the *learnToScript.sh* command.

### Editing a script file

Take a moment and make certain you are familiar with *vim* or any text editor. Throughout this article I will be utilizing *vim*. At the command prompt type the following:

vim learnToScript.sh

This will bring you to an empty text file with a bunch of tildes in it. Type *i* on your keyboard and this will move you into — INSERT — mode. You can see it’s in this mode by looking at the bottom left of the terminal window. (Note that an alternative editor is the [ nano editor](https://fedoramagazine.org/gnu-nano-minimalist-console-editor/).)

From here you need to make sure that the file is recognized by the correct interpreter. So enter the shebang ( #! ) and the directory to your bash, /bin/bash:

#!/bin/bash

One last thing that you will use throughout the article is saving the document. Hit *Esc* to leave input mode, then Shift + Colon. At the colon you will enter *wq*. This will write(*w*) the file and quit(*q*) *vim* once you hit enter.

A few things to remember while using *vi*m, anytime you want to write into a document you need to enter *i* and you will see –INSERT– at the bottom. Anytime you want to save, you will need to hit *Esc* to leave input mode, and then *Shift+:* to enter *w* to write the file or *Esc* then *Shift+: *to enter *q* to quit and not save. Or add both *wq* together and it will write and close. *Esc* by itself will exit INSERT mode. You can find much more about *vim* at it’s [website](https://www.vim.org/docs.php) or this [get started](https://linuxhandbook.com/basic-vim-commands/) site.

## Lets start scripting…

### echo

The *echo* command is used to return something to the terminal. You will notice that you can use single quotes, double quotes or no quotes. So let’s take a look at it with a traditional Hello World!

#!/bin/bash echo Hello World! echo 'Hello World!' echo "Hello World!"

[zexcon ~]$ ./learnToScript.sh Hello World! Hello World! Hello World! [zexcon ~]$

Notice that you get the same result with all three options. This is not always the case but in this basic script it is. In some circumstances the type of quotes will make a difference. By the way, congratulations you have written your first Bash script. Let’s look at a few things that you will want to know as you continue to create more scripts and let your mind run wild.

### Command Substitution $( ) or ` `

Command substitution allows you to get the results of a command you might execute at the command line and write that result to a variable. For example if you type* ls* at the command prompt you will get a list of the current working directory. So let’s put this into practice. You have two options for command substitution. Note that the first option uses a back tick found above the Tab key on the left side of the keyboard. It is paired with the tilde ~ key. The second option uses a shell variable.

#!/bin/bash command1=`ls` echo $command1 command2=$(ls) echo $command2

[zexcon ~]$ ./learnToScript.sh Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos Desktop Documents Downloads learnToScript.sh Music Pictures Public snap Videos [zexcon ~]$

Notice no space between the variable, equal sign, and the start of the command. You get the exact same result with both options. Note that variables need to be led by a dollar sign. If you forget and you echo out the command variable without the dollar sign you will just see the name of the command as shown in the next example.

#!/bin/bash command1=`ls` echo command1 command2=$(ls) echo command2

[zexcon ~]$ ./learnToScript.sh command1 command2 [zexcon ~]$

### Double Parentheses (())

So what are double parentheses for? Double parentheses are simple, they are for mathematical equations.

#!/bin/bash echo $((5+3)) echo $((5-3)) echo $((5*3)) echo $((5/3))

[zexcon ~]$ ./learnToScript.sh 8 2 15 1 [zexcon ~]$

## Conclusion

At this point we have created our first script. We have an idea how to take several commands, place them in a script and run it to get the results. We will continue this discussion in the next article and look at redirection of input and output, the pipe command, using double brackets or maybe just adding some comments.

## Athan

The chmod command is inconsistent with what the targeted outcome is.

## Stephen Snow

Hello, good catch,

~~I changed it to “chmod 755~~ to be consistent with the results displayed . Oops, it was correct originally so I retracted my change.## Donald Sebastian Leung

Wouldn’t it be better to change both (1) the command to

and (2) the output of

to match the command?

permissions is weird (and insecure) because anyone can edit your script, even if you are the only one that can execute it.

Or just

and you don’t have to worry about accidentally making your script world-writable.

## Richard England

That was missed in editing. It has been corrected.

## Bthan

It’s still wrong. The listing says “-rwxrw-rw-” but below the listing you say “execute permissions (-rwxr-xr-x)”.

Chmod 766 is wrong. 6 is read and WRITE, so a security issue that others can alter your script on the fly. Use 755 instead.

Why don’t you use “chmod +x” to give execute permissions?

Oh, and BTW. the link to Paul W. Fields is broken too.

## Richard England

Corrections were made for the permissions. But the links to the other articles appear to be correct. What are you seeing when attempting to view them?

## Bthan

Actually, the link is not broken, but it’s an empty page.

The link to Paul’s profile:

“… recommend reading the Fedora Magazine articles written by Paul W. Frields.”

The page says:

This page is primarily used internally

## Richard England

The link to Paul W. Frields should not have been a link. The two images (that are links to the two articles) are the important part. The OpenID link has been removed.

## Scott Auge

LOL I read it because there is “always a sentence of interest reading” and that’s the truth, because $(()) was new to me and I had read two bash manuals!

## Daniel

Good.

## Breno

I would recommend

instead of

at a beginner level. Also,

sounds more intuitive for a beginner to me.

## Thuur

You can also check this permission site :

http://permissions-calculator.org/

## Anil F Duggirala

Thanks so much for this. Always been curious about these scripts. Thanks for allowing me to get into it so smoothly.

I already know vim, I hope your other readers don’t get lost or discouraged by getting stuck with vim. Also, keep in mind that there are various different keyboard layouts, not just US English.

thanks so much,

## zexcon

Thank you I’ve added the specification into the next article for clarification on the keyboard.

## person

Why do i have to be at ~

## Joao Rodrigues

You don’t

haveto be at ~. You can place your script anywhere you have write permission.You could, for example, place it in ~/.local/bin or ~/bin. These directories are ususally in your $PATH, so you could call your script from any directory by just typing “learnToScript.sh” instead of “~/learnToScript.sh”

## zexcon

You don’t have to be in your home directory. This is only for simplicity of the article. You can place your script any place you just need to specify the path or be in the location to run the script.

## Smackeyacky

The file listing of the directory containing your script shows the right permissions for chmod 766, but the text underneath says you wanted rwxr-xr-x which is 755. Change the command to 755 and fix the listing of files and it will be consistent.

## Darvond

While I’d

suggest vim for a beginner, I do understand it is the defacto. (For some reason; though it and emacs have been outmoded for years in terms of sheer sanity by others.)neverBut! Fedora’s default editor is nano; should that not be the editor invoked accordingly?

Instead of the one that requires complex

bespoke keystrokesjust to enter insertion mode?## Richard England

For some (perhaps many) vi/vim is what they know and it was the standard editor for some time. A note has been added pointing out that nano is an alternative. The point of the article was not the editor to use rather the script that was being created.

But thank you for your input.

## Brian

I never had any trouble using vim or vi when I was teaching myself to program from the command line. What is the point in trying to discourage beginners from learning something that is NOT THAT DIFFICULT in the first place? Entering insertion mode in vi or vim requires — i . Leaving insertion mode requires the– Esc — the escape key. This is difficult ? Saving a file requires– :wq and the name of the file if it’s a new file — :wq ./Boogers

Quiting without saving requires– :q! How hard is that? Personally, I don’t like nano at all.

Aside from that, I’ve had Fedora on my box for 20 years, and I never had nano installed at all until last year.

## Darvond

Beg pardon from someone born after the German Reunification and ergo; the Emacs/Vim Holy Wars.

The way my opinion flows is this: When people open an editor, they want to

edit. Drop in, start typing.But it may also be worth noticing that no graphical editor really goes out of their way to emulate vi because you just focus the window

and type.Even ancient tools from the other side of the force like QBASIC’s Editor didn’t require anything weird to get going.

## Richard England

…and the wars continue. 🙂

## Inci

Great intro! Looking forward for part 2.

## edier88

Great!

This is really important for sysadmins and developers.

Looking forward for the next parts!

## Stathis

You might want to consider changing the shebang line of the script to

This seems to be preferred nowadays.

As it does not assume “bash” to be present in a specific directory it helps promote portability.

## Joao Rodrigues

Well, that just assumes “env” is present in /usr/bin

You have to put an absolute path in the hashbang. You have to start assuming something at some point. If for some reason bash is not in /bin, a more sensible approach would be just to symlink bash in /bin.

## Bryan

Very nice article sir

## Putin

Unrelated to the above topic at hand, I wish to say that I now love Fedora. Been using Ubuntu and its derivatives for the past 20 years until a couple of weeks ago where I just happened to stumble upon the Distrowatch website. Yes, I never knew it existed. Wanted a change of scene and somehow Fedora looked very enticing. Got it installed on main machine without a second thought. Loving it. The community is fantastic. Keep it up folks.

## Pedgerow

Thanks for this! Please explain how to take input in a future article. I have never been sure about how to do this, but I assume it’s very basic. By this I mean, how can I pass an argument to a Bash script? Like if I wanted to write a script that did the same as “echo”, and it only contained one command and that was “echo $input”, what else would I need to put in the script to make it work?

Also, does it have to start with #!/bin/bash, or can it start with something else? What if I put the script file (echov2.sh or whatever) in a different path? It would be very cool if you could answer these questions in a future article.

## Gregory Bartholomew

The words (parameters) passed to the script on the command line are available in the numbered variables $1, $2, $3, etc. If you want them all at once, you can use $*. So in your script, you would put “echo $*”. There is also a $@ that you may see used from time to time. It is similar to $* but it “tokenizes” the parameters a little differently. But that is a more advanced topic. 🙂

## Dietmar

If you ever consider to look into

bash, shellscriptingor just the bestLinuxCLI tutorials of all times – ask your search engine forMachtelt Garrels, Bash Guide for Beginners

and

Mendel Cooper, Advanced Bash-Scripting Guide

to be found here:

https://tldp.org/guides.html

For me this is the greatest IT – literature of all times.

A reference and a tutorial and an introduction and a specialists treasure trove in one.

Second to none.

Give it a try! Fell in love with bash scripting …