shell脚本介绍
1.为什么使用Shell脚本
批量命令
重复、条件等控制
2.Shell脚本的基本内容
第一行:#!/bin/sh
第二行:注释:#
第三行:变量
第四行:条件判断、循环
3.脚本的运行方式
chmod +x 脚本
./脚本文件名
4.示例(hello.sh)
#!/bin/bash //第一行
#这是一个基本的shell脚本 //注释
op="hello world" //变量
echo $op //打印变量
shell特性
1.别名(alias)
e.g. alias ll='ls -alh'
2.命令替换
3.管道(|)
把一个命令的输出连接到另一个命令的输入。
ls | sort
cat func.txt | grep -v ^#
4.重定向(<>)
与管道相关,可以改变程序运行的输入来源和输出地点
Linux shell下常用输入输出操作符是:
1. 标准输入 (stdin) :代码为 0 ,使用 < 或 << ; /dev/stdin -> /proc/self/fd/0 0代表:/dev/stdin
2. 标准输出 (stdout):代码为 1 ,使用 > 或 >> ; /dev/stdout -> /proc/self/fd/1 1代表:/dev/stdout
3. 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ; /dev/stderr -> /proc/self/fd/2 2代表:/dev/stderr
输出重定向:
格式:
command-line1 [1-n] > file或文件操作符或设备
上面命令意思是:将一条命令执行结果(标准输出,或者错误输出,本来都要打印到屏幕上面的) 重定向其它输出设备(文件,打开文件操作符,或打印机等等)1,2分别是标准输出,错误输出。
1. command > filename | 把标准输出重定向到一个新文件中 |
2. command >> filename | 把标准输出重定向到一个文件中(追加) |
3. command 1 > filename | 把标准输出重定向到一个文件中 |
4. command > filename2 > &1 | 把标准输出和标准错误一起重定向到一个文件中 |
5. command2 > filename | 把标准错误重定向到一个文件中 |
6. command2 >> filename | 把标准输出重定向到一个文件中(追加) |
7. Command >> filename 2 > &1 | 把标准输出和标准错误一起重定向到一个文件中(追加) |
8. Command < filename > filename 2 | command命令以filename文件作为标准输入,以filename 2文件作为标准输出 |
9. Command << delimiter | 从标准输入中读入,直至遇到delimiter分界符 |
10. Command < &m | 把文件描述符m作为标准输入 |
11. Command > &m | 把标准输出重定向到文件描述符m中 |
12. Command2 < &- | 关闭标准输入 |
例1:将myfle1作为sort的输入,并输出到屏幕。
$ sort<myflle1
例2:将date的输出转向到myfile2文件中。
$ date>myfile2
例3:将ls-l的输出追加到myfile3文件中。
$ ls -l>> myfile3
例4:将myprogram错误输出改向到err_file文件。
$ myprogram 2 >err_file
重定向标准输出示例:
cat file | sort 1 > sort.out 第3种情况
cat file | sort > sort.out 第1种情况
pwd >> path.out 第2种情况
> nullfile.txt 创建一个文件
重定向标准输入示例:
sort < file 将file文件中的数据作为输入,sort对其进行排序,然后将排序后的结果输出到屏幕上
sort < name.txt > name.out 第8种情况,对排序后的内容输出到name.out文件中
标准输入示例: 第9种情况
[root@jack shell]# cat >> term.txt << SITECH
>Hello,there I am using a $TERM !
>and my username is $LOGNAME
>bye…
>SITECH
[root@jack shell]# cat term.txt
Hello,there I am using a vt100 !
and my username is root
bye…
重定向标准错误示例:
[root@jack shell]# grep “trd” book.txt
Grep: missiles:No such file or directory
[root@jack shell]# grep “trd” book.txt 2> /dev/null
解释:表示把错误信息扔给/dev/null , /dev/null 不会保存错误信息,实质就是丢失错误信息。
如果sky.txt不存在,则错误信息存入到一个指定的文件中,如:
ls -al sky.txt 2 > err_message.txt
结合使用标准输出与标准错误示例:
[root@jack shell]# cat account_new.txt \
Account_old.txt 1> accounts.out 2> accounts.err
[root@jack shell]# cat accounts.out
???
[root@jack shell]# cat accounts.err
将2个文件的内容重定向到accounts.out中,如果某一个文件不存在,或出错,
则将错误信息重定向到错误文件中accounts.err
合并标准输出与标准错误示例:
合并的时候shell是从左到右分析相应命令
grep “standard” standard.txt > grep.out 2>&1
->如果文件不存在,则把错误信息记录到grep.out中
->如果文件存在, 也把正确的信息记录到grep.out中
5.后台处理
显示以txt为扩展名的文件或显示以a开头的文件,这种情况称为模式匹配。
实现方式:正则表达式
ls *.txt
6.模式匹配
7.变量
变量用来存储信息
示例:
#!/bin/bash
#这是一个基本的shell脚本
printchar = “hello world”//定义变量
echo $printchar
8.特殊字符
分号(;):允许在一行上放多个命令。
eg: cd ~/backup ; mkdir startup ; cp ~/.* startup/.
&:命令后执行。
括号():创建成组的命令。
竖杆(|):管道标示符。
< > &:表示重定向。
* ? [ ] !:表示模式匹配。
$:变量名的开头。
#:表示注释(第一行除外)。
空格,制表符,换行符:当做空白。
$((...)) :对括号内的表达式求值
eg:
#!/bin/sh
x=0
while [ "$x" -ne 10 ]; do
echo $x
x=$(($x+1))
done
exit 0
**: 两个星号在运算时代表 "次方" 的意思
eg: "sus=2**3"
echo "sus = $sus"
$ sus = 8
{} 大括号:
用法一:通配符扩展
eg: ls my_{finger,toe}s
这条命令相当于如下命令的组合:
ls my_fingers my_toes
eg: mkdir {userA,userB,userC}-{home,bin,data}
用法二:可用于语句块的构造。
'string' 单引号 和 "string" 双引号
双引号:如果想在定义的变量中加入空格,就必须使用单引号或双引号,
单、双引号的区别在于双引号转义特殊字符而单引号不转义特殊字符
eg: $ heyyou=home
$ echo '$heyyou'
$ $heyyou ($没有转义)
eg: $ heyyou=home
$ echo "$heyyou"
$ home ($转义了输出了heyyou变量的值)
单引号:
由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。例如:
双引号:
由双引号括起来的字符,除$, \, '和"这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。
双引号(“):用来使shell无法认出空格、制表符和其他大多数特殊字符,这样“David Medinets”表示一个值。
让 $ 反斜杠 反引号 不失效
单引号(‘):用来使shell无法认出所有特殊字符。
反引号(`):用来替换命令。
反斜杠(\):用来使shell无法认出以上的特殊字符,使其后的特殊字符失去特殊含义。
如:David\ Medinets
[root@sky /root]# touch David\ Medinets
[root@sky /root]# ls David\ medinets
放在指令前,有取消 aliases(别名) 的作用;放在特殊符号前,则该特殊符号的作用消失;
放在指令的最末端,表示指令连接下一行(使得回车符无效,只起换行作用)
shell输入输出
1.echo
2.read
3.cat
4.管道
5.tee
shell控制结构
if then else语句
语法格式:
if 条件1
then
命令1
elif 条件2
then
命令2
else 命令3
fi
case语句
语法格式:
case 值 in
模式1)
命令1
…
;;
模式2)
命令2
…
;;
esac
注:可使用模式匹配
for循环
语法格式:
for 变量名 in 列表
do
命令1
命令2
……
done
until循环
语法:
until 条件
命令1
命令2…
done
注:条件发生在循环末尾,至少执行一次循环
while循环
语法:
while 条件
do
命令1
命令2
……
done
FAQ
1.if [ "$#" -eq 0 ] ; then 是神马意思
$#表示位置参数的数目(对脚本来说,是运行脚本时所带的参数;对函数来说,是函数调用时传入的参数)。
数值的比较用 -eq ,字符串的比较才用 =