shell脚本的基本格式第一行是指用什么shell,第二行是注释。剩下的是脚本处理内容。
#!/bin/bash
# This script displays the date and who's logged on
date
who
这样一个简单的shell脚本就构建完成了。可以根据需要,使用分号将两个命令放在一行上,但在shell脚本 中,你可以在独立的行中书写命令。shell会按根据命令在文件中出现的顺序进行处理。 尝试使用这个脚本,但是会报错
-bash: test1: command not found
shell执行的时候,是根据PATH当中的路径逐一循环查找各目录下有没有这个可执行文件。我们创建了这个脚本,但是脚本所在的目录并没有在PATH路径当中,所以无法执行。这种时候咋办呢?
- 将shell脚本文件所处的目录添加到PATH环境变量中;
- 在提示符中用绝对或相对文件路径来引用shell脚本文件。 那么继续
[root@vultr /]# ./test1
-bash: ./test1: Permission denied
又报错了……这次是为啥,查看一下脚本的权限。
-rw-rw-r-- 1 user user 73 Sep 24 19:56 test1
原来是没有执行的权限,那么久给他执行的权限chmod u+x test1
再执行这个脚本
Wed Dec 26 17:34:50 CST 2018
root pts/1 2018-12-26 11:03 (115.206.55.15)
终于执行成功了,也是不容易啊。
用echo输出一串字符串的时候是不需要引号的。但是假如这个字符串当中有引号,那么我们要用合适的引号将这个字符串包裹起来,才能正确的输出内容。
$ echo 'Rich says "scripting is easy".'
Rich says "scripting is easy".
稍微修改一下脚本
#!/bin/bash
# This script displays the date and who's logged on
echo The time and date are:
date
echo "Let's see who's logged into the system:"
who
The time and date are:
Wed Dec 26 17:47:57 CST 2018
Let's see who's logged into the system:
root pts/1 2018-12-26 11:03 (115.206.55.15)
想要输出在同一行,可以给echo命令加-n参数。
系统定义了很多全局变量,我们可以把这些变量用到脚本当中去。
#!/bin/bash
# display user information from the system.
echo "User info for userid: $USER"
echo UID: $UID
echo HOME: $HOME
User info for userid: root
UID: 0
HOME: /root
echo命令中的环境变量会在脚本运行时替换成当前值。假如我们在脚本中输出美元符号,可以使用转义符(\)。
你可能还见过通过${variable}形式引用的变量。变量名两侧额外的花括号通常用来帮 助识别美元符后的变量名。
我们也可以在脚本当中自定义一些变量使用
#!/bin/bash
# testing variables
days=10
guest="Katie"
echo "$guest checked in $days days ago"
days=5
guest="Jessica"
echo "$guest checked in $days days ago"
Katie checked in 10 days ago
Jessica checked in 5 days ago
重要的是要记住,引用一个变量值时需要使 用美元符,而引用变量来对其进行赋值时则不要使用美元符。
value1=10
value2=$value1
echo The resulting value is $value2
有两种方式可以将shell的命令赋值给变量。一种是反引号(`),另一种是$()
。
[root@vultr /]# echo $test
Wed Dec 26 18:00:44 CST 2018
[root@vultr /]# test1=$(date)
[root@vultr /]# echo $test1
Wed Dec 26 18:00:59 CST 2018
命令替换会创建一个子shell来运行对应的命令。子shell(subshell)是由运行该脚本的shell 所创建出来的一个独立的子shell(child shell)。正因如此,由该子shell所执行命令是无法 使用脚本中所创建的变量的。
在命令行提示符下使用路径./运行命令的话,也会创建出子shell;要是运行命令的时候 不加入路径,就不会创建子shell。如果你使用的是内建的shell命令,并不会涉及子shell。
在命令行提示符下运行脚本时一定要留心!
重定向输出,我们想将一个输出放入一个文件,可以使用大于号。
格式 command > outputfile
$ date > test6
$ ls -l test6
-rw-r--r-- 1 user user 29 Feb 10 17:56 test6
$ cat test6
Thu Feb 10 17:56:58 EDT 2014
假如原本不存在这个文件,这个命令就会新建一个文件,假如原本就存在这个文件,那么会将该文件原本的内容覆盖掉。倘若不想把原本的内容覆盖,只是想追加在文件末尾,可以用>>
符号。
输入重定向符号是小于号(<):
command < inputfile
[root@vultr /]# wc < test2
2 12 58
wc命令可以对对数据中的文本进行计数。默认情况下,它会输出3个值:
- 文本的行数
- 文本的词数
- 文本的字节数
还有另外一种输入重定向的方法,称为内联输入重定向(inline input redirection)。用<<
,和php当中的一种定义长字符串的方式非常相似。
管道符号(|)这将非常有用。
该符号由两个 竖线构成,一个在另一个上面。然而管道符号的印刷体通常看起来更像是单个竖线(|)。
在美式 键盘上,它通常和反斜线(\)位于同一个键。管道被放在命令之间,将一个命令的输出重定向 到另一个命令中:
command1 | command2
不要以为由管道串起的两个命令会依次执行。Linux系统实际上会同时运行这两个命令,在 系统内部将它们连接起来。在第一个命令产生输出的同时,输出会被立即送给第二个命令。数据 传输不会用到任何中间文件或缓冲区。
使用方括号来计算加减乘除。
[root@vultr /]# var1=$[1+6]
[root@vultr /]# echo $var1
7
[root@vultr /]# var2=$[$var1 * 2]
[root@vultr /]# echo $var2
14
不过这些都只能用来整数的算法,想要进行浮点型的计算,得用bc
。
假如报错没有bc那么安装一个yum install bc
计算浮点数,有一个scale
控制着期望获得小数位数。
[root@vultr /]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1*0.1
.1
quite
0
quit
#!/bin/bash
var1=10.46 var2=43.67 var3=33.2 var4=71
var5=$(bc << EOF
scale = 4
a1 = ( $var1 * $var2)
b1 = ($var3 * $var4)
a1 + b1
EOF
)
echo The final answer for this mess is $var5
linux的退出码,执行完毕立刻用$?
查看。
退出码 | 描述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shell命令 |
126 | 命令不可执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与Linux信号x相关的严重错误 |
130 | 通过Ctrl+C终止的命令 |
255 | 正常范围之外的退出状态码 |
shell脚本的基础……
To be continue……