SHELL脚本学习笔记
标签(空格分隔): linux shell脚本
1. 常用命令汇总
alias
设置别名
unalias
取消别名
history
历史命令
vim -o file1 file2
同时打开两个窗口
netstat -tuln
// 查询已经开启的网络服务端口,如netstat -tuln | grep 80
netstat -tnlp
scp
从服务器上下载或上传文件(同理用的是22端口,类似sftp)
- scp [-pr] [-l 速率] file [账号@]主机:目录名 <==上传
- scp [-pr] [-l 速率] [账号@]主机:file 目录名 <==下载
-p :保留原本档案的权限数据;
-r :复制来源为目录时,可以复制整个目录 (含子目录)
-l :可以限制传输的速度,单位为 Kbits/s ,例如 [-l 800] 代表传输速限 100Kbytes/s
rsync [-avrlptgoD] [-e ssh] [user@host:/dir] [/local/path]
-v :观察模式,可以列出更多的信息,包括镜像时的档案档名等;
-q :与 -v 相反,安静模式,略过正常信息,仅显示错误讯息;
-r :递归复制!可以针对『目录』来处理!很重要!
-u :仅更新 (update),若目标档案较新,则保留新档案不会覆盖;
-l :复制链接文件的属性,而非链接的目标源文件内容;
-p :复制时,连同属性 (permission) 也保存不变!
-g :保存源文件的拥有群组;
-o :保存源文件的拥有人;
-D :保存源文件的装置属性 (device)
-t :保存源文件的时间参数;
-I :忽略更新时间 (mtime) 的属性,档案比对上会比较快速;
-z :在数据传输时,加上压缩的参数!
-e :使用的信道协议,例如使用 ssh 通道,则 -e ssh
-a :相当于 -rlptgoD ,所以这个 -a 是最常用的参数了!
- 其实三种传输模式差异在于有没有冒号 (:) 而已,本地端传输不需要冒号,透过 ssh 或 rsh 时,就得要利用一个冒号 (:), 如果是透过 rsync daemon 的话,就得要两个冒号 (::)
系统
uname -a
#查看内核/操作系统/CPU信息
head -n 1 /etc/issue
#查看操作系统版本
cat /proc/cpuinfo
#查看CPU信息
hostname
#查看计算机名
lspci -tv
#列出所有PCI设备
lsusb -tv
#列出所有USB设备
lsmod
#列出加载的内核模块
env
#查看环境变量
资源
free -m
#查看内存使用量和交换区使用量
df -h
#查看各分区使用情况
du -sh
<目录名> #查看指定目录的大小
grep MemTotal /proc/meminfo
#查看内存总量
grep MemFree /proc/meminfo
#查看空闲内存量
uptime
#查看系统运行时间、用户数、负载
cat /proc/loadavg
#查看系统负载
磁盘和分区
mount | column -t
#查看挂接的分区状态
fdisk -l
#查看所有分区
swapon -s
#查看所有交换分区
hdparm -i /dev/hda
#查看磁盘参数(仅适用于IDE设备)
dmesg | grep IDE
#查看启动时IDE设备检测状况
网络
ifconfig
#查看所有网络接口的属性
iptables -L
#查看防火墙设置
route -n
#查看路由表
netstat -lntp
#查看所有监听端口
netstat -antp
#查看所有已经建立的连接
netstat -s
#查看网络统计信息
进程
ps -ef
#查看所有进程
top
#实时显示进程状态
用户
w
#查看活动用户
id
<用户名> #查看指定用户信息
last
#查看用户登录日志
cut -d: -f1 /etc/passwd
#查看系统所有用户
cut -d: -f1 /etc/group
#查看系统所有组
crontab -l
#查看当前用户的计划任务
服务
chkconfig --list
#列出所有系统服务
chkconfig --list | grep on
#列出所有启动的系统服务
程序
rpm -qa
#查看所有安装的软件包
1. 引号的作用
- 双引号(“”)
- 使用””可引用除字符$(美元符号)、`(反引号)、\(反斜线)外的任意字符或字符串。双引号不会阻止shell对这三个字符做特殊处理(标示变量名、命令替换、反斜线转义)。
Eg:name=gezn; echo “User name:$name”//将打印User name :gezn
Echo “The date is:date +date-%d-%m-%Y”
//将打印The date is: 03-05-2009
Echo –e “$USER\t$UID”
//将打印gezn 500 - 如果要查新包含空格的字符串经常用到双引号
- 使用””可引用除字符$(美元符号)、`(反引号)、\(反斜线)外的任意字符或字符串。双引号不会阻止shell对这三个字符做特殊处理(标示变量名、命令替换、反斜线转义)。
- 单引号(’’)
- 如果用单引号把字符串括起来,则dayi9nhao内字符串中的任何特殊字符的特殊含义均被屏蔽。
- 举例:
echo –e ‘$USER\t$UID’
//将打印$USER $UID
(没有屏蔽\t,是因为选项“-e”的缘故)
echo ‘USER\t$UID’
//将打印$USER\t$UID
- 反引号(``)
- shell将反引号中的内容作为一个系统命令,并执行其内容。使用这种方法可以替换输出为一个变量
- 举例:
a=date + date-%d-%m-%Y
//将打印The date is: 03-05-2009
- 反斜线(\)
- 如果下一个字符有特殊含义,反斜线防止shell误解其含义,即屏蔽其特殊含义。
- 下属字符包含有特殊含义:& * + $ ` “ | ?
- 在打印字符串时要加入八进制字符(ASCII相应字符)时,必须在前面加反斜线,否则shell作普通数字处。
举例: bj=Beijing; echo ”variable$bj=$bj”//将打印variable $bj = beijing
1. 大小括号的作用
- 形式
${var}
$(cmd)
()和{}
${var:-string},${var:+string},${var:=string},${var:?string}
$((exp))
$(var%pattern),$(var%%pattern),$(var#pattern),$(var##pattern)
- 具体解释
Shell中变量的原形
这个最常见的变量形式就是$var,打印var用命令
echo $var
可是这里有个问题:当你要显示变量值加随意的字符(如$varAA
)时,就会出错。系统会认为整个varAA是一个变量,这时就可以用一个大括号来限定变量名称的范围,如${var}AA
,这样就好了。-
命令替换
$(cmd)
命令替换$(cmd)
和符号cmd
(注意这不是单引号,在美式键盘上,`是ESC下面的那个键)有相同之处.以echo $(ls)
来说明整个替换过程:shell扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令echo $(ls)中的$(ls)位置,即替换了$(ls),再执行echo命令。如下:$ ls a b c $ echo $(ls) a b c $ echo `ls` a b c
3. 一串的命令执行()和{}
`()`和`{}`都是对一串的命令进行执行,但有所区别:
- ()只是对一串命令重新开一个子shell进行执行
- {}对一串命令在当前shell执行
- ()和{}都是把一串的命令放在括号里面,并且命令之间用;号隔开
- ()最后一个命令可以不用分号
- {}最后一个命令要用分号
- {}的第一个命令和左括号之间必须要有一个空格
- ()里的各命令不必和括号有空格
- ()和{}中括号里面的某个命令的重定向只影响该命令,但括号外的重定向则影响到括号里的所有命令
4. 几种特殊的替换结构:`${var:-string}`,`${var:+string}`,`${var:=string}`,`${var:?string}`
- `${var:-string}`和`${var:=string}`:若变量var为空,则用在命令行中用string来替换`${var:-string}`,否则变量var不为空时,则用变量var的值来替换`${var:-string}`;对于`${var:=string}`的替换规则和`${var:-string}`是一样的,所不同之处是`${var:=string}`若var为空时,用string替换`${var:=string}`的同时,把string赋给变量var: `${var:=string}`很常用的一种用法是,判断某个变量是否赋值,没有的话则给它赋上一个默认值。
- `${var:+string}`的替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)
- `${var:?string}`替换规则为:若变量var不为空,则用变量var的值来替换`${var:?string}`;若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。
- :在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。
5. POSIX标准的扩展计算:`$((exp))`
这种计算是符合C语言的运算符,也就是说只要符合C的运算符都可用在`$((exp))`,甚至是三目运算符。注意:这种扩展计算是整数型的计算,不支持浮点型.若是逻辑判断,表达式exp为真则为1,假则为0。
6. 四种模式匹配替换结构:`${var%pattern}`,`${var%%pattern}`,`${var#pattern}`,`${var##pattern}`
1. 第一种模式:`${variable%pattern}`,这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最短的匹配模式
2. 第二种模式:`${variable%%pattern}`,这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
3. 第三种模式:`${variable#pattern}`,这种模式时,shell在variable中查找,看它是否一给的模式pattern开始,如果是,就从命令行把variable中的内容去掉左边最短的匹配模式
4. 第四种模式: `${variable##pattern}`,这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,就从命令行把variable中的内容去掉右边最长的匹配模式
7. 这四种模式中都不会改变variable的值,其中,只有在pattern中使用了*匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,*表示零个或多个任意字符,?表示零个或一个任意字符,[...]表示匹配中括号里面的字符,[!...]表示不匹配中括号里面的字符
```
[root@root shell]# var=testcase
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var%s*e} 从最右边删除最短匹配
testca
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var%%s*e} 从最右边删除最长匹配
te
[root@root shell]# echo $var 变量没有改变
testcase
[root@root shell]# echo ${var#?e} 从最左边删除最短匹配
stcase
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var#*e} 从最左边删除最短匹配
stcase
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var##*e} 从最左边删除最长匹配,即删除所有
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var##*s} 从最左边删除最长匹配
e
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var#test} 删除test
case
[root@root shell]# echo $var
testcase
[root@root shell]# echo ${var#tests} 没有匹配
testcase
```
8.至于中括号[ ],感觉作用就是用来比较的。比如放在if语句里面,while语句里面,等等。这 里引出来[..]和[[…]]的区别:(摘自网上,实测证实):使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如,&&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错。
3. if条件判断
1. 基本语法:
if [ command ]; then
符合该条件执行的语句
fi
2、扩展语法:
if [ command ];then
符合该条件执行的语句
elif [ command ];then
符合该条件执行的语句
else
符合该条件执行的语句
fi
3、语法说明:bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语句,否则后面的命令不执行,跳到下一条命令。当有多个嵌套时,只有第一个返回0退出状态的命令会导致符合该条件执行的语句部分被执行,如果所有的语句的执行状态都不为0,则执行else中语句。返回状态:最后一个命令的退出状态,或者当没有条件是真的话为0。
4. **注意**:
1. [ ]表示条件测试。注意这里的空格很重要。要注意在'['后面和']'前面都必须要有空格
2. 在shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。
3. 注意if判断中对于变量的处理,需要加引号,以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。比如[ -n "$var" ]如果var为空会出错
4. 判断是不支持浮点值的
5. 如果只单独使用>或者<号,系统会认为是输出或者输入重定向,虽然结果显示正确,但是其实是错误的,因此要对这些符号进行转意
6. 在默认中,运行if语句中的命令所产生的错误信息仍然出现在脚本的输出结果中
7. 使用-z或者-n来检查长度的时候,没有定义的变量也为0
8. 空变量和没有初始化的变量可能会对shell脚本测试产生灾难性的影响,因此在不确定变量的内容的时候,在测试号前使用-n或者-z测试一下
9. ? 变量包含了之前执行命令的退出状态(最近完成的前台进程)(可以用于检测退出状态)
5. 常用参数:
- 文件/目录判断:
[ -a FILE ] 如果 FILE 存在则为真。
[ -b FILE ] 如果 FILE 存在且是一个块文件则返回为真。
[ -c FILE ] 如果 FILE 存在且是一个字符文件则返回为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则返回为真。
[ -e FILE ] 如果 指定的文件或目录存在时返回为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则返回为真。
[ -g FILE ] 如果 FILE 存在且设置了SGID则返回为真。
[ -h FILE ] 如果 FILE 存在且是一个符号符号链接文件则返回为真。(该选项在一些老系统上无效)
[ -k FILE ] 如果 FILE 存在且已经设置了冒险位则返回为真。
[ -p FILE ] 如果 FILE 存并且是命令管道时返回为真。
[ -r FILE ] 如果 FILE 存在且是可读的则返回为真。
[ -s FILE ] 如果 FILE 存在且大小非0时为真则返回为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID位时返回为真。
[ -w FILE ] 如果 FILE 存在且是可写的则返回为真。(一个目录为了它的内容被访问必然是可执行的)
[ -x FILE ] 如果 FILE 存在且是可执行的则返回为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则返回为真。
[ -G FILE ] 如果 FILE 存在且默认组为当前组则返回为真。(只检查系统默认组)
[ -L FILE ] 如果 FILE 存在且是一个符号连接则返回为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则返回为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则返回为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新, 或者 FILE1 存在但是 FILE2 不存在则返回为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 老, 或者 FILE2 存在但是 FILE1 不存在则返回为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则返回为真。
- 字符串判断
[ -z STRING ] 如果STRING的长度为零则返回为真,即空是真
[ -n STRING ] 如果STRING的长度非零则返回为真,即非空是真
[ STRING1 ] 如果字符串不为空则返回为真,与-n类似
[ STRING1 == STRING2 ] 如果两个字符串相同则返回为真
[ STRING1 != STRING2 ] 如果字符串不相同则返回为真
[ STRING1 < STRING2 ] 如果 “STRING1”字典排序在“STRING2”前面则返回为真。
[ STRING1 > STRING2 ] 如果 “STRING1”字典排序在“STRING2”后面则返回为真。
- 数值判断
[ INT1 -eq INT2 ] INT1和INT2两数相等返回为真 ,=
[ INT1 -ne INT2 ] INT1和INT2两数不等返回为真 ,<>
[ INT1 -gt INT2 ] INT1大于INT2返回为真 ,>
[ INT1 -ge INT2 ] INT1大于等于INT2返回为真,>=
[ INT1 -lt INT2 ] INT1小于INT2返回为真 ,<
[ INT1 -le INT2 ] INT1小于等于INT2返回为真,<=
- 逻辑判断
[ ! EXPR ] 逻辑非,如果 EXPR 是false则返回为真。
[ EXPR1 -a EXPR2 ] 逻辑与,如果 EXPR1 and EXPR2 全真则返回为真。
[ EXPR1 -o EXPR2 ] 逻辑或,如果 EXPR1 或者 EXPR2 为真则返回为真。
[ ] || [ ] 用OR来合并两个条件
[ ] && [ ] 用AND来合并两个条件
其他判断
[ -t FD ] 如果文件描述符 FD (默认值为1)打开且指向一个终端则返回为真
[ -o optionname ] 如果shell选项optionname开启则返回为真
6. IF高级特性:
- 双圆括号(( )):表示数学表达式,在判断命令中只允许在比较中进行简单的算术操作,而双圆括号提供更多的数学符号,而且在双圆括号里面的'>','<'号不需要转意。
- 双方括号[[ ]]:表示高级字符串处理函数,双方括号中判断命令使用标准的字符串比较,还可以使用匹配模式,从而定义与字符串相匹配的正则表达式。
7. 双括号的作用:
在shell中,[ $a != 1 || $b = 2 ]是不允许出,要用[ $a != 1 ] || [ $b = 2 ],而双括号就可以解决这个问题的,[[ $a != 1 || $b = 2 ]]。又比如这个[ "$a" -lt "$b" ],也可以改成双括号的形式(("$a" < "$b"))
8. 实例
1. 判断目录$doiido是否存在,若不存在,则新建一个
if [ ! -d "$doiido"]; then
mkdir "$doiido"
fi
2. 判断普通文件$doiido是否存,若不存在,则新建一个
if [ ! -f "$doiido" ]; then
touch "$doiido"
fi
3. 判断$doiido是否存在并且是否具有可执行权限
if [ ! -x "$doiido"]; then
mkdir "$doiido"
chmod +x "$doiido"
fi
4. 是判断变量$doiido是否有值
if [ ! -n "$doiido" ]; then
echo "$doiido is empty"
exit 0
fi
5. 两个变量判断是否相等
if [ "$var1" = "$var2" ]; then
echo '$var1 eq $var2'
else
echo '$var1 not eq $var2'
fi
6. 测试退出状态:
if [ $? -eq 0 ];then
echo 'That is ok'
fi
7. 数值的比较:
if [ "$num" -gt "150" ]
echo "$num is biger than 150"
fi
8. a>b且a<c
(( a > b )) && (( a < c ))
[[ $a > $b ]] && [[ $a < $c ]]
[ $a -gt $b -a $a -lt $c ]
9. a>b或a<c
(( a > b )) || (( a < c ))
[[ $a > $b ]] || [[ $a < $c ]]
[ $a -gt $b -o $a -lt $c ]
10. 检测执行脚本的用户
if [ "$(whoami)" != 'root' ]; then
echo "You have no permission to run $0 as non-root user."
exit 1;
fi
上面的语句也可以使用以下的精简语句
[ "$(whoami)" != 'root' ] && ( echo "You have no permission to run $0 as non-root user."; exit 1 )
11. 正则表达式
doiido="hero"
if [[ "$doiido" == h* ]];then
echo "hello,hero"
fi
12. 查看当前操作系统类型
#!/bin/sh
SYSTEM=`uname -s`
if [ $SYSTEM = "Linux" ] ; then
echo "Linux"
elif [ $SYSTEM = "FreeBSD" ] ; then
echo "FreeBSD"
elif [ $SYSTEM = "Solaris" ] ; then
echo "Solaris"
else
echo "What?"
fi
13. if利用read传参判断
#!/bin/bash
read -p "please input a score:" score
echo -e "your score [$score] is judging by sys now"
if [ "$score" -ge "0" ]&&[ "$score" -lt "60" ];then
echo "sorry,you are lost!"
elif [ "$score" -ge "60" ]&&[ "$score" -lt "85" ];then
echo "just soso!"
elif [ "$score" -le "100" ]&&[ "$score" -ge "85" ];then
echo "good job!"
else
echo "input score is wrong , the range is [0-100]!"
fi
14. 判断文件是否存在
#!/bin/sh
today=`date -d yesterday +%y%m%d`
file="apache_$today.tar.gz"
cd /home/chenshuo/shell
if [ -f "$file" ];then
echo "OK"
else
echo "error $file" >error.log
mail -s "fail backup from test" loveyasxn924@126.com <error.log
fi
15. 这个脚本在每个星期天由cron来执行。如果星期的数是偶数,他就提醒你把垃圾箱清理:
#!/bin/bash
WEEKOFFSET=$[ $(date +"%V") % 2 ]
if [ $WEEKOFFSET -eq "0" ]; then
echo "Sunday evening, put out the garbage cans." | mail -s "Garbage cans out" your@your_domain.org
fi
16. 挂载硬盘脚本(windows下的ntfs格式硬盘)
#! /bin/sh
dir_d=/media/disk_d
dir_e=/media/disk_e
dir_f=/media/disk_f
a=`ls $dir_d | wc -l`
b=`ls $dir_e | wc -l`
c=`ls $dir_f | wc -l`
echo "checking disk_d..."
if [ $a -eq 0 ]; then
echo "disk_d is not exsit,now creating..."
sudo mount -t ntfs /dev/disk/by-label/software /media/disk_d
else
echo "disk_d exits"
fi
echo "checking disk_e..."
if [ $b -eq 0 ]; then
echo "disk_e is not exsit,now creating..."
sudo mount -t ntfs /dev/disk/by-label/elitor /media/disk_e
else
echo "disk_e exits"
fi
echo "checking disk_f..."
if [ $c -eq 0 ]; then
echo "disk_f is not exsit,now creating..."
sudo mount -t ntfs /dev/disk/by-label/work /media/disk_f
else
echo "disk_f exits"
fi
9. `var=$((运算内容))`
4. case流程控制语句
case $变量名 in
"字符串")
// do something
;;
"条件二")
// do something
;;
*)
// default action
;;
esac
5. for in
for var in con1 con2 con3
do
// do something
done
6. while
while [ condition ]
do
// do something
done
7. until
until [ condition ]
do
// do something
done
8. for
for((i=0; i<=100; i++))
do
// do something
done
9. 函数
function 函数名(){
// 函数内部通过 `$0`获取函数名
// $1, $2, $3...获取相应的参数值
// $# 参数总数
// $@ 参数
}
函数内的变量可以在函数外使用
调用方式: 直接函数名 [param1] [param2] [param3] ...
10. Debug方式
bash -nvx 脚本 param...
- n // 不运行脚本, 仅仅执行语法检查
-v // 将脚本的内容print到屏幕
-x // 将过程print到屏幕上
交互操作
-
read -p "提示信息" -t 5 variable (用户输入)
-
-p
: 提示信息 -
-t
: 多少秒没有输入就结束等待
-
-
declare -aixr variable(声明变量类型)
-
a
:声明为一个数组 -
i
:声明为一个整数 -
x
:声明为一个环境变量 -
r
:声明为只读变量
-
-
变量配置方式 说明 ${变量#关键词}
若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除 ${变量##关键词}
若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除 ${变量%关键词}
若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除 ${变量%%关键词}
若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除 ${变量/旧字符串/新字符串}
若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』 ${变量//旧字符串/新字符串}
若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』 字符串的替换和删除
变量配置方式 说明 ${变量#关键词}
若变量内容从头开始的数据符合『关键词』,则将符合的最短数据删除 ${变量##关键词}
若变量内容从头开始的数据符合『关键词』,则将符合的最长数据删除 ${变量%关键词}
若变量内容从尾向前的数据符合『关键词』,则将符合的最短数据删除 ${变量%%关键词}
若变量内容从尾向前的数据符合『关键词』,则将符合的最长数据删除 ${变量/旧字符串/新字符串}
若变量内容符合『旧字符串』则『第一个旧字符串会被新字符串取代』 ${变量//旧字符串/新字符串}
若变量内容符合『旧字符串』则『全部的旧字符串会被新字符串取代』 -
变量配置方式 str 没有配置 str 为空字符串 str 已配置非为空字符串 var=${str-expr}
var=expr
var=
var=$str
var=${str:-expr}
var=expr
var=expr
var=$str
var=${str+expr}
var=
var=expr
var=expr
var=${str:+expr}
var=
var=
var=expr
var=${str=expr}
str=expr,var=expr
str 不变,var=
str 不变,var=$str
var=${str:=expr}
str=expr,var=expr
str=expr,var=expr
str 不变,var=$str
var=${str?expr}
expr 输出至 stderr
var=
var=$str
var=${str:?expr}
expr 输出至 stderr
expr 输出至 stderr
var=$str
变量的其他规则
变量配置方式 str 没有配置 str 为空字符串 str 已配置非为空字符串 var=${str-expr}
var=expr
var=
var=$str
var=${str:-expr}
var=expr
var=expr
var=$str
var=${str+expr}
var=
var=expr
var=expr
var=${str:+expr}
var=
var=
var=expr
var=${str=expr}
str=expr,var=expr
str 不变,var=
str 不变,var=$str
var=${str:=expr}
str=expr,var=expr
str=expr,var=expr
str 不变,var=$str
var=${str?expr}
expr 输出至 stderr
var=
var=$str
var=${str:?expr}
expr 输出至 stderr
expr 输出至 stderr
var=$str
-
符号 内容 #
批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不运行 \
跳脱符号:将『特殊字符或通配符』还原成一般字符 ` ` 管线 (pipe):分隔两个管线命令的界定(后两节介绍); ;
连续命令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同) ~
用户的家目录 $
取用变量前导符:亦即是变量之前需要加的变量取代值 &
工作控制 (job control):将命令变成背景下工作 !
逻辑运算意义上的『非』 not 的意思! /
目录符号:路径分隔的符号 >, >>
数据流重导向:输出导向,分别是『取代』与『累加』 <, <<
数据流重导向:输入导向 (这两个留待下节介绍) ' '
单引号,不具有变量置换的功能 " "
具有变量置换的功能! `` 两个『 ` 』中间为可以先运行的命令,亦可使用 $( ) ( )
在中间为子 shell 的起始与结束 { }
在中间为命令区块的组合! bash环境中常用通配符的使用
符号 内容 #
批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不运行 \
跳脱符号:将『特殊字符或通配符』还原成一般字符 ` ` 管线 (pipe):分隔两个管线命令的界定(后两节介绍); ;
连续命令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同) ~
用户的家目录 $
取用变量前导符:亦即是变量之前需要加的变量取代值 &
工作控制 (job control):将命令变成背景下工作 !
逻辑运算意义上的『非』 not 的意思! /
目录符号:路径分隔的符号 >, >>
数据流重导向:输出导向,分别是『取代』与『累加』 <, <<
数据流重导向:输入导向 (这两个留待下节介绍) ' '
单引号,不具有变量置换的功能 " "
具有变量置换的功能! `` 两个『 ` 』中间为可以先运行的命令,亦可使用 $( ) ( )
在中间为子 shell 的起始与结束 { }
在中间为命令区块的组合! -
数据的重定向
- 标准输入 (stdin) :代码为 0 ,使用 < 或 << ; // <<表示追加写入
- 标准输出 (stdout):代码为 1 ,使用 > 或 >> ;
- 标准错误输出(stderr):代码为 2 ,使用 2> 或 2>> ;
- /dev/null 垃圾桶黑洞装置与特殊写法,如
find /home -name .bashrc 2> /dev/null
- 讲错误和输出写入同一文件中, 写法如下:
find /home -name .bashrc > list 2>&1
-
管线命令
-
awk
命令(简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理,从$1
开始)- 语法
-
$0
变量是指整条记录。$1
表示当前行的第一个域,$2
表示当前行的第二个域,......以此类推。 - 内置变量:
-
ARGC
命令行参数个数 -
ARGV
命令行参数排列 -
ENVIRON
支持队列中系统环境变量的使用 -
FILENAME
awk浏览的文件名 -
FNR
浏览文件的记录数 -
FS
设置输入域分隔符,等价于命令行 -F选项 -
NF
浏览记录的域的个数 -
NR
已读的记录数 -
OFS
输出域分隔符 -
ORS
输出记录分隔符 -
RS
控制记录分隔符
-
-
print
和printf
-
- 用法:
awk '{pattern + action}' {filenames}
-
pattern
:执行的匹配模式,如:-F ':'
,以:分隔(默认为空格分隔) -
action
:要执行的操作
-
- 使用示例:
cat /etc/passwd |awk -F ':' '{print $1}'
cat /etc/passwd |awk -F ':' 'BEGIN {print "name,shell"} {print $1","$7} END {print "blue,/bin/nosh"}'
last -n 5 | awk '{print $1}'
awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd
ls -l | awk 'BEGIN {size=0;} {size = size + $5;} END {print size / 1024, "k"}'
ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
awk -F ':' 'BEGIN {count=0;} {name[count] = $1;count++;}; END{for (i = 0; i < NR; i++) print i, name[i]}' /etc/passwd
- More
- 语法
-
cut
命令-
cut -d'分隔字符' -f 第几段字符区间
// 字符区间从1开始-
echo $PATH | cut -d ':' -f 3,5
// 将环境变量路径按:
分隔, 并取出第3和第5段区间
-
-
cut -c 2-5
// 取出第2到第5之间的字符
-
-
grep [-acinv] [--color=auto] 正则表达式 filename
- 参数
-
-a
:将 binary 文件以 text 文件的方式搜寻数据 -
-c
:计算找到 '搜寻字符串' 的次数 -
-i
:忽略大小写的不同,所以大小写视为相同 -
-n
:顺便输出行号 -
-v
:反向选择,亦即显示出没有 '搜寻字符串' 内容的那一行! -
--color=auto
:可以将找到的关键词部分加上颜色的显示喔! -
-A
:往后n行 -
-B
:往前n行 -
-C
:往前和往后各n行
-
- 正则表达式
-
.
:匹配任意单个字符 -
[]
:匹配指定范围任意单个字符 -
[^]
:匹配指定范围外任意单个字符 -
*
:匹配前面字符任意多次(贪婪模式) -
\?
:匹配前面字符1次或0次 -
\{m,n\}
:匹配前面字符次数n到m次 -
^
:行首 -
$
:行尾 -
\b
:锚定单词首或尾 -
\(\)
:分组匹配 -
\n
:反向引用,如:\1
-
- 参数
-
sort [-fbMnrtuk] [file or stdin]
-
-f
:忽略大小写的差异,例如 A 与 a 视为编码相同; -
-b
:忽略最前面的空格符部分; -
-M
:以月份的名字来排序,例如 JAN, DEC 等等的排序方法; -
-n
:使用『纯数字』进行排序(默认是以文字型态来排序的); -
-r
:反向排序; -
-u
:就是 uniq ,相同的数据中,仅出现一行代表; -
-t
:分隔符,默认是用 [tab] 键来分隔; -
-k
:以那个区间 (field) 来进行排序的意思
-
-
uniq [-ic]
// 去重-
-i
:忽略大小写字符的不同; -
-c
:进行计数
-
-
wc [-lwm]
-
-l
:仅列出行; -
-w
:仅列出多少字(英文单字); -
-m
:多少字符;
-
- 合并多个文件为一个文件
cat file1 file2 >> newfile
-
split [-bl] file PREFIX
// 将大文件分割成小文件-
-b
:后面可接欲分割成的文件大小,可加单位,例如 b, k, m 等; -
-l
:以行数来进行分割。 -
PREFIX
:代表前导符的意思,可作为分割文件的前导文字。
-
-
xargs
- 很多命令其实并不支持管线命令,因此我们可以透过 xargs 来提供该命令引用 standard input 之用
- 管道命令中将前一个命令的用到文件名传递给下一个命令,可使用
-
- 如:
tar -cvf - /home | tar -xvf -
- 如:
-
-
定时任务
-
at
:-
-l or atq
: 列出所有排程 -
-d or atrm 排程号
: 删除排程 -
-c 排程号
: 查看该排程的具体信息 -
时间
- 时间格式:
-
HH:MM
ex> 04:00
在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此工作。 -
HH:MM YYYY-MM-DD
ex> 04:00 2009-03-17
强制规定在某年某月的某一天的特殊时刻进行该工作! -
HH:MM[am|pm] [Month] [Date]
ex> 04pm March 17
也是一样,强制在某年某月某日的某时刻进行! -
HH:MM[am|pm] + number [minutes|hours|days|weeks]
ex> now + 5 minutes ex> 04pm + 3 days, 就是说,在某个时间点『再加几个时间后』才进行。
-
- 时间格式:
-
-
batch 时间
:- 如果当时的CPU负载大于0.8, 则暂缓进行该项任务, 可以通过atq和atrm进行管理
-
crontab
:
-
-
前台任务和后台任务(连续按ctrl+z两次可将任务转至后台并暂停,然后通过
fg %任务号
来唤醒到前台执行)-
bg
,查看当前的后台任务 -
jobs
,查看当前的后台任务 -
command &
, 任务后台执行 -
nohup command &
, 与终端机无关的背景执行任务(如远程登录断开连接后, 继续在后台执行)
-
-
daemon相关知识
-
service
-
service --status-all
: 将系统所有的 stand alone 的服务状态通通列出来 service service-name {start|stop|restart|...}
-
-