xDroid's Blog

20.0 shell语言 (从新手到菜鸟的Linux教程)

忙里偷闲写点东西……想了想好像也快没什么好写了(尴尬),于是挖个大坑吧,看看什么时候能填完。

那么就来接触一下 bash 的语法吧。

bash 是不是在第三篇的时候提到过来着?那一篇似乎只说了 echo 。翻了一下我之前学 bash 语法的网页,是这篇,觉得讲的挺好的 意思是估计接下来的教程全都得抄 。那么我们就开始吧。


首先明确几件比较重要的事情:

  • shell 语言(和它的后继者们)都是 脚本语言 ,所谓 脚本语言 就是可以不用编译直接运行的;因此,脚本语言有一个非常重要的特点,就是可以在到运行时才确定句子的赋值,换句话说就是可以在运行到某句话的时候才“写出”它的样子然后马上执行,或者干脆“拼凑”出一句程序运行
  • shell 就是这个语言的 REPL ,也即是说怎么在终端输入就可以怎么在脚本里写
  • 由于是弱类型语言(所有变量均视为字符串),加上动态生成程序的样子,因此实际运行的程序的模样可能和写的时候千差万别

总之弱类型还是系统相关就导致这语言使用不当会很危险~~


首先开始写第一个 shell 脚本吧!

$ nano hello_world.sh # or `vim hello_world.sh`

然后输入

#!/bin/sh
echo "Hello World!"

开头的一行叫 释伴(shebang) (这是我见过的信达雅的翻译之一),用来表明以下的程序由 /bin/sh 来执行(反正 sh 被软链接到 bash 上)。接下来的程序就与平时我们所见的 shell 命令没什么区别了;命令行下输入的命令与脚本里被解释的命令运行模式几乎是一样的。


然鹅怎么运行呢,记得当年菜鸟的自己也是遇到了“千古难题”:

$ hello_world.sh
sh: command not found: hello_world.sh

不就在目录下吗,为什么找不到呢?因为这样直接写出来的命令, bash 会到 $PATH 中去找(可以理解成一个 yindian 的路径),而当前目录一般都不会在钦定的系统目录中(对吧),自然找不到啦。

那怎么才能找到呢?很简单,指定该文件是 ./hello_world.sh 是当前目录下的这个文件就可以了

$ ./hello_world.sh
sh: permission denied: ./hello_world.sh

黑人问号?怎么权限拒绝了呢?明明可以读可以写啊?原来 Unix/Linux 除了读写之外还有第三种权限是 可执行权限 ,没有可执行权限自然是不能运行该脚本的啦。为了赋予我们能够执行这个文件,我们要用到 chmod

$ chmod +x hello_world.sh 
$ ls -l hello_world.sh 
-rwxr-xr-x 1 xdroid users 33 Jan 19 09:49 hello_world.sh

+x 参数的意思是给所有人都增加执行这个文件的权限,用 ls -l 可以看到文件详细的情况。现在就可以执行了。

$ ./hello_world.sh 
Hello World!

既然能输出,那怎么输入呢?用 read 呗:

$ vim hello_world.sh
#!/bin/sh
echo "Please enter you name : "
read NAME
echo "Your name is $NAME. Bye."

运行一下试试

$ ./hello_world.sh 
Please enter your name : 
xDroid
Your name is xDroid. Bye.

想想也知道 read NAME 的作用是将输入的一行读到 NAME 这个变量里去,可是为什么下一行使用的时候还要在变量名前加 $ 号呢?我们下一篇说这个事情。


P.S. 关于释伴

别以为释伴只能写 #!/bin/sh 哦!除了 #!/usr/bin/python 这一类脚本语言解释器以外,其实什么命令都是可以的~~(以下摘抄自维基百科)

由于 shebang 开头的井号也是 Bourne shell 和许多其它解释性语言的注释符,因此在这些语言中,解释器指令本身会被解释器认为是单纯的注释而跳过。 然而,并不是每一种解释器都会自动忽略 shebang 行,例如对于下面的脚本,

#!/bin/cat
Hello world!

cat 会把文件中的两行都输出到标准输出中。

我理解下来意思是说 shebang 之后可以跟任意的命令,然后运行这个脚本的时候这个文件会作为参数传给这个命令。除了 cat 的这个例子之外我还准备了一个例子:

#!/usr/bin/sort
1
2
3

将这个文件保存为 test.sh,赋予可执行权限,再运行一下:

$ chmod +x test.sh
$ ./test.sh 
1
2
3
#!/usr/bin/sort

看,它将 shebang 一起排序进去了。