Shell 完整教程笔记
2019-02-15 16:01:54 0 举报
AI智能生成
Shell 完整教程。Shell 的所有基础知识点。适用于初学 Shell 和多年不用要返回头来查找 Shell 知识时使用。
作者其他创作
大纲/内容
Shell 概述
Shell 是什么
Shell 是一个用 C 语言编写的程序。
Shell 是 UNIX/Linux 下的脚本编程语言。
Shell 是用户使用Unix/Linux的桥梁。
Shell 脚本
Shell 脚本是一种为 shell 编写的脚本程序。
业界所说的 shell 通常都是指 shell 脚本。
但实际上,shell 和 shell script 是两个不同的概念。
Shell 开发环境
一个能编写代码的文本编辑器
一个能解释执行的脚本解释器
Bourne Shell(sh)
/usr/bin/sh 或 /bin/sh
Bourne Again Shell(bash)
/bin/bash
C Shell
/usr/bin/csh
Korn Shell(K Shell)
/usr/bin/ksh
Shell for Root
/sbin/sh
编译型语言和解释型语言
执行 Shell 命令的方式
交互式(Interactive)
解释执行用户的命令,用户输入一条命令,Shell 就解释执行一条。
批处理(Batch)
用户事先写一个Shell脚本,其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。
第一个 Shell 脚本
1. 打开文本编辑器(可以使用 vi/vim 命令来创建文件)
2. 新建一个文件 test.sh
3. 输入第一行代码:#!/bin/bash
4. 输入其他 Shell 命令
5. 保存文件
运行 Shell 脚本的的方法
作为可执行程序
1. cd 到脚本所在目录
2. 输入命令:chmod +x ./test.sh
3. 执行脚本:./test.sh
作为解释器参数
1. cd 到脚本所在目录
2. 直接运行解释器:/bin/sh test.sh
Shell 变量
定义变量
变量名=值
变量名
变量名由数字、字母、下划线组成。
必须以字母或者下划线开头。
中间不能有空格,可以使用下划线(_)。
不能使用标点符号。
不能使用bash里的关键字(可用help命令查看保留关键字)。
赋值号(=)
赋值号的周围不能有空格。
三种值的方式
variable=value
variable='value'
variable="value"
已定义的变量,可以被重新定义。(只读变量除外。)
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号($)即可。
变量名外面的花括号是可选的,加不加都行。
加花括号是为了帮助解释器识别变量的边界,如 ${skill}Script。
推荐给所有变量加上花括号,这是个好的编程习惯。
只读变量
使用 readonly 命令可以将变量定义为只读变量。尝试更改只读变量会报错。
删除变量
使用 unset 命令可以删除变量。
变量被删除后不能再次使用。(但不会报错。)
unset 命令不能删除只读变量。
变量类型
局部变量
局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
环境变量
所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。
必要的时候shell脚本也可以定义环境变量。
shell 变量
shell 变量是由 shell 程序设置的特殊变量。shell 变量中有的是环境变量,有的是局部变量。
Shell 特殊变量
$0
当前脚本的文件名。
$n
传递给脚本或函数的参数。n 是一个数字,表示第几个参数。
$#
传递给脚本或函数的参数个数。
$*
传递给脚本或函数的所有参数。
$@
传递给脚本或函数的所有参数。
$?
上个命令的退出状态,或函数的返回值。
$-
显示Shell使用的当前选项,与set命令功能相同。
$$
脚本运行的当前进程ID号。
$!
后台运行的最后一个进程的ID号。
Shell 字符串
字符串拼接
字符串写在一起就可以直接拼接。
获取字符串长度
${#字符串}
提取子字符串
${字符串:开始序号:结束序号}
查找子字符串
`expr index "$字符串" 子字符串`
Shell 数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
定义数组
数组名=(值1 值2 ... 值n)
可以单独定义数组的各个分量
读取数组
${数组名[下标]}
使用 @ 符号可以获取数组中的所有元素
获取数组的长度
获取数组的元素个数
length=${#array_name[@]}
length=${#array_name[*]}
获取数组单个元素的长度
lengthn=${#array_name[n]}
Shell 注释
在 Shell 脚本中,以 # 开头的行就是注释,会被解释器忽略。
sh 里没有多行注释,只能每一行加一个#号。
bash 里的多行注释(:<<EOF)
巧妙的方法:花括号括起来
Shell 运算符
概述
bash 支持很多运算符
算术运算符
关系运算符
布尔运算符
字符串运算符
文件测试运算符
但是原生 bash 不支持简单的数学运算
可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
示例
算术运算符
+(加法)
-(减法)
*(乘法)
/(除法)
%(取余)
=(赋值)
==(相等)
!=(不相等)
关系运算符
-eq(相等)
-ne(不相等)
-gt(大于)
-lt(小于)
-ge(大于等于)
-le(小于等于)
布尔运算符
!(非运算)
-o(或运算)
-a(与运算)
逻辑运算符
&&(逻辑的 AND)
||(逻辑的 OR)
字符串运算符
=(相等)
!=(不相等)
-z(字符串长度是否为0)
-n(字符串长度是否不为0)
文件测试运算符
-b(检测块设备文件)
-c(检测字符设备文件)
-d(检测是否目录)
-f(检测是否普通文件)
-g(检测 SGID 位)
-k(检测粘着位)
-p(检测名管道)
-u(检测 SUID 位)
-r(检测是否可读)
-w(检测是否可写)
-x(检测是否可执行)
-s(检测文件是否为空)
-e(检测文件是否存在)
Shell echo命令
用于字符串的输出
基本命令语法为:echo stirng
显示普通字符串
echo "It is a test"
显示转义字符
echo "\"It is a test\""
显示变量
echo "${value} is a test"
原样显示字符串(不转义或取变量)
echo '$name\"'
显示换行
echo -e "OK! \n"
显示不换行
echo -e "OK! \c"
显示命令执行结果
echo `date`
显示结果重定向至文件
echo "It is a test" > filename
Shell printf 命令
printf 命令用于格式化输出
基本命令格式为:printf format-string [arguments...]
format-string:为格式控制字符串。
arguments:为参数列表。参数用空格分隔。
若给出的参数个数超出格式指定的参数个数仍然会按照该格式输出,format-string 被重用。
若给出的参数个数少于格式指定的参数个数,那么 %s 用NULL代替,%d 用 0 代替。
printf 命令与 C 语言 printf() 函数的不同
printf 命令不用加括号。
format-string 可以没有引号,但最好加上,单引号双引号均可。
参数多于格式控制符(%)时,format-string 可以重用,可以将所有参数都转换。
arguments 使用空格分隔,不用逗号。
printf的转义序列
\a
警告字符,通常为ASCII的BEL字符。
\b
后退
\f
换页(formfeed)
\n
换行
\r
回车(Carriage return)
\t
水平制表符
\v
垂直制表符
\\
反斜杠字符
\ddd
表示1到3位数八进制值的字符。仅在格式字符串中有效。
\0ddd
表示1到3位的八进制值字符。
Shell 流程控制语句
if else 语句
if ... fi 语句
if [ expression ]
then
Statement(s)
fi
then
Statement(s)
fi
if ... else ... fi 语句
if [ expression ]
then
Statement(s)
else
Statement(s)
fi
then
Statement(s)
else
Statement(s)
fi
if ... elif ... fi 语句
if [ expression 1 ]
then
Statement(s)
elif [ expression 2 ]
then
Statement(s)
elif [ expression 3 ]
then
Statement(s)
fi
then
Statement(s)
elif [ expression 2 ]
then
Statement(s)
elif [ expression 3 ]
then
Statement(s)
fi
if ... elif ... else ... fi 语句
if [ expression 1 ]
then
Statement(s)
elif [ expression 2 ]
then
Statement(s)
else
Statement(s)
fi
then
Statement(s)
elif [ expression 2 ]
then
Statement(s)
else
Statement(s)
fi
case 语句
case 值 in
模式1)
Statement(s)
;;
模式2)
Statement(s)
;;
*)
Statement(s)
;;
esac
模式1)
Statement(s)
;;
模式2)
Statement(s)
;;
*)
Statement(s)
;;
esac
for 循环
for 变量 in 列表
do
Statement(s)
done
do
Statement(s)
done
while 循环
while condition
do
Statement(s)
done
do
Statement(s)
done
循环读取键盘数据的例子
until 循环
until condition
do
Statement(s)
done
do
Statement(s)
done
跳出循环
break 命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
continue 命令
continue命令与break命令类似,但它仅仅跳出当前循环。
Shell 函数
函数的定义格式
[ function ] fun_name [()]
{
action;
[return int;]
}
{
action;
[return int;]
}
函数的使用
调用函数只需要给出函数名,不需要加括号。
函数返回值在调用该函数后通过 $? 来获得。
函数示例
删除函数
unset 命令,不过要加上 .f 选项
$unset .f fun_name
函数参数
在函数体内部,通过 $n 的形式来获取参数的值。
$1 表示第一个参数。而不是 $0 。
当 n<10 时,$n 或 ${n} 两种表示方式都行。当 n>=10 时,必须使用 ${n} 来获取参数。
还有其他还有几个用来处理参数的特殊字符,见 Shell 特殊变量。
Shell 输入/输出重定向
标准输入和标准输出
Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。
一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。
输出重定向:command > file
command 命令输出到显示器的内容会被重定向到 file。
在显示器上不会看到任何输出。
输出重定向会覆盖文件中内容。
如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾。
输入重定向:command < file
本来需要从键盘获取输入的命令会被重定向为从文件读取内容。
重定向深入讲解
一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件
标准输入文件(stdin)
标准输出文件(stdout)
标准错误文件(stderr)
默认情况下,command > file 将 stdout 重定向到 file,command < file 将 stdin 重定向到 file。
如果希望 stderr 重定向到 file,可以这样写:command 2 > file。
如果希望 stderr 追加到 file 文件末尾,可以这样写:command 2 >> file。
如果希望将 stdout 和 stderr 合并后重定向到 file,可以这样写:command > file 2>&1。
如果希望对 stdin 和 stdout 都重定向,可以这样写:command < file1 >file2。
Here Document
Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
它的基本的形式如下:
command << delimiter
document
delimiter
document
delimiter
它的作用是将两个 delimiter 之间的内容(document)作为输入传递给 command。
两点注意:
结尾的 delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
开始的 delimiter 前后的空格会被忽略掉。
delimiter 可以替换成任何文本或符号,常用的是 EOF。
可以将 Here Document 用在脚本中。
/dev/null 文件
/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃。
如果尝试从 /dev/null 中读取内容,那么什么也读不到。
如果希望执行某个命令,但又不希望有任何输出结果,那么可以将输出重定向到 /dev/null。
执行 command 但禁止输出:command > /dev/null。
如果希望屏蔽 stdout 和 stderr,可以这样写:command > /dev/null 2>&1。
Shell 文件包含
Shell 也可以包含外部脚本,将外部脚本的内容合并到当前脚本。
Shell 文件包含的语法格式有两种:
. filename
source filename
示例
1. 创建两个 shell 脚本文件
2. test1.sh 代码
3. test2.sh 代码
4. 为 test2.sh 添加可执行权限
5. 执行 test2
6. 输出结果
0 条评论
下一页