Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
Bourne Shell(/usr/bin/sh或/bin/sh)
Bourne Again Shell(/bin/bash)
C Shell(/usr/bin/csh)
K Shell(/usr/bin/ksh)
Shell for Root(/sbin/sh)
打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好,如果你用 php 写 shell 脚本,扩展名就用 php 好了
#!/bin/bash
echo "Hello World !"
/bin/pwd
#!
是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
echo
命令用于向窗口输出文本
可以在sh
文件中写诸如pwd、ls 这样的命令,使用命令的时候尽量使用觉得路径
命令一般两个位置:
/bin
/usr/bin
chmod +x ./test.sh #使脚本具有执行权限。 ll 查看是否有执行权限,没有则添加(chmod +x)
./test.sh #执行脚本
注意,一定要写成 ./test.sh
,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH
里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh
告诉系统说,就在当前目录找
直接运行解释器,其参数就是 shell 脚本的文件名
/bin/sh test.sh
# 或者简化 sh.test.sh 也可以
#!/bin/sh
# 参数 %F 格式化日期; >> 表示重定向追加到 ex.info中
/bin/date +%F >> /home/uzong/ex.info
echo "disk info" >> /home/uzong/ex.info
echo >> /home/uzong/ex.info
# 将磁盘情况打印
/bin/df -h >> /home/uzong/ex.info
echo "online users:" >> /home/uzong/ex.info
#输出用户信息。 使用 管道 | 过滤,参数 -v 排查。
/usr/bin/who | /bin/grep -v root >> /home/uzong/ex.info
echo "Memory info" >> /home/uzong/ex.info
# free -m 内存使用情况
/usr/bin/free -m >> /home/uzong/ex.info
echo >> /home/uzong/ex.info
#vim root
/usr/bin/wall < /home/uzong/ex.info && /bin/rm /home/uzong/ex.info
定义变量时,变量名不加美元符号
your_name="runoob.com"
echo $your_name
echo ${your_name}
your_name="alibaba"
#第二次赋值的时候不能写$your_name="alibaba",使用变量的时候才加美元符($)
#变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
变量名长度没有限制,在使用变量值是,要在变量名前加上前缀“$”
。一般变量使用大写字母表示,并且全是英文字母开头,赋值符号“=”两边没有空格
注意: 变量名和等号之间不能有空格
变量是shell传递数据的一种方法,用来代表每个取值的符号名。
shell
有两类变量,临时变量和永久变量
临时变量是shell程序内部定义的,其使用范围仅限于定义它的程序,对其他程序不可见。包括:用户自定义变量、位置变量。永久变量是环境变量,其不随shell脚本的执行结果而消失。
可以将一个命令的执行结果赋值给变量,但是需要使用命令替换符号。注意单引号和双引号的区别,双引号是会把里面的变量值进行输出,单引号是会把内容原封不动输出,不会识别里面的变量。
set
命令查看所有变量。unset
命令删除指定的变量#!/bin/bash
#使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变
myUrl="http://www.google.com"
readonly myUrl
myUrl="http://www.runoob.com"
#运行脚本:/bin/sh: NAME: This variable is read only.
位置变量:ls -l file1 file2 file3 …(n范围=1~9)在代码中使用$1-9进行代替。
案例:
#!/bin/sh
DATE=`/bin/date +%Y%m%d`
echo "today is $DATE"
# 占位变量,使用$1-$9 代替。
/bin/ls -l $1
/bin/ls -l $2
/bin/ls -l $3
$*
这个程序的所有参数
$#
这个程序的参数个数
$$
这个程序的PID
$!
执行上一个后台命令的PID
$?
执行上一个命令的返回值
$(0-9)
显示位置变量
从键盘录入数据,赋值给变量
-x
跟踪执行情况的作用。
注意:
expr
的运算必须用空格隔开\*
表示转义符运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true |
在shell脚本中做测试判断
test -d file 知道文件是否是目录
test -f file 文件是否为常规文件
test -x file 文件是否是可执行文件
test -r file 文件是否可读
test -w file 文件是否可写
语法格式 if test -d $1 then ... elif then .... else ... fi
变量测试语句可以用简化格式:[]
,比如test -d $1
等价于["空格" -d $1 "空格" ]
(注意空格)
案例: 判断一个入参是否为文件夹
if test -d $1 then ... elif then .... else ... fi
语法格式:
case 值 in
模式1)
command1
command2
...
commandN
;;
模式2)
command1
command2
...
commandN
;;
esac
语法格式:
while condition
do
command
done
结束和继续:
布尔运算符
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
逻辑运算符
运算符 | 说明 | 举例 |
---|---|---|
&& |
逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| |
逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
这个语法用的不多。
for...done
语句格式
for 变量 in 名字表表
do
命令列表
done
语法用的不多
格式:
select 变量 in 列表
do
cmd...
done
# 格式如下
[ function ] funname [()]
{
action;
[return int;]
}
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…
注意,$10
不能获取第十个参数,获取第十个参数需要${10}
。当n>=10
时,需要使用${n}
来获取参数
参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
@ 与 @ 与 @与*相同,但是使用时加引号,并在引号中返回每个参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:
#Shell 数组用括号来表示,元素用"空格"符号分割开
array_name=(value1 ... valuen)
# 或者使用下标的方式
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
读取数组元素值的一般格式是
${array_name[index]}
如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到/dev/null
:
$ command > /dev/null
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。
如果希望屏蔽 stdout 和 stderr,可以这样写:
$ command > /dev/null 2>&1
和其他语言一样,Shell 也可以包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。
#Shell 文件包含的语法格式如下:
. filename # 注意点号(.)和文件名中间有一空格
或
source filename
http://www.runoob.com/linux/linux-shell-include-file.html