变量-管道-条件判断
1.什么时shell脚本编程
一组命令顺序执行,解释型语言,执行前不需要提前编译;
命令 + 语法 + 语句 + 思想
2.shell的执行
sh file.sh
./file.sh
sh -x file.sh 显示脚本执行过程
变量:
本地变量:作用范围仅限于当前shell进程有效局部变量:当前函数体有效
环境变量:作用范围是当前shell进程和其子进程
PS1 提示符显示内容
可以使用内置的宏进行定义 man bash 进行查询
默认PS1='[\u\h\w]\$'
PS2 上一条命令未完成时的追加提示符
PS3 select用于显示提示信息
PS4
OLDPWD 切换目录前的上一个目录
PWD 当前目录
配置文件
全局:
/etc/profile /etc/profile.d/* /etc/bashrc
个人:
~/.bash_profile ~/.bashrc
bash的运行方式:
交互式(login)读取顺序:/etc/profile -> /etc/profile.d/* -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc
非交互式(nologin)读取顺序:~/.bashrc -> /etc/bashrc -> /etc/profile.d/*
profile类
设定环境变量
运行命令或脚本 HOSTNAME='/bin/hostname'
bashrc类
通常用于设定本地变量
设定命令别名
eg : alias ls = 'ls -al'
unlias ls
当命令与命令别名重名时,\command 使用命令本身,而不是别名
source 让配置文件立即生效
变量的查看和声明:
set 查看当前bash环境下的
pstree 查看进程树
bash 进入子进程
env 查看环境变量
export 自定义变量转换为环境变量
declare -x 声明环境变量
-i 声明为整型
-a:声明为数组
-r:只读变量,readonly ,即常量,无法改值,也不可撤销
$变量 引用变量的内容
echo 显示变量内容
echo 查看变量
-n 不换行
-e 解释转义字符
定义变量规则:
declare 定义变量,可以加参数声明变量的类型
shell变量是字母大小写敏感的
变量定义时,等号两边不能存在空格,赋值内容本身存在空格,需用引号
单引号与双引号的区别
变量可以时字母,数字,下划线 但不能以数字开头
变量可以赋多个值,以冒号分隔
变量的取消 unset
操作变量的方法
变量的获取方式 $变量 ${变量}
$() $(()) $[] ${} ` ` [[ ]]
$() ` ` 返回命令执行执行结果
$(()) $[] 运算
${} 取变量
[[ ]] 用于条件判断
变量切片 ${变量:start:number}
变量截取 ${变量#} ${变量## ${变量%} ${变量%%}
变量替换 ${变量/xxx1/xxx2} ${变量//xxx1/xxx2}全部替换
扩展a=1234567890,我要得到4567这几个字符
# echo ${a:3:4}
# echo $a|cut -c4-7
# echo $a|awk '{print substr($0,4,4)}'
# echo $a|sed -r 's/(...)(....)(.*)/\2/'
basename 取路径的最末端
read -p “请输入你的名字:” name
${file-my.file.txt} :假如 $file 没有设定,则使用 my.file.txt 作传回值。(空值及非空值时不作处理)
${file:-my.file.txt} :假如 $file 没有设定或为空值,则使用 my.file.txt 作传回值。 (非空值时不作处理)
${file+my.file.txt} :假如 $file 设为空值或非空值,均使用 my.file.txt 作传回值。(没设定时不作处理)
${file:+my.file.txt} :若 $file 为非空值,则使用 my.file.txt 作传回值。 (没设定及空值时不作处理)
${file=my.file.txt} :若 $file 没设定,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。 (空值及非空值时不作处理)
${file:=my.file.txt} :若 $file 没设定或为空值,则使用 my.file.txt 作传回值,同时将 $file 赋值为 my.file.txt 。 (非空值时不作处理)
${file?my.file.txt} :若 $file 没设定,则将 my.file.txt 输出至 STDERR。 (空值及非空值时不作处理)
${file:?my.file.txt} :若 $file 没设定或为空值,则将 my.file.txt 输出至 STDERR。 (非空值时不作处理)
管道:command1 |command2 |...
cut -d"分隔符" -f列
grep 正则表达式进行过滤
wc -l 查多少行
-L 查文件最长的行有多少字符(可用于算单行的字符长度)
-m 查文件总的字符数(但每行都会把换行符也算一个字符)
sort -r 反向排序
-n 以数字来排
-f 大小写不敏感
-t 分隔符
-k 接数字代表第几列
-u 相当于sort | uniq
例:把/etc/passwd的用户以uid大小来进行倒序排序
# sort -nr -t":" -k3 /etc/passwd
uniq -c 计数统计
例:统计/etc/passwd里最后一列/bin/bash,/sbin/nologin等各有多少个
# cut -d":" -f7 /etc/passwd |sort |uniq -c
- ls /var/log |file - file这类文件比较特殊,次方法不可行
tee 同时把命令执行结果重定向到文件和标准输出
ls /etc |tee /tmp/test.out |tr 'a-z' 'A-Z'
tr -d 删除
ls /etc | tr 'a-z' 'A-Z' | tr -d '0-9'| less
重定向
默认输入设备:stdin 0
默认输出设备:stdout ,只输出成功信息 1
默认错误信息输出设备:stderr 2
输出重定向:
command > file
命令的执行结果保存到文件中,文件中原有数据被覆盖,慎重使用
set -C 关闭输出重定向功能,对当前shell生效,若希望永久生效,写入配置文件
command >| file 在关闭重定向功能时,强制重定向
set +C
command >> file 追加重定向,不会覆盖原有数据
/dev/null 数据黑洞
/dev/zero 输出0 的泡泡机
/dev/random 随机数生成器
输入重定向:
command < file
command << EOF (结束符) 脚本中用于生成文档
EOF end of file
cat > /tmp/abc <<EOF
cat >> /tmp/abc <<EOF
EOF可以用任意字符进行替代
eg:写入三行数据到文件中的方法
1.三次echo追加
2.echo -e "firstline \nsecondline \nthirdline" >> filename
3.cat >> filename <<EOF
comments
EOF
错误重定向:
command 2> file
command 2>> file
标准输出、错误输重定向到同一文件
command > file 2> &1
command &> file
ssh 10.1.1.110 < passwd
--ssh是不可以的,需要用到expect脚本
例:自动配置本地yum的配置文件
cat > /etc/yum.repos.d/rhel-source.repo <<EOF
[server]
name=server
baseurl=file:///yum/Server
enabled=1
gpgcheck=0
例:自动ftp下载我的笔记 (用户名:weekendnotes 密码:123 )
#!/bin/bash
lftp 10.1.1.35 -u weekendnotes,123 <<HAHA
mirror ule/ /notes/
mirror shell/ /notes/
quit
HAHA
--总结: < 和 EOF 几乎可以传任何非bash环境下的命令(包括passwd,lftp,samba,mysql,oracle等),除了(ssh,scp,smbpasswd)
$x的含义
$$ 返回程序的pid
$0 脚本本身名字
$1-n 脚本的参数
$*/$@ 代表所有参数
$# 显示后面接的参数的个数
$? 上一条命令执行的返回值,0为正确执行
条件判断:
if [] ;then
command
fi
if [] ;then
command
else
command
fi
if [] ;then
command
elif [] ;then
command
elif [] ;then
command
else
command
fi
[] 判断
文件判断
判断文件是否存在 判断文件类型
[ -e $file ] 判断文件是否存在
[ -s $file ] 判断文件是否为空白文件
[ -f $file ] 判断文件是否为普通文件
[ -d $file ] 判断是否为目录
[ -S $file ] 判断是否为socket
[ -p $file ] 管道文件
[ -c $file ] 字符文件
[ -b $file ] 块设备文件
[ -L $file ] 链接文件
文件权限相关的判断
[ -r/w/x $file ] 当前用户对其是否可读
[ -u/g/k $file ] 是否有suid/sgid/t位
两个文件之间的判断
[ $file1 -nt $file2 ] file1比file2新
[ $file1 -ot $file2 ] file1比file2旧
[ $file1 -ef $file2 ] file1是否与file2相同,即指向统一个inode,(硬链接)
整数判断
[ $? -eq/-ne/-gt/lt/ge/le 0 ] 等于/不等/大于/小于/大于等于/小于等于
字符串判断
-z 是否为空字符串
-n 是否为非空字符串
string1 = string2 是否相等
string1 != string2 不等
例子
判断一个用户是否存在
id abc
grep ^abc: /etc/passwd
判断服务是否OK(以httpd为例)
elinks -dump 10.1.1.35 &> /dev/null
wget url
输入一个文件,判断它属于哪种类型、
逻辑关系
; --前面执行完,不管成功与否,都执行后面
&& --前面执行完,只有前面执行成功了,才执行后面
|| --前面执行完,只有前面执行失败了,才执行后面
# ./configure ; make ;make install --执行完前面,再执行后面
# ./configure && make && make install --前面执行成功,再执行后面的
# [ -e /etc/fstab ] && echo "存在" || echo "不存在" --正确写法