为什么要用脚本语言?
以Linux系统为例,linux系统里面有很多个命令,脚本可以是一个或者多个命令的集合,通过运行脚本,达到既定的功能或者效果。
shell与批处理的比较:
Linux环境下有个脚本语言叫做shell,一般的,shell脚本文件以.sh结尾,.sh并没有什么实际作用,只是用来标识这是一个shell脚本语言。
windows环境有个脚本语言叫批处理,以.bat结尾,windows环境下的.bat有其特定作用,因为.bat的标识可通过MIME协议调用指定的应用程序来解释
介绍完背景,就直接开始shell脚本的编写之旅。
国际惯例:第一个程序必须是hello world!
#!/bin/bash
echo "hello world!"
#! 是一个特定的标记,用来告诉系统这个脚本需要用什么程序来执行
保存为shell.sh,然后运行
此时发现权限不够,通过ls -ls指令查看shell.sh的详细信息
发现没有执行权限,因此要修改shell.sh的权限,可通过chmod指令修改,至少加入执行权限
建议修改shell脚本权限的时候在shell脚本前加./,即当前目录下查找,否则会在PATH下开始查找,避免不必要的麻烦。
运行脚本:
[root@localhost /]# ./shell.sh
hello world!
系统给定的特殊变量:
变量名 | 作用 |
$0 | 当前脚本的名字 |
$n | 传递给脚本或者函数的参数,n表示第几个参数 |
$# | 传递给脚本或函数的参数个数 |
$* | 传递给脚本或函数的所有参数 |
$@ | 传递给脚本或者函数的所有参数 |
$$ | 当前shell脚本进程的PID |
$? | 函数返回值,或者上个命令的退出状态 |
$BASH | BASH的二进制文件问的路径 |
$BASH_ENV | BASH的启动文件 |
$BASH_VERSINFO[n] | BASH版本信息,有六个元素 |
$BASH_VERSION | BASH版本号 |
$EDITOR | 脚本所调用的默认编辑器 |
$EUID | 当前有效的用户ID |
$FUNCNAME | 当前函数名 |
$GROUPS | 当前用户所属组 |
$HOME | 当前用户家目录 |
$HOSTTYPE | 主机类型 |
$LINENO | 当前行号 |
$OSTYPE | 操作系统类型 |
$PATH | PATH路径 |
$PPID | 当前shell进程的父进程ID |
$PWD | 当前工作目录 |
$SECONDS | 当前脚本运行秒数 |
$TMOUT | 不为0时,超过指定的秒将退出shell |
$UID | 当前用户ID |
$* 和 $@ 的区别
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
定义变量:
字符串变量:string="value",string为变量名,value为字符串
数字变量:num=5,其中num为变量名,5为其对应的值
注意:
1、定义变量时不加$,使用时要加$,用以区别字符串,变量名用{}括来是个好习惯,shell会将花括号里面的字符解释为一个整体,后面将数组的时候会体现。
2、不要在等号两边加上空格,否则将会报错!
测试代码:
#! /bin/bash执行结果:
string="I am shell"
num=5
echo "a=${a},string=${string}"
[root@localhost /]# ./shell.sh
a=,string=I am shell
变量定义时等号两边加空格测试:
[root@localhost /]# cat shell.sh
#! /bin/bash
string = "I am shell"
num = 5
echo "a=${a},string=${string}"
[root@localhost /]# ./shell.sh
./shell.sh: line 3: string: command not found
./shell.sh: line 4: num: command not found
a=,string=
发现问题没有?定义变量时等号两边加空格会识别不出来。
还有!错误代码会提示,而且还会自动跳过!!变量定义还默认为空!
验证下猜想:
#! /bin/bash执行结果:
this is wrong test!
echo "a = $a"
[root@localhost /]# cat shell.sh
#! /bin/bash
this is wrong test!
echo "a = $a"
[root@localhost /]# ./shell.sh
./shell.sh: line 3: this: command not found
a =
说明猜想正确!错误代码会跳过并继续执行之后的代码(解释性语言特点)!变量默认值为空!
测试变量的特性以及表达式赋值:
#! /bin/bash执行结果:
a=5
b=$a+5
echo "now b=$b"
b=8
echo "after:b=$b"
[root@localhost /]# cat shell.sh
#! /bin/bash
a=5
b=$a+5
echo "now b=$b"
b=8
echo "after b=$b"
[root@localhost /]# ./shell.sh
now b=5+5
after b=8
由结果可发现,shell中变量没有类型!根据表达式自动改变其类型!还发现一个问题,表达式不能计算结果,变成了字符串的拼接!
又有一个新问题,如何执行表达式的结果而不是字符串的拼接呢?
三种赋值方式:
1、赋值关键字let
使用方法:let 变量名 = 表达式
测试代码;
#! /bin/bash执行结果:
a=5
let b=$a+5
echo "now b=$b"
let b=8*5
echo "after:b=$b"
[root@localhost /]# cat shell.sh
#! /bin/bash
a=5
let b=$a+5
echo "now b=$b"
let b=8*5
echo "after b=$b"
[root@localhost /]# ./shell.sh
now b=10
after b=40
2、从终端(stdin)获取变量赋值:
#! /bin/bash运行结果:
echo "who are you?"
read name
echo "hello, $name"
[root@localhost /]# cat shell.sh
#! /bin/bash
echo "who is you?"
read name
echo "hello,$name"
[root@localhost /]# ./shell.sh
who is you?
oba 【此为输入字符】
hello,oba
3、使用$(linux命令)来赋值
#! /bin/bash
a=$(ls)
echo "$a"
执行结果:
[root@localhost /]# ./shell.sh
bin
boot
dev
etc
home
lab2.sh
lib
lost+found
media
mnt
opt
proc
qt
root
sbin
selinux
Settings
shell.sh
srv
sys
tmp
usr
var
部分内容参考:http://c.biancheng.net/cpp/shell/