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 一起排序进去了。