目录
16.在SecureCRT中把文件传给本机的‘我的文档’目录下
59. 向文件追加多行内容(Here Document 特性)
61. 为文件内每个匹配内容对(不在同一行的先后出现的2个内容)进行关联修改(使用内容队的第1个的内容修改第2个的内容)
62. 提取文件中的第1列并使用空格拼接(方便作为参数输入)
67. 测试urls列表里的资源地址是否可用且返回指定类型内容(改进版)
68. 读取字节设备(如镜像文件)的内容(最简语法实现,嵌入式Linux可用)
Red Hat Linux 9 编程开发与网络管理 冉林仓 电子工业出版社 2006 (将linux系统的各种情况和dos系统做了对比)
UNIX基础教程 龚汉明等 清华大学出版社 2007
Linux应用开发技术详解 范永开等 人民邮电出版社 2006
Linux Shell 脚本攻略 Sarath Lakshman 人民邮电出版社 2011
在线linux:JSLinux
★shell编程
0.Shell命令支持选项
#!/bin/bash 指定了shell脚本的执行shell
可以在使用bash命令运行时,使用选项-x来控制功能,或者在shell脚本里通过命令set -x来控制功能(set -x表示开启x功能,set +x表示关闭x功能)。
多个指令可以合并缩写,例如:-ex
支持的命令选项列表:
选项 | 说明 |
-e | 出错后立刻退出,不再继续运行剩下的命令。 |
-u | 遇到不存在变量,报错并停止。 |
-x | 显示执行的每条命令和其参数值。 |
-a | 将变量输出至环境变量。 |
-n | 只读取指令,而不实际执行。 |
-v | 显示shell所读取的输入值。 |
更多参数 |
1.变量
变量名区分大小写,无须声明,可以直接赋值;引用变量需要在变量前面加$符号。注意:直接赋值时变量和=之间不带空格,如'var=100'。
如果需要用变量和其他字符组成新的字符串,可以把变量用{}括起来。比如“I'm ${name}.”
对于未赋值的变量,bash会以空值对待,也可以使用unset命令来清除给变量赋的值。
数组形式为:变量名[下标]=值,或者 变量名=(val1 val2 val3),或者 array=([index1]=val1 [index2]=val2 [index3]=val3)。下标可以用字符做索引,则为关联数组。
使用readonly来定义只读变量,该变量的值不能被改变,只能unset来删除。
declare(或typeset,兼容Korn shell,bash推荐使用declare)命令设置变量,-r 只读,-i 整型, -a 设置为数组。
export可以把变量输出到环境中,以使其他程序也可以使用。相反,使用local声明的变量是局部变量,仅供在当前函数内使用。
特定shell变量:$0当前命令对应的可执行文件名;$1-$9命令参数;$#参数个数;$*所有参数;$@所有参数,并且每个参数以'括住;$$当前进程ID号;$?最后的命令的退出状态,如果正常退出则返回0,反之为非0值。
变量扩展修饰符:
a) ${var:-val} 如果变量var已经初始化并且值非空,则返回$var的值,否则返回值val
b) ${var:=val} 该表达式始终返回$var的值,如果变量var没有初始化或者值为空,则先设置$var的值为val,再返回$var的值。
c) ${var:+val} 如果变量var已经初始化并且值非空,则返回值val,否则返回空。
d) ${var:?val} 如果变量var已经初始化并且值非空,则返回$var的值,否则打印值val(一般是个说明)并退出shell。
e) ${var:offset} 返回变量var中从offset开始到末尾的子串
f) ${var:offset:length} 返回变量var中,从offset开始,长度为length的子串
g) ${#var} 获取变量长度
h) ${var%parttern} 通配符从右向左最小匹配,从var中删除通配符所匹配的字符串,即保留了var的左侧部分;其中匹配符parttern非正则表达式,仅仅是以*来表示通配符。
i) ${var%%pattern} 从右向左最大匹配后删除;
j) ${var#pattern} 通配符从左向右最小匹配,从var中删除通配符所匹配的字符串,即保留了var的右侧部分;
k) ${var##pattern} 从左向右最大匹配后删除。
数组的操作:
a) 数组长度:${#array[*]}
b) 获取数组所有值:${array[*]} 或 ${array[@]}
c) 获取数组所有索引:${!array[*]} 或 ${!array[@]}
d) 遍历数组:
myArr=('a' 'b')
for var in ${myArr[@]}
do
echo $var
done
重要的环境变量:
/proc/$$/environ 程序运行的环境变量,以\0分割,可以 | tr '\0' '\n' 显示为按行分割
$PATH 执行路径
$HOME 当前用户的主目录
$PWD 当前工作路径
$USER 当前使用的帐户名
$UID 当前使用的UID,如果非0,则不是root用户
$SHELL 执行当前脚本使用的shell名称
$PS1 Bash提示字符串,默认为"[\u@\H \W]\$"
$IFS 内部字段分隔符,是for循环等的数据流划分成不同数据元素的定界符。默认是空,表示以换行,空格或制表符为分隔符。
$RANDOM 随机值
2.特有命令
: 空,永远返回true,可用于while循环作为条件
shift 可以后跟一个数字n来左移n个参数
read 从输入设备读入变量值,后必须跟一个变量名
echo 显示信息
eval 它把参数连接成一个命令让shell执行
exec 执行命令
return/break/continue 在函数和循环中使用
3.比较语句
使用test expression或[ expression ]形式.
注意:
1. 在bash语法中,if语句中应该使用[[ ]]进行判断。注意:需要使用[ ]才能支持逻辑操作的与、或、非。
2. 对字符串进行判断时,一定要使用""括住变量,而不能直接判断变量,否则会得到错误的结果。例如$nu; 则[ -n $nu ]为真;[ -n "$nu" ]为假。
3. [[ ]]和其内容之内的前后之间需要有空格,例如if [[ "$1" = "xxx" ]]是可以的,在if和[[之间,[[和"$1"之间,=前后,"xxx"和]]之间,都是有空格的。
4. 正则判断=~在某些shell下不好用,建议用echo $line | grep -q "$key"; if [[ $? ]];then ... 来替代。
字符串比较:比较两个字符串内容是否相同可以直接使用=或!=操作符。选项-n用于判断字符串是否非空。选项-z用于判断字符串是否为空。使用=~来判断正则匹配,比如[ "${line}" =~ ".*${keywd}.*" ]来判断line中是否包含keywd。
数值比较:使用选项-eq,-ne,-lt,-gt,-le,-ge来判断两个数值之间的大小。
文件操作:选项-d,-f,-L分别用于判断对象类型是否是目录,文件和符号链接。选项-r,-w,-x分别用于判断文件属性是否是可读,可写,可执行。选项-e用来判断文件是否存在,选项-s用来判断文件长度是否大于零。选项-n用来判断第一个文件是否比第二个文件新(根据修改日期)。
逻辑操作:使用选项-a,-o,!来表示与,或,非的逻辑操作。
4.算术计算语句
使用let expression或(( expression ))形式
可以在表达式里使用多种操作符,如+,-,*,/,%,<=,>=,<,>,==,!=,=等
注:返回的是一个变量,故赋值前要加$符号,使用类似以下方式赋值:
var=100
var=$(($var+1))
5.大括号扩展
举例:
>echo {1..9}
1 2 3 4 5 6 7 8 9
>echo {9..1}
9 8 7 6 5 4 3 2 1
>echo {a..f}
a b c d e f
>echo {f..a}
f e d c b a
>echo {1..9..2} #步阶为2,mac上不支持
1 3 5 7 9
>echo {9..1..2}
9 7 5 3 1
>echo {a..f..2}
a c e
>echo {f..a..2}
f d b
>echo {a,x}
a x
>echo {a,x}.txt
a.txt x.txt
>echo plain{1..5}.txt
plain1.txt plain2.txt plain3.txt plain4.txt plain5.txt
6.控制语句
使用
for循环语法格式如下:
for var in list
do
...
done
以上语句对list列表中以换行,空格,制表符分隔的对象实行遍历。如果需要可以通过改变IFS的值来更改分割符,例如 IFS=, 即以逗号做分隔符,可以处理类似 list="one,two,three" 的情况。
while循环语法格式如下:
while condition
do
...
done
当条件为真时循环执行。
until循环语法格式如下:
until condition
do
...
done
当条件为假时循环执行。
if语句语法如下:
if cond1
then
...
elif cond2
then
...
else
...
fi
case语句语法如下:
case string in
str1|str2)
...
;;
str3)
...
;;
*)
...
;;
esac
select语句语法如下:
select name in list
do
... #一般在这里使用case
done
7.函数
函数定义的基本格式如下:
function name
{
...
}
函数调用的形式类似于普通的命令,也可以加参数。并且函数可以采用递归形式。
★linux基本命令
1.命令语法
" " 双引号表示整个引号内的内容是一个完整字符串,如果字符串中包含环境变量,则会在执行时被替换成环境变量对应的内容
' ' 单引号也表示整个引号内的内容是一个完整字符串,但不会对环境变量进行替换
` ` 反引号括起来的内容被作为命令行处理,执行的结果用来代替整个反引号所括起来的内容.也可以使用$(cmd)形式
; 用来在命令行中分隔多个命令,多个命令会顺序执行,但前一个命令是否成功执行并不会影响后一个命令的执行
&& 也可以分隔多个命令,只有前一个命令成功执行才会再执行下一个命令
& 也可以分割多个命令,多个命令会同时执行
> 输出重定向字符,注:>相当于1>,即标准输出的重定向;2>表示标准错误的重定向;&>或>xx.txt 2>&1表示合并stdout和stderr结果,然后再重定向;完全屏蔽输出使用“>/dev/null 2>&1”
< 输入重定向字符
>> 重定向追加字符
| 管道符,将一个命令的输出传送给另一个命令作为输入
& 位于命令行的末尾,表示后台处理,返回的是命令的PID
2.帮助命令
man 显示详细帮助。man查看的文档保存在usr/share/man目录下的各个子目录中以.gz格式存储。此外,还可以在usr/share/doc和usr/doc目录下找到大量的FAQs和How-To操作指南。也可以在命令后加--help选项来实现相同的功能.
whereis 用于查找命令,帮助信息等所在的位置,仅限于内部命令;whatis 用于显示命令的简单描述,是取自帮助信息,故也只能用于内部命令。
which 用于查找命令或执行文件的位置,也会给出别名命令的真实命令和位置。
type 查询命令类型,对应非别名命令(内部命令或路径里可执行文件)都会给出可执行文件的地址,别名命令只会给出真实命令。
info 用于显示命令相关的信息文档。已经被man代替,不推荐。
3.系统状态命令
w 查看当前使用系统的用户,也等同于who命令;whoami命令查看当前登录的用户;id不带参数,显示当前用户的信息,也可以带用户名参数,显示该用户的信息;last 可以提示登录会话信息,其实是一个登录会话的日志。
wall 向终端中所有的当前登录用户发送广播消息。例如: ’echo “hello everybody” | wall‘
date 显示当前日期和时间,例如date +'%Y-%m-%d %H:%M:%S'可以指定格式显示日期时间。注意:-d参数可以得到其他时间,例如:date -d "5 minute ago" +"%m-%d %H:%M",可以得到5分钟之前的时间,并按照指定格式输出。
cal 显示日历
env 不带参数则显示所有环境变量,也多用于自动执行文件,类似于: #!/usr/bin/env ruby
4.通用命令
grep 它能使用正则表达式搜索文本并把匹配的行显示出来。选项-v只显示不匹配的行,-i匹配时忽略大小写。
sort 排序
uniq 去除重复,选项-d是只显示重复项
tee 把输出同时输出到标准输出和文件中,默认是覆盖到文件,-a则追加到文件
expr 进行数学运算
alias 为字符串或命令起别名,unalias禁止一个别名。使用 ‘\commend’ 方式来执行命令commend时,忽略可能存在的别名,是一种不错的安全实践。
history 显示已输入过的命令,使用!加命令号码可以重新执行该命令
time 后加命令可以显示该命令执行所用的时间,该时间会被添加到stderr中;也可以使用 -o 选项将执行时间记录到文件中
clear 清屏
export 导出变量,如添加新路径,但重启后就会恢复修改。
5.文件和目录操作命令
cd 切换目录。cd-返回上一个目录,cd~进入用户的home目录。
ls 目录列表。选项-a显示全部文件,-l显示长信息,-R递归列出所有子目录的内容,--sort=time按更新时间降序排序。注:alias ll='ls -l --color=tty'
mkdir 建立目录。
rmdir 删除目录。
rm 删除文件。选项-f强制删除,-i删除前给出提示信息,-r|-R递归删除所有子目录和文件。
cp 复制。选项-r|-R递归复制所有子目录和文件,-u不覆盖更新的文件,-b为被覆盖的文件创建备份(默认以~为后缀)。
mv 移动或重命名文件。
ln 建立连接文件.
chmod 改变文件的存取权限。a为所有用户,u为所有者,g为组用户,o为其他用户,对这几种范围可以使用+,-,=来设置r,w,x属性。-R来做递归修改。
umask 改变文件的默认存取权限
chown 改变文件的属主
chgrp 改变文件所属的组
touch 更新文件的时间标志或创建新文件
pwd 显示当前工作路径
cat 显示文件内容,选项-n显示行号,-s显示时合并多个空行为一个空行,-T将tab符显示为^I
more 按页显示文件内容,中途可以按q提前退出
less 按页显示文件内容,可以使用翻页键来前后翻页
wc 统计文件中的行数,单词数和字符数
find 查找文件。选项-name后可跟文件名的匹配模式,-iname则文件名忽略大小写,-exec cmd '{}' ';'使用每一个匹配的文件名作为参数执行指定的命令。其他常用参数:-group -user -nouser -empty -size +/-512k -amin -n -atime -n -mmin-n -mtime -n
locate 定位路径。支持多个搜索字符串和正则表达式匹配。
file 判断可执行文件的具体类型
strings 查找一个二进制文件中的可显示字符串
head 显示文件的开头10行,-n N 等同于‘-N’,显示开头的N行,-n -N 显示除了结尾的N行的其余行。
tail 显示文件的末尾10行,-n N 等同于‘-N’,显示末尾N行,-n +(N+1) 显示除了开头N行的其余行。
gpg 利用gpg数字签名技术对文件进行加密,使用-c 选项后接源文件file进行加密,生成file.gpg文件;直接跟file.gpg文件即可解码。加密/解码时会提示输出密码。
6.用户帐号管理命令
useradd 添加用户
passwd 为用户制定密码
userdel 删除用户,选项-r会删除该用户账户拥有的所有目录和文件
usermod 更改用户的设置
groupadd 增加一个用户组
groupdel 删除一个用户组
groupmod 更改一个用户组的设置
7.进程管理命令
nice 改变指定进程的优先级,优先级默认为10,值越小优先级越高
ps 对当前的进程状态进行快照并显示.
top 动态显示进程状态,选项-d指定刷新间隔,单位为秒
kill 杀死指定PID的对应进程,选项-9/-KILL是强行结束,-1/-HUP是重新运行,不加参数默认是-15/-TERM
8.磁盘和设备管理命令
df 检查文件系统的磁盘空间占用情况,选项-a显示所有文件系统
du 显示指定目录的磁盘空间的使用情况,选项-s只显示总数,-a递归显示所有文件和子目录,默认是只递归显示子目录
mount 加载设备,选项-t type dev dir用来加载设备的文件系统到指定的目录,type指定分区类型,vfat为FAT32或FAT16,ntfs为NTFS分区,-ocodepage=936,iocharset=cp936指定用中文显示文件名和目录。
例如:
加载U盘:mount /dev/sda1 /usb -ocodepage=936,iocharset=cp936。
加载软盘:mount /dev/df0 /mnt/floppy
加载光盘:mount /dev/cdrom /mnt/cdrom
如果需要开机时自动加载,需要把以上命令的参数加入etc/fstab
umount 卸载指定目录对应的文件系统
9.网络管理命令
nslookup 将域名解析为IP地址
ifcongfig 网络接口配置,可以配置IP地址,子网掩码等
route 路由配置
netstat 显示网络状态信息
ping ping命令,选项-c后跟测试次数
traceroute 跟踪路由,得到数据包从源主机到目标地址的路由信息
service 启动某个守护进程
arp 地址解析协议命令,选项-a可以显示当前访问的所有远程主机名,IP地址和硬件地址
telnet 远程登陆命令
ftp ftp命令
10.常用应用程序
vi 有三种模式:命令模式,文本输入模式,命令提示行交互模式。常用的编辑指令有:wq存盘退出,w FileName把缓冲区内容写入指定文件中,q!不存盘直接退出,n,mw FileName把n~m行写入指定文件中,n,mw>> Filename把n~m行追加到指定文件中。
emacs 是linux平台另一个流行文本编辑器
awk 可以对匹配模式的行进行指定的操作.命令的格式为awk -F [fild_separator] 'pattern {action} pattern {action}'input_file
sed 也是一个文本过滤工具.
tar 命令的常用选项有:c用于创建新的档案文件,t查看档案文件的内容,x从档案文件中释放文件,v显示命令处理的文件信息,f使用档案文件或设备,z使用gzip进行过滤处理。
使用举例:
tar cf my.tar /home 把/home目录下所有的文件和子目录打包成my.tar文件
tar xvf root/my.tar /home 把root目录下的my.tar文件展开到/home目录下
tar tvf my.tar 查看my.tar文件的内容
tar cfz my.tar.gz /home 使用gzip压缩的打包文件(也常用.tgz或.tar.z作为扩展名)
tar -cfz my.tar.gz --exlude myfile/log myfile 把当前目录下的myfile文件或文件夹压缩成my.tar.gz文件,而且,不包含myfile文件中的log文件或目录
tar tvfz my.tar.gz 查看my.tar.gz文件的内容
tar xvfz my.tar.gz /home 解压缩gzip的打包文件
gzip 该命令是linux下经常使用的压缩和解压缩工具,压缩后文件的扩展名默认为.gz。常用的选项有:-d解压缩(默认功能是进行文件压缩),--fast最快压缩,--best最好压缩。gunzip即对应gzip -d的命令,用来解压缩文件。
unzip 命令主要用于解压Windows平台下winzip压缩的文档,扩展名即为.zip。选项-P< >输入密码。
zip 命令则用于以winzip格式压缩多个文件。
uncompress 命令用于解压缩.Z格式的文档。
11. 使用软件包管理器一键式安装软件包和依赖
1)RPM
RPM是RedHat Package Manager(RedHat软件包管理工具)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux、S.u.S.E.以及Turbo Linux等Linux的分发版本都有采用,可以算是公认的行业标准了。
rpm 命令可以实现RPM软件包的安装、更新、卸载和检验等操作。常用的选项有:-i安装,-h安装时显示安装进度,-v显示附加信息,-q查询安装包的是否安装和版本信息,-e卸载安装包,-U升级安装。
举例如下:
rpm -ivh usermin.rpm 安装RPM软件包
rpm -q webmin 查询
rpm -qpi webmin 列出RPM软件包的描述信息
rpm -e webmin 卸载RPM安装包
rpm -Uvh usermin.rpm 升级安装
2)apt
Advanced Packaging Tool(apt)是Debian发明,用于其软件包管理工具dpkg(可以安装本地deb文件但不解决文件依赖关系)的前端,可以在制定软件包名称后自动下载更新的版本并解压缩,编译和安装。APT使用一个文件列出可获得软件包的镜像站点地址,这个文件就是/etc/apt/sources.list。APT由几个名字以“apt-”打头的程序组成。apt-get、apt-cache 和apt-cdrom是处理软件包的命令行工具。
/etc/apt/sources.list #软件源设置
apt-get update #更新软件源数据
apt-get upgrade #更新已安装软件
apt-get dist-upgrade #更换系统版本
apt-get -f install #通过安装包或卸载包来修复依赖错误
apt-cache search foo #搜索软件源数据
apt-cache show<span style="white-space:pre"> </span>#获取包的相关信息,如说明、大小、版本等
apt-get install foo #解压安装软件包
apt-get --reinstall #install foo 重新安装软件包
apt-get remove foo #删除软件包释放的内容
apt-get --purge remove foo #卸载软件,同时清除该软件配置文件
apt-get autoclean #删除不需要的包
apt-get clean #删除所有已下载的包
apt-get build-dep foo #自动安装编译一软件所需要的包
3)yum
Yum(全称为 Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE、CentOS中的Shell前端软件包管理器。基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,并且一次安装所有依赖的软件包。
常用的参数:-e 静默执行 ,-t 忽略错误,-R[分钟] 设置等待时间,-y 自动应答yes,--skip-broken 忽略依赖问题,--nogpgcheck 忽略GPG验证
常用命令:
yum -y install foo-x.x.x.rpm #安装软件包
yum remove foo-x.x.x.rpm #卸载软件包,也可以使用:yum erase foo-x.x.x.rpm
yum update foo #更新软件包,也可以使用:yum upgrade foo
yum info foo #查询信息
yum search foo #搜索软件包
yum deplist foo #显示软件包依赖关系
yum list installed #列出已经安装的软件包
yum list extras #列出已经安装且不在资源库的包
yum reinstall foo #重新安装软件包foo
yum localinstall xx.rpm #安装本地的rpm包
4)区别
一般来说著名的 Linux 系统基本上分两大类:
RedHat 系:Redhat、Centos、Fedora 等 。它们使用rpm作为包安装工具;yum作为依赖管理工具。
Debian 系:Debian、Ubuntu 等。它们使用dpkg作为包安装工具,apt作为依赖管理工具。
12.开放源代码的编译使用
在readme和install文档中一般都介绍了编译方法和安装步骤,列出了程序正常工作需要的其他程序、编译选项,以及默认安装位置等。一般步骤是:
./configure [--prefix=/home/my/tool --exec-prefix=/home/my/tool]
make
make install
注意:在这种方式下,一般前两步用户权限就可以,而第三步需要root权限,否则无法写入/usr/bin等目录。解决办法是执行configure命令时添加--prefix=/home/my/tool --exec-prefix=/home/my/tool两个参数来指定目录。
★Red Hat Linux的图形界面
X Windows系统由许多部分组成,包括X服务器,X客户端,X协议,X开发库和X工具箱.和用户实现交互的是X客户端,它借助于X协议访问X服务器.在一个系统中可以拥有多个X客户端,但是只能运行一个X服务器.
Windows操作系统除98外操作系统和GUI界面是紧密耦合的,Linux中的字符界面和GUI界面是完全独立的.
在/etc/inittab文件里修改默认启动级别为5可以更改默认启动的用户界面.
X Windows在即插即用方面做了很大改进,可以自动识别需要mount的设备.
两种桌面风格:GNOME和KDE
常用应用程序:文件管理器Nautilus,运行对话框,搜索文件,运行终端,记事本gedit,系统监视器,包管理器,服务管理器,浏览器Firefox,办公软件OpenOffice包括Writer,Calc,Impress等,Wine模拟器模拟windows系统程序.
RedHat的shell界面中,用蓝色表示文件夹,青色表示链接文件,白色表示文件。
★文件布局详解
一、根目录详解
/usr 操作系统的命令,库和文档
/etc 系统配置文件,不包含可执行文件
/var 动态信息,如日志,临时文件,缓冲文件
/home 用户目录
/root root用户的主目录
/lib 库文件
/bin 标准命令文件
/sbin 系统管理命令
/opt 应用程序
/dev 设备文件
/mnt 挂接临时映射的文件系统
/tmp 临时文件夹,随时可清空
/boot 内核和引导加载器
/proc 位于内存中的伪文件系统,存放进程和系统信息
二、部分子目录详解
1./usr目录的子目录
bin 操作系统的命令
sbin 系统管理命令
local 用户自己新安装的软件
X11R6 与X Windows相关的内容
include C开发工具需要的头文件
share 共享目录,如帮助手册和技术文档
2./var目录的子目录
log 日志文件
spool 缓冲文件
local 安装程序产生的中间数据
run 系统运行期间的有关系统信息
tmp 临时文件夹
3./dev目录的子目录
hd[s][d] s为a,b,c,d等表示第n块IDE硬盘驱动设备,d为1,2,3,4,5等表示第n个分区
sd[s][d] s为a,b,c,d等表示第n块SCSI硬盘驱动设备,d为1,2,3,4,5等表示第n个分区
ttyS[d] d为1,2,3,4表示COM1~COM4设备
lp0 并口设备
null 空设备,用于屏蔽输出消息或者删除不需要的文件
4./proc目录的内容
version 保存了Linux核,gcc等版本号
cpuinfo CPU信息
meminfo 内存状态的信息
stat 这个文件包含的信息有CPU利用率,磁盘,内存页,内存对换,全部中断,接触开关以及上次自举时间(自1970年1月1日起的秒数)
uptime 自从上次系统自举以来的秒数,以及其中有多少秒处于空闲
loadavg 给出以几个不同的时间间隔计算的系统平均负载
devices 字符和块设备的主设备号和设备名称
modules 可加载内核模块的信息
mounts 给出当前系统所安装的文件系统信息
dma DMA通道和驱动程序名称
pci 给出PCI设备的信息
ioports 设备的I/O端口范围
kcore 物理内存以core文件格式保存的二进制格式文件
filesystems 可供使用的文件系统类型
interrupts 中断号和发生中断次数
数字n 该文件夹存储了pid和数字n相同的应用进程的信息,包括该应用进程的可执行文件的所在路径都可以在这里查到(在该文件夹建立了可执行文件的链接文件,ll 即可看到可执行文件的实际地址)。重要的文件和目录介绍如下:
a) environ:包含与进程相关联的环境变量
b) exe:是一个到进程工作目录的符号链接
c) fd:包含了由进程所使用的文件描述符
5.Bash配置:
~/.bash_profile 当用户登录时,该文件仅仅执行一次;是交互式、login方式进入 bash运行的
~/.bashrc 当登录时以及每次打开新的shell时,该文件被读取;是交互式 non-login方式进入 bash运行的
通常二者设置大致相同,所以通常前者会调用后者。
使用source命令可以不重启而令配置文件立刻生效
source FileName作用:在当前bash环境下读取并执行FileName中的命令。source在当前bash环境下执行命令,而scripts是启动一个子shell来执行命令。这样如果把设置环境变量(或alias等等)的命令写进scripts中,就只会影响子shell,无法改变当前的BASH,所以通过文件(命令列)设置环境变量时,要用source 命令。
6.重要文件和目录
/etc/inittab 用来保存默认启动的运行级别,设置为5可直接进入X窗口。
/etc/fstab 用来存放文件系统的静态信息的文件,自动挂载文件系统应该修改此文件。
/etc/resolv.conf 编辑DNS地址
/etc/sysconfig/network 修改主机名
/etc/sysconfig/network-scripts/ifcfg-eth0编辑IP地址,掩码和网关。可以使用netconfig命令来在文本图形界面里设置该文件和DNS地址的文件。
/etc/profile 所有用户的配置文件,可以把export语句加入这里来为所有用户添加环境变量。
/usr/share/dict/words 保存了单词列表,每行一个单词
/dev/null 控设备,可以将不需要显示的内容重定向到这里
/dev/stderr 标准错误输出。对于tee命令,如果带上这个参数,就会同时输出到stdout和stderr,而stdout可以用管道传给下个命令,stderr则输出到终端上
7.重要的环境变量
PATH 可执行文件搜索路径,一般用export PATH=$PATH:/newpath来添加新路径
LANG 显示语言。LANG=UTF-8可以正常显示英文。在X窗口的终端里可以设置LANG=zh_CN.UTF-8显示中文。在纯控制台下是不可以简单通过设置LANG来显示中文的。
★VMWare网络配置
1.桥接方式(bridge) :
默认使用vmnet0
将虚拟机的ip设置与主机同网段未使用ip,其余与主机相同:
ip地址与主机同段相异,子网掩码,网管,DNS服务器与主机相同。
实现虚拟机<--->主机虚拟机<---->互联网通信。
2.共享方式(nat) :
默认使用vmnet8
将虚拟机设置成使用DHCP方式上网,windows下选择"自动获取ip",linux下开启DHCP服务即可。
3.私有方式(host-only):
默认使用vmnet1
将虚拟机ip设置与vmnet1同网段,gateway设置成vmnet1的ip,其余设置与vmnet1相同,DNS设置与主机相同
这样就实现了虚拟机<--->主机 通信,但是虚拟机<--->互联网 仍无法通信
★工作中常用的命令详解
1.从其他机器拷贝文件夹
格式: scp -r 文件夹名 用户名@机器名:/路径
范例: scp -r search work@zjm-testing-ps23.zjm.baidu.com:/home/work/
格式:rsync -v 文件夹名 用户名@机器名:/路径
范例:rsync -v search work@zjm-testing-ps23.zjm.baidu.com:/home/work/
格式:wget <url>
范例:wget ftp://zjm-testing-ps23.zjm.baidu.com//home/work/search
说明:下载远程ftp或http服务器的文件到本地当前目录
选项:可以后跟多个url,从多处进行下载;-O 指定保存的文件名;-o 指定日志信息的输出文件;-t 指定重试次数;--limit-rate 指定速度限制,例如:20k,50m;-Q/--quota 存储空间的限额;-c 断点续传;--mirror 镜像整个网站;-r -N -l DEPTH 递归指定的页面层级DEPTH,-N是指允许对文件使用时间戳;--user username --password pass 用于HTTP或FTP认证中提供用户名密码,也可以使用--ask-password来由网页提示并手动输入密码
注:wget、scp、rsync三者的比较参见专题:linux服务器之间传输文件的几种方式
2.查看哪个程序在用特定端口
格式: netstat -apen | grep 端口号
范例: netstat -apen | grep 8080
输出结果如下:
Proto Recv-Q Send-Q Local Address Foreign Address State User Inode PID/Program name
tcp 0 0 0.0.0.0:12341 0.0.0.0:* LISTEN 500 477730063 2439/gss
’grep UID /etc/passwd‘ 来获取uid的信息,如用户名;'cd /proc/PID' 来获取pid的信息,如exe的链接地址就指向了真实的可执行文件,也可以通过 ’ps aux | grep PID‘ 命令来获取pid的信息。
也可以使用如下命令来查看PID:
# list open files
sudo lsof -i:8080
3.实时监控日志文件内容
格式: tail -f 日志文件名
范例: tail -f ui.log | grep 'hello'
说明:这显示ui.log文件的最后十行中含有hello字符串的行。tail命令继续显示添加到ui.log文件中的并且含hello字符串的行。显示会一直继续,直到您按下 Ctrl-C按键顺序来停止
4.查看指定用户拥有的进程
格式: pstree 用户id
范例: pstree work
说明:显示work用户正在运行的各进程之间的继承关系,以树状结构方式列出
5.查看磁盘空间使用情况
格式: df -h
6.查找某文件中出现指定字符串的行
格式: grep 指定字符串 文件名
范例: grep 电视剧夏天的味道 ui.log
说明: 找出日志文件ui.log中包含“电视剧夏天的味道”的行
范例:grep --include *.{c,cpp} --exclude ‘common.c’ -r “function”./*
说明:在当前目录下循环查找子目录里,所有c或cpp文件,且非common.c文件中,包含function字符串的文件。
进阶:'-A n' 显示匹配行和其之后的n行,'-B n' 显示匹配行和之后的n行,'-C n' 和 '-n' 相同,显示匹配行和其前和其后的各n行;-o 只显示匹配项,以行分割;--color 将显示中的匹配项显示为红色;-E 使用正则表达式进行匹配;-c 输出匹配的行数;-i 忽略大小写的方式进行匹配;-v 只显示不匹配的行;;-r/-R 递归搜索当前目录的文件,进行匹配;-e 执行多个匹配命令,各个匹配命令是或的关系;-q 静默输出,当找到匹配项时,$?==0,当没有找到匹配项时??==1,当文件不存在时,$?==2;
7.查看内存使用情况
格式: free
8.查看系统信息
查看系统内核版本:
格式: uname -a
选项:-r 是系统的发行版本;-m 是主机类型
查看主机名:
格式:hostname
格式:uname -n
查看CPU的相关信息:
cat /proc/cpuinfo
cat /proc/cpuinfo | sed -n '5p' #cpu型号
查看内存的相关信息:
cat /proc/meminfo
cat /proc/meminfo | head -1 #内存容量
9.查看当前路径下的文件/文件夹大小
格式: du -shc 文件名/文件夹名
选项:--max-depth 限制层数;
10.变更为其它使用者的身份
格式: su 使用者帐号
范例: su work
11.远程登陆
格式: ssh 用户名@机器名
范例: ssh rd@build01
12.不挂断地运行命令(即使关闭终端连接)
格式: nohup command &
范例: nohup ./build_index.sh -d ../newdbi/ &
高级:使用screen命令可以在新窗口运行shell,并且在从远程终端退出后,仍然可以在保持窗口的状态,再以后时再次进入。
格式: screen #进入窗口(新建一个窗口)
格式: screen -list #显示当前后台(Detached)所有的窗口,格式为<session id>.<session name>例如:29334.screensession
格式: screen -r [session id]
进入窗口后:
使用exit命令退出当前窗口;
使用Ctrl+A后,输入?显示帮助,帮助中命令均要使用Ctrl+A后再去输入
使用Ctrl+A后,输入d将当前窗口Detached,回到原来的环境
使用Ctrl+A后,输入a将执行Ctrl+A的组合键功能
修改配置文件(位于~/.screenrc)进行功能加强:
#启动时不显示欢迎屏幕
startup_message off
term linux
# 定义screen的功能键为Ctrl-Z。向终端输入Ctrl-Z时应按 Ctrl-Z z。
#escape ^Zz
##设置屏幕缓冲区为4096行
defscrollback 4096
#设置状态栏
hardstatus on
hardstatus alwayslastline
shelltitle "$|bash"
hardstatus string '%{= kG}[ %{G}%c:%s %{g}][%= %{= kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][ %{C}(F1)New (F2)Rename (F3)Monitor (F4)Slience %{g}][%{kB} %d/%m %{w}%c %{g}]'
##shutdown the noise
vbell off
## w to show the window list
bind w windowlist -b
bind ^w windowlist -b
##初始化显示4个窗口,默认选择窗口0
screen
screen
screen
screen
select 0
#进行快捷键的绑定:k1-k9表示功能键F1-F9,F1、F2表示功能键F11、F12
bindkey -k k1 screen
bindkey -k k2 title
bindkey -k k3 monitor
bindkey -k k4 silence
bindkey -k k5 colon
#bindkey -k k6 split
#bindkey -k k; focus
bindkey -k k7 focus
#bindkey -k k8 only
bindkey -k k9 detach
bindkey -k F1 prev
bindkey -k F2 next
attrcolor u "-u B"
sessionname screensession
autodetach on
13.查看文件的行数
格式: wc -l 文件名
范例: wc -l as.conf
说明: 支持批量,例如 ‘wc -l ./*’
14.比较两个文件的不同之处
格式: diff 文件1文件2
-u 以统一的格式来展示。输出格式如下:@@ -127,10 +127,6 @@表示此段显示前一个文件(---)的127行开始的10行,后一个文件(+++)的127行开始的6行,在展示时,如果此行前面为-号表示只在前一个文件(---)中出现,前面为+号表示只在后一个文件(+++)中出现,前面为空格表示在两个文件中都出现。
-b 忽略空格造成的不同。
-B 忽略空行造成的不同。
-I:忽略大小写的变化。
-y 以并列的方式显示文件的异同之处。
-W<宽度> 在使用-y参数时,指定栏宽。
-u 以合并的方式来显示文件内容的不同。
-c 显示全部内容,并标出不同之处。
-q 只显示不同的文件名
diff -ruN <文件名> <文件名> > <补丁文件名>
注:vimdiff命令请参考vim的split命令。
15.杀死进程
格式: killall -9 进程名
范例: killall -9 bs.se
16.在SecureCRT中把文件传给本机的‘我的文档’目录下
格式: sz 文件名 #注:本机的保存位置,是由SecureCRT的配置项决定的
范例: sz 1.txt
17.把本机文件传给SecureCRT中当前机器的当前目录
格式: rz -be
18.Vi文本编辑器
H 光标移至屏幕顶行
nG 光标移至第n行首,等同于::n;移到文件头使用1G(等价于命令gg),移到文件尾使用G。
n+ 光标下移n行
n- 光标上移n行
* 向后查找光标所在的单词
# 向前查找光标所在的单词
n 查找下一个
N 查找上一个
nz 将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部。
J 将下一行和当前行连接为一行
r 替换当前光标所在处的字符
x/X 删除光标后/光标前的字符(前面可加数字表示删除的字符个数)
dd 剪切行(前面可加数字表示删除的行数,前面加字母表示复制到哪个缓冲区,使用缓冲区时:1. 前面加双引号开头 2.小写a-z表示替换到缓冲区,大小A-Z表示追加到缓冲区,例如:"a10dd ;另外,+表示系统剪贴板,vim需要安装增强才能支持,输入:reg来查看所有缓冲区,如果没有"+就是不支持)
yy 复制行(前面可加数字表示复制的行数,前面加字母表示复制到哪个缓冲区,使用缓冲区类上)
dw 删除一个单词;d^删除到行首;d$删除到行尾;d1G删除到文档首;dG删除到文档尾
yw 复制一个单词;y^复制到行首;y$复制到行尾;y1G复制到文档首;yG复制到文档尾
p 贴在游标后(整行复制则是下一行,前面加双引号和字母时表示从哪个缓冲区复制,例如:"ap)
P 贴在游标前(整行复制则是上一行,前面加字母表示从哪个缓冲区复制)
u 撤销命令;Ctrl+r 重做
输入:后可以使用的命令有:
split [file] 水平分割,不接文件则新窗口显示当前文件。Ctrl+W,然后按方向键可以切换窗口。
vsplit [file] 垂直分割
diffsplit [file] 比较并水平分割
vertical diffsplit [file] 比较并垂直分割
比较并分割的具体命令:1.将光标移动到蓝色区后,输入 do或者 dp,do表示将以对比的文件为标准来修改当前文件中光标所在的不同之处
dp表示以当前文件为标准,来修改对比文件中的差异之处。2.从一个差异移动到另一个差异的方法有: n[c移动到上一个差异,移动n此,如果要向下移动则使用: n]c
#,# copy/move # 把行号#,#之间的行区域复制/移动到行号#
w 保存
x 保存并退出
q! 直接退出不保存
/word 向后查找;?word向前查找
#,#s/old/new/g 替换命令,"#,#"表示两个行号之间的行区域,"old"指被替换的字符串,"new"替换成哪个字符串
%s/old/new/g 整篇替换命令
:set nu 显示行号
:set fileencoding 查看文件编码格式。
:set list/nolist 显示所有字符/隐藏不可见字符,这些不可见字符使用“Ctrl+V+字符”的方式来输入,而直接使用“Ctrl+字符”的方式可以执行该控制字符的功能。控制字符的列表可以在ASCII码的Ctrl列找到,也可以参见详细解释:ASCII字符集中的控制字符。常见的控制字符包括:^M-回车,^J-换行,^I-Tab键等。
set all 显示所有支持的vi环境变量,这些变量均可以使用set <env_var>来显示,使用set <env_var> <value>来设置新值
配置文件设置:(即~/.vimrc,默认不存在,自己新建即可)
colorscheme desert "设置背景
syntax on "自动语法高亮,也就是有多种颜色了
解决乱码(其实是GBK编码显示乱码问题)的一套方案(放于.vimrc的最顶端)
set fileencodings=ucs-bom,utf-8,cp936,gb18030,big5,euc-jp,euc-kr,latin1
set encoding=utf-8
set termencoding=cp936
language messages zh_CN.UTF-8
自动将TAB符以4个空格替换,并且将文件中TAB符以4个空格长度表示(默认为8个),该设置只对ruby和rb类型的文件生效:
autocmd FileType rb,ruby set tabstop=4 | set shiftwidth=4 | set expandtab
view xxx.txt 等价于 vi -R xxx.txt : 以只读方式打开文件
19.文件编码转换
查看文件的编码类型:
格式:file 文件名
转换文件的编码类型:
格式:iconv -f 源编码 -t 目标编码 <输入文件名> -o <输出文件名>
举例:iconv -f "GBK" -t "UTF-8" xx.txt -o xx_utf8.txt
其他选项:-l 列出所有支持的编码名称;-s 不输出警告(例如遇到转换编码错误);
格式:piconv -f 源编码 -t 目标编码 <-s 输入字符串|输入文件名>
举例:piconv -f "GBK" -t "UTF-8" xx.txt > xx_utf8.txt
其他选项:-l 列出所有支持的编码名称;-r 转换编码名称为其规范名;-s 输入字符串;
注:在处理大文件时,piconv的效率明显低于iconv。但是piconv可以对实时连续不断地输出的内容,按行进行处理并返回结果;iconv则需要等待所有输出完成后,再一次性对所有行进行处理并返回结果。
查询编码类型的规范名:
举例:piconv -r gb2312 #euc-cn
piconv -r gbk #cp936
20.文本抽取
见awk命令专题总结:AWK命令简记
21.非交互性文本流编辑器
见sed命令专题总结:sed命令简记
22.将文件中的记录排序
格式:sort [选项]–o输出文件名 [其他选项] +pos1+pos2输入文件名
参数:
-c 测试文件是否已经排序
-m 合并两个排序文件
-u 删除所有复制行
-o 存储sort结果的输出文件名
其它参数有:
-b 使用域进行排序时,忽略第一个空格。
-n 指定排序是域上的数字排序。
-t 域分隔符;用非空格或t a b键分隔域。
-r 对排序次序或比较求逆。
+n n为域号。使用此域号开始排序。
n n为域号。在排序比较时忽略此域,一般与+ n一起使用。
pos1,pos2 传递到m,n。m为域号,n为开始排序字符数;例如4,6意即以第5域排序,从第7个字符开始。
范例:sort -t: +2n video.txt 以“:”为域分割符,按第三个域数字排序video.txt
23.去除文本文件的重复行
格式:uniq [选项]输入文件 [输出文件]
参数:
-u 只显示不重复行。
-d 只显示有重复数据行,每种重复行只显示其中一行
-c 打印每一重复行出现次数。
-f n为数字,前n个域被忽略。一些系统不识别- f选项,这时替代使用- n。
范例:uniq –n2 parts.txt
-s n为数字,前n个字符被忽略。
-w n为数字,只比较n个字符
24.连接两个文本文件
格式:join [选项]文件1文件2
说明:join用来将来自两个文本文件的行连在一起,两个输入文件必须已经分过类,每个文件里都有一些元素与另一个文件相关,由于这种关系,join将两个文件连在一起。
参数:
-an n为一数字,用于连接时从文件n中显示不匹配行。例如, - a 1显示第一个文件的不匹配行,- a 2为从第二个文件中显示不匹配行。
-o n.m n为文件号,m为域号。1 . 3表示只显示文件1第三域,每个n,m必须用逗号分隔,如1 . 3,2 .1。
-j n m n为文件号,m为域号。使用其他域做连接域。
-t 域分隔符。用来设置非空格或t a b键的域分隔符。例如,指定冒号做域分隔符- t:
范例: join –o 1.1,2.2 names.txttown.txt
25.从文本文件中剪切列或域
格式:cut [选项] 文件名
参数:
-c list 指定剪切字符数。
-f field 指定剪切域数。
-d 指定与空格和tab键不同的域分隔符。
- c用来指定剪切范围,如下所示:
- c 1,5-7 剪切第1个字符,然后是第5到第7个字符。
-f 格式与- c相同。
-f 1,5 剪切第1域,第5域。
范例: cut –d: -f3 pers
26.将两个文本文件按列粘贴在一起
格式:paste [options] file1 file2
说明:粘贴两个不同来源的数据时,首先需将其分类,并确保两个文件行数相同。paste将按行将不同文件行信息放在一行。缺省情况下, paste连接时,用空格或tab键分隔新行中不同文本,除非指定-d选项,它将成为域分隔符。
参数:
-d 指定不同于空格或t a b键的域分隔符。例如用@分隔域,使用- d @。
-s 将每个文件合并成行而不是按行粘贴。
范例: paste –d: pas2 pas1 用冒号作分割符
27.将大文件进行分割
格式:split [选项]输入文件名 输出文件名前缀
参数:-a 指定后缀的长度(缺省为2)
-b 每个输出文件的字节大小
-l 每个输出文件的行数
-d 后缀以数字形式排序
范例:split –l 1000 bigfile.txtoutfile
进阶:csplit可以支持更多的筛选功能,例如:csplitserver.log /SERVER/ -n 2 -s {*} -f server -b “%02d.log”这个命令的意思是把server.log文件以包含/SERVER/的行进行分离为文件server01.log、server02.log等,并且{*}表示全部都分割。
29.查找文件
格式:find 查找路径 -iname/-name字符串
范例:find . -iname "*hello*" 2>/dev/null
说明:在当前路径下找到文件名包含hello字符串(不区分大小写)的文件。后面的输出表示不显示Permission denied的行。
范例:find . \( -name “*.txt” -or -name “*.pdf” \)
说明:查找以txt或者pdf结尾的文件
范例:find . -type f -maxdepth 1 -user work -exec cp {}{}.bak \;
说明:把当前目录下的文件全部做一个以.bak结尾的备份
范例:find . -maxdepth 2 -type d -name .git -exec rm -rf {} +
说明:把当前目录及子目录下的.git目录删除,使用加号 (+) 的方式意味着 find 将把所有匹配项传递给命令行一次,而不是为每个匹配项单独调用一次 shell。
进阶: -not否定条件,-and交集条件,-path限定路径,-mindepth限定最小路径深度,-maxdepth限定最大路径深度,-type指定搜索的文件类型(f/l/d/c/b/s/p),-atime/mtime/ctime +/-n文件在n天之前/或之内,被访问过/内容被修改过/状态发生了变化,-amin/mmin/cmin +/-n同前,只是单位为分钟,-size +/-n(b/c/w/k/M/G)文件的体积大于/小于n单位,-perm指定权限,-user指定用户
30.压缩包操作
打包:tar cvf 文件名.tar 文件
解包:tar xvf 文件名.tar
打压缩包:tar zcvf 文件名.tar.gz 文件
解压缩包: tar zxvf 文件名.tar.gz
解zip压缩包:unzip文件名.zip
31.计算文件的md5码
格式:md5sum 文件名 >保存md5码的文件名
范例:md5sum download.xml > download.xml.md5
范例:md5sum -c download.xml.md5
说明:校验md5是否正确
进阶:计算和校验sha1码的命令是sha1sum,用法类似。
32.向服务器发送POST或GET请求
格式:curl -d POST参数 url地址
范例:curl -d 'username=xx&passwd=mypd'http://www.baidu.com/login
范例:curl "http://www.baidu.com" #get方式
范例:curl -i -H 'Content-Type:application/json;charset=UTF-8' --data-ascii '{key1:val1, key2:val2}' 'http://www.sample.com/deal.php' #jason方式,可以使用--data-ascii参数来POST纯文本的数据;-i来显示HTTP头
范例:curl -F 'key1=val1' -F 'key2=val2' -F 'filekey=@file_fullpath' 'http://www.sample.com/deal.php' #上传文件,会自动添加Content-Type: multipart/form-data; boundary=----------------------------长度
选项:curl通常将下载文件输出到stdout,将进度信息输出到stderr;--silent 不显示进度信息;--progress 显示#组成的下载进度条;-O 输出保存为文件,但是必须是要访问一个文件的url时;-C offset 指定一个偏移量offset来断点续传,如果希望curl自动计算断点续传的位置,使用 ‘-C -’ 即可;--referer 设置参照页;--cookies “COOKIES” 使用cookies选项,其中cookies字符串为"name=value;name=value";--user-agent 设置UA;-H 设置头部信息,可以使用多个-H来添加多个头部信息;--limit-rate 设置限速,单位可以为k、m;--max-filesize 设置存储限额;-u username:password 完成HTTP或FTP认证,只使用 '-u username' 的话,会提示输入密码;-I/--head 只打印响应头信息(有助于进行各种检查或统计)
33.将上一个命令的结果作为参数,分组使用进行操作
格式:前一个命令 | xargs -i -t -n1 <命令和参数>
范例:find . -iname '*openmobile*' | xargs -i -t -n1 cp {} {}.bak
说明:-d参数指定分隔符,-0指定以‘\0’作为分隔符;-I指定替换字符,-I {} 和 -i{} 是一样的;-t 将要执行的命令输出到Stderr;-n2和-n 2是一样的,指定每次使用几个参数;
说明:把当前目录的文件名含有openmobile的文件,全部做个备份,生成对应的'文件名.bak'文件。其中{}引用了上一个命令的结果,n1表示如何使用上一个命令的结果,n1为执行一次命令使用1个结果值,n2为执行一次命令使用2个结果值,例如find . -iname 'openmobile*' | xargs -i -t -n2 diff –q
34.录制执行命令的脚本为文本文件
格式:script 文件名
范例:script cmdlines.txt
说明:执行exit命令或ctrl-D命令结束录制,录制的命令和输出结果会存储在cmdlines.txt文件中。
35.替换操作
格式:tr 字符集1 字符集2
范例:echo “HELLO WORLD | tr ‘A-Z’ ‘a-z’
说明:把大写转换为小写
进阶:-s 删除掉重复的 字符集1中的字符(只保留第一次出现的那个字符),-d 删除掉 字符集1中的字符,-c <字符集> 使用<字符集>的补集。
36.文件名操作和批量重命名
格式:rename ‘模式’文件
范例:rename ‘s/ /_/g’ *.txt
范例:rename ‘y/A-Z/a-z/’ *
范例:file_jpg=”sample.jpg”;name=${file_jpg%.*};extension=${file_jpg##*.}
说明:%非贪婪从右至左匹配,%%贪婪从右至左匹配,#非贪婪从左至右匹配,##贪婪从左至右匹配
37.检查拼写
格式:aspell -l 或 aspell -c文件名
范例:echo hello | aspell -l
格式:look 单词
范例:look - hello
说明:列出所有以’hello’开头的单词
38.查找两个文件内容相同的行
格式:comm 文件1 文件2 -1 -2 -3
范例:sort A.txt -o A.txt; sort B.txt -o B.txt; comm. A.txtB.txt -1 -2
说明:显示A.txt和B.txt内容相同的行;comm的输入文件必须先sort,结果显示为3列,第1列为只在A文件有,第2列为只在B文件有,第3列为在A、B文件都有的行,三个列之间用tab分割。-1,-2,-3的参数分别表示不显示第1列,第2列和第3列。
39.对文本文件按行进行循环处理
范例:...(cat filename) | (while read line; do echo $line; done)
范例:
while read line
do
echo $line
done < filename(待读取的文件)
40.倒序单词或字符
格式:rev 字符串
格式:tac 字符串
范例:echo "hello world" | tac -s ' ' | tr '\n' ' '
说明:把单词倒序,tac默认是倒序行,此处指定分隔符为空格;rev是倒序每个字符。
41. 定时任务
格式:crontab -e
说明:执行文字编辑器来设定时程表。时程表格式如下:“f1 f2 f3 f4 f5 program”,其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天(星期天为0,星期一为1,...,星期六为6)。program 表示要执行的程式。
fx的表示说明:当 f1 为 * 时表示每分钟都要执行 program;当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行;当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次;当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行。
其他参数: -l 列出目前的时程表
范例:0 2 * * * cd /home/mysql/dbproxy/log && find . -mtime +30 -exec rm -rf {} \;
说明:每天凌晨2点定期删除30天以前的日志文件
注意:如果命令行里使用了%,需要添加转义符,否则整个命令行会解析错误,不被执行
范例:cd /home/work/tools/ud_web/alamon && /home/work/odp/php/bin/php -n ./wise_push_data.alamon_pushdata.php > wise_push_data.log.`date +\%Y\%m\%d`
注意:crontab执行的命令,并不基于当前用户的环境参数,例如打印$PATH可能只是为‘/usr/bin:/bin’,故很多基于环境参数的命令无法执行(不限于写在crontab中的命令,而是包括crontab执行的命令例如shell脚本里的内容),包括‘#! /usr/bin/env python’这种自动执行脚本的语句。不过,‘~’会被解释为当前用户的主目录(每个用户都拥有自己独立的crontab任务列表),但为了任务的可移植性,建议尽量使用全路径。
正确做法是,在执行命令前执行'cd /home/work/myscript && source /home/work/.bash_profile && ./helloworld.py'或者使用全路径执行'cd /home/work/myscript && /home/work/local/python/bin/python helloworld.py'
查看其他人的定时任务:
sudo conrtab -l -u <userName>
42. core文件的设置
格式:ulimit -a #显示当前core文件的相关设置,例如:开启或关闭core文件的生成
/proc/sys/kernel/core_uses_pid可以控制产生的core文件的文件名中是否添加pid作为扩展,如果添加则文件内容为1,否则为0
/proc/sys/kernel/core_pattern可以设置格式化的core文件保存位置或文件名,比如可以这样设置:/home/coresave/core.%e.%p.%t
注意:添加内容到/proc/sys/中的文件时,使用>,而不要使用vi编辑。例如:‘echo '/home/coresave/core.%e.%p.%t' > /proc/sys/kernel/core_pattern’
如果想永久生效,重启之后也可以生效,则应该将内容添加到/etc/sysctl.conf文件中,然后执行'sysctl -p'命令令其立即重新加载sysctl.conf配置文件。例如:上面的例子应该添加:‘kernel.core_pattern = /home/coresave/core.%e.%p.%t’
调试core文件的命令:(生成可执行文件时使用g++ -g参数来加入调试信息会有益于追查,可以直接显示错误的行和以下中更多的详尽信息)
gdb [可执行文件] [core文件]
dir|directory [代码所在路径] //指定对应的代码,然后就可以查看代码了。
bt|backtrace //查看退出时的堆栈信息
f|frame [n] //n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
info frame|info f //这个命令会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内存地址
info args //打印出当前函数的参数名及其值
info locals //打印出当前函数中所有局部变量及其值
info catch //打印出当前的函数中的异常处理信息
info thread //如果是多线程程序,这样可以看到每个线程的信息。但是至于程序挂在哪个线程里了要用肉眼去分辨,这个应该不难。
thread 1 //进入第一个线程
gdb [被调试文件] -c [进程号] //连接到正在运行的进程
43. 执行脚本的绝对路径
#获取当前执行的脚本文件所在的绝对路径:
sh_dir_tmp=`dirname "$0"`
sh_dir=`cd "$sh_dir_tmp"; pwd`
注:sh_dir为最后不带/的路径,例如“/home/work/dir”
#`basename "$0"`来获取当前执行的脚本文件的文件名
另一种方法:
# 获取当前脚本的绝对路径,使用read -f而不是之后再cd一下来处理符号链接情况
current_script=$(readlink -f "$0")
current_dir=$(dirname "$current_script")
44. 调试shell命令
选项-x 进入跟踪方式,显示所执行的每一条命令;-n 只读取shell脚本,测试shell脚本是否存在语法错误,但不实际执行。另外,调试脚本里的管道命令时,可以在两个管道命令之间插入tee命令来将前一个管道的命令保存到文件中去查看,也可以使用 | tee /dev/stderr | 的方式来将前一个管道的输出同时显示在终端和传递给下一个管道。
“-x”选项使shell在执行脚本的过程中把它实际执行的每一个命令行显示出来,并且在行首显示一个"+"号。 "+"号后面显示的是经过了变量替换之后的命令行的内容,有助于分析实际执行的是什么命令。先执行export PS4='+{$LINENO:${FUNCNAME[0]}} ', 然后再使用“-x”选项来执行脚本,就能在每一条实际执行的命令前面显示其行号以及所属的函数名。
对于使用-x得到的+输出,是无法通过重定向命令保存的,也不可以使用管道+more命令来分页查看;可以使用录制命令来保存输出结果到文件中再自行查看,即:script 文件名,exit结束录制。
shell的执行选项除了可以在启动shell时指定外,亦可在脚本中用set命令来指定。 "set -x"表示启用调试选项,"set +x"表示关闭调试选项,这2个标记之间的内容为被跟踪的代码段。
调试钩子,例如以下的DEBUG函数,可以通过DEBUG <命令>的方式来调用,例如:“DEBUG set -x”;并且在执行时使用export DEBUG=true来打开。
DEBUG()
{
if [ "$DEBUG" = "true" ]; then
$@
fi
}
45. 打印彩色输出
echo -e "\e[1;31m This is red text \e[0m"
每种颜色都有对应的颜色码。比如:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37。
要设置背景色,和上面的前景色对应,以4开头,例如:重置=0,黑色=40,红色=41,绿色=42,...,青色=46,白色=47。
echo -e "\e[1;32m [Pass]全部case的结果一致 \e[0m"
echo -e "\e[1;31m [Fail]有${failNum}个case的结果不一致! \e[0m"
46. 数学运算
整数运算可以使用let或者(( ))和[ ],expr,复杂的则可以使用bc函数,举例:
echo '4*0.56' | bc #2.24
echo "scale=2; 3/8" | bc #0.37,保留2位精度
echo "obase=10; ibase=2; 1100100" | bc #100
echo “sqrt(100)” | bc #10
echo "10^3" | bc #1000
47. BASE64编解码
BASE64编码:
echo -n $text | perl -e 'use MIME::Base64; $_ = encode_base64(<>); print;'
BASE64解码:
echo -n $base64 | perl -e 'use MIME::Base64; $_ = decode_base64(<>); print;'
48. 对程序输出中的特定关键字进行高亮显示
以高亮显示lighttpd.log日志中的”box“关键词为例:
hlkw="box" && tail -f lighttpd.log | sed -e "s/$hlkw/$(tput smso)$hlkw$(tput rmso)/g" #加重
word="box" && tail -f lighttpd.log | | sed -e "s/$word/$(tput setaf 7; tput setab 1; tput bold)"$word"$(tput sgr0)/g" #红底白字
更多控制字符的用法参见博客: http://blog.csdn.net/fdipzone/article/details/9993961
49. 如何追查服务器的问题现场
# 目前都谁在线
w
# 最近有谁登陆过服务器
last -w
# 查看history文件,位于各个用户的主目录下
# export HISTTIMEFORMAT="%F %T `whoami` "
cat $HOME/.bash_history
# 查看正在运行的进程和相关的用户
pstree -a
50. 单行编写for循环语句
for i in {0..9}; do echo $i; done
for (( i=0;i<10;i++ ));do echo $i; done
for i in `seq 0 9`;do echo $i;done
51. 把字符串转为数组和关联数组
#! /bin/sh
#################
# 把字符串转为数组 #
#################
str_arr=' ( "aa", "bb",cc ,dd ) '
#str_arr="()"
# 去除前后的空白符
str_arr=`echo "$str_arr" | sed -e "s/^[ ]*//" -e "s/^\\t*//" -e "s/[ ]$//" -e "s/\\t$//"`
if [[ -z "$str_arr" ]];then
echo "Error, inptut is null."
exit 99
fi
echo "$str_arr" | grep -q -E "\\(.*\\)$"
if [[ $? != 0 ]];then
echo "Error, input form should be: (xx, yy, zz)"
exit 98
fi
# 提取内容,并将其格式化为紧凑形式,例如:("xx", "yy", zz)=>xx,yy,zz
str_arr_content=`echo "$str_arr" | sed -e "s/^.//" -e "s/.$//" -e "s/^[ ]*\"\\{0,1\\}//" -e "s/^\\t*\"\\{0,1\\}//" -e "s/\"\\{0,1\\}[ ]$//" -e "s/\"\\{0,1\\}\\t$//" -e "s/\"\\{0,1\\}[ ]*,[ ]*\"\\{0,1\\}/,/g" -e "s/\"\\{0,1\\}\\t*,\\t*\"\\{0,1\\}/,/g"`
#echo $str_arr_content
OLD_IFS="$IFS"
IFS=","
rst_arr=($str_arr_content)
IFS="$OLD_IFS"
for s in ${rst_arr[@]}
do
echo "$s"
done
#######################
# 把字符串转换为关联数组 #
#######################
str_dict=' { "key1" : "val1" , "key2":"val2",key3:val3 ,key4:val4} '
#str_dict="{}"
# 去除前后的空白符
str_dict=`echo "$str_dict" | sed -e "s/^[ ]*//" -e "s/^\\t*//" -e "s/[ ]$//" -e "s/\\t$//"`
if [[ -z "$str_dict" ]];then
echo "Error, inptut is null."
exit 99
fi
echo "$str_dict" | grep -q -E "^\\{.*\\}$"
if [[ $? != 0 ]];then
echo "Error, input form should be: {xx, yy, zz}"
exit 98
fi
# 提取内容,并将其格式化为紧凑形式,例如:{"key1": "val1", key2: val2}=>key1:val1,key2:val2
str_dict_content=`echo "$str_dict" | sed -e "s/^.//" -e "s/.$//" -e "s/^[ ]*\"\\{0,1\\}//" -e "s/^\\t*\"\\{0,1\\}//" -e "s/\"\\{0,1\\}[ ]$//" -e "s/\"\\{0,1\\}\\t$//" -e "s/\"\\{0,1\\}[ ]*,[ ]*\"\\{0,1\\}/,/g" -e "s/\"\\{0,1\\}\\t*,\\t*\"\\{0,1\\}/,/g" -e "s/\"\\{0,1\\}[ ]*:[ ]*\"\\{0,1\\}/:/g" -e "s/\"\\{0,1\\}\\t*:\\t*\"\\{0,1\\}/:/g"`
#echo $str_arr_content
OLD_IFS="$IFS"
IFS=","
kv_arr=($str_dict_content)
IFS="$OLD_IFS"
# 声明关联数组,需要BashShell版本在4.0以上才支持
declare -A rst_dict
for kv in ${kv_arr[@]}
do
#echo $kv
key=${kv%%:*}
#echo $key
if [[ -z "$key" ]];then
continue
fi
value=${kv##*:}
#echo $value
rst_dict["$key"]="$value"
#echo ${rst_dict["$key"]}
done
for index in ${!rst_dict[*]}
do
echo ${index}"=>"${rst_dict[$index]}
done
val=${rst_dict["notExist"]}
if [[ -z "$val" ]];then
echo "not exist!"
fi
52. atnodes和tonodes等批量操作工具
工具github首页地址:https://github.com/agentzh/sshbatch
工具使用perl编写,只依赖Net::OpenSSH,也就是依赖OpenSSH客户端(ssh命令)的。安装和使用等更多内容参见其github首页。
# 示例:在多台机器上批量执行命令
atnodes 'pwd' myMachine[1-5].com
# 用法说明
atnodes -h
USAGE:
atnodes [OPTIONS] COMMAND... -- HOST_PATTERN... [OPTIONS]
atnodes [OPTIONS] COMMAND HOST_PATTERN... [OPTIONS]
OPTIONS:
-c <num> Set SSH concurrency limit. (default: 20,
when -tty is on, this setting will no use)
-h Print this help.
-l List the hosts and do nothing else.
-L Use the line-mode output format, i.e., prefixing
every output line with the machine name.
(could be controlled by the env SSH_BATCH_LINE_MODE)
-p <port> Port for the remote SSH service.
-ssh <path> Specify an alternate ssh program.
(This overrides the SSH_BATCH_SSH_CMD environment.)
-t <timeout> Specify timeout for net traffic.
-u <user> User account for SSH login.
-v Be verbose.
-w Prompt for password (used for both login and sudo,
could be privided by SSH_BATCH_PASSWORD).
-W Prompt for password (just for sudo),
should not be used with -w.
-P Prompt for passphrase (used for login,
could be privided by SSH_BATCH_PASSPHRASE).
-tty Pseudo-tty.
-q Run SSH in quiet mode
# 示例:在多台机器上批量上传文件
tonodes ./source.txt myMachine[1-5].com:~/
# 用法说明
tonodes -h
USAGE:
tonodes [OPTIONS] FILE... -- HOST_PATTERN... [OPTIONS]
tonodes [OPTIONS] FILE HOST_PATTERN... [OPTIONS]
OPTIONS:
-c <num> Set SSH concurrency limit. (default: 20)
-b <num> bandwidth limit in Kbits/sec.
-g Use glob to process the input files/directories.
-h Print this help.
-l List the hosts and do nothing else.
-L Use the line-mode output format, i.e., prefixing
every output line with the machine name.
(could be controlled by the env SSH_BATCH_LINE_MODE)
-p <port> Port for the remote SSH service.
-r Recurse into directories too.
-rsync Use "rsync" to transfer files.
-archive Enable rsync archive mode
-update Enable rsync update
-compress Enable rsync compress
-t <timeout> Specify timeout for net traffic.
-u <user> User account for SSH login.
-v Be verbose.
-w Prompt for password (used mostly for login and sudo,
could be privided by SSH_BATCH_PASSWORD).
-P Prompt for passphrase (used mostly for login,
could be privided by SSH_BATCH_PASSPHRASE).
53. 批量执行一个文件里命令行
#! /bin/sh
if (( $# < 1 ))
then
echo "Missing Param: Command File, Quit Now."
exit -1
fi
function beforeRun()
{
echo "In before Run: "
echo "$1"
}
function afterRun()
{
echo "In after Run: "
echo "$2"
}
while read line
do
beforeRun "$line"
result=`$line`
afterRun "$line" "$result"
done < "$1"
54. 完成对json的操作
命令jq
安装方法:参见官网教程: Download jq (除了其上列出的命令,还可以直接下载其2进制文件使用)
用法参见:shell jq解析_明天是Spring的博客-CSDN博客_jq shell
55. windows换行CRLF和linux换行LF转换
早年电传打字机有2个概念:一个叫做"回车"(Carriage Return),简称CR,计算机中标记为\r;另一个叫做"换行"(Linefeed),简称LF,计算机标记为\n。
windows系统中,每行结尾是CRLF;linux系统中,每行结尾是LF;mac系统中,每行结尾是CR。
可以使用file命令来查看结果,例如:
file test.sh
test.sh: ASCII text, with CRLF line terminators
file test2.sh: ASCII text
转换的命令:
#将具有windows风格的格式文件转化为unix下的格式文件
dos2unix
sed -i 's/\r//' filename1 filename2 ...
#将具有unix风格的格式文件转化为具有window下的格式文件
unix2dos
56. Java相关问题的排查工具和命令
jps
jps是jdk提供的一个查看当前java进程的小工具, 可以看做是JavaVirtual Machine Process Status Tool的缩写。非常简单实用。
示例:sudo jps -mlvV
显示的信息大致等价于:ps aux | grep java
jstack
Java 中jstack命令可以打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。
一般情况下,通过jstack输出的线程信息主要包括:jvm自身线程、用户线程等。
常用于分析Java应用的性能问题,例如:线程死锁,CPU的负载高等。
命令帮助参见:
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstack.html
Java进程状态的枚举意义参见:
https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html
用法示例:sudo -u<java用户名> jstack <pid>
其中,<java用户名>是指启动java进程所使用的用户,如果就是当前用户启动的Java进程,可以不加该参数;<pid>是指Java进程的pid
实战用法参见:
Java jstack 命令详解_在梅边的专栏-CSDN博客_java jstack
jinfo
jinfo可以用来查看正在运行的java运用程序的扩展参数,甚至支持在运行时动态地更改部分参数。
示例:sudo jinfo <pid>
其中,pid是java进程的pid
jmap
Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本。打印出某个java进程(使用pid)内存内的,所有‘对象’的情况(如:产生那些对象,及其数量)。
示例:sudo jmap -heap <pid>
打印指定pid的java进程的heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况。
示例:sudo -u<java用户名> jmap -histo:live <pid>
打印每个class的实例数目,内存占用,类全名信息。VM的内部类名字开头会加上前缀”*”。如果live子参数加上后,只统计活的对象数量。
示例:sudo -u<java用户名> jmap -dump:live,format=b,file=/tmp/heap.heapprofile <pid>
在目录/tmp下生成heap dump离线文件heap.heapprofile,以方便进一步做分析。例如追查内存泄露的原因。
实战用法参考:
jmap命令详解_zhaozheng7758的专栏-CSDN博客_jmap命令详解
使用jmap和MAT分析JVM堆内存_Jeff 的专栏-CSDN博客_mat分析jmap
jstat
Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。
示例:sudo jstat -gcutil <pid>
查看gc的统计信息,关注点 主要是 已使用/总空间的占比情况。结果详情参见:jstat命令介绍_测试极客-CSDN博客_jstat命令
命令详解:
jstat命令详解_zhaozheng7758的专栏-CSDN博客_jstat
dmesg
示例:dmesg | grep --color -C50 'killer'
如果发现自己的java进程悄无声息的消失了,几乎没有留下任何线索,那么可能是被系统oom kill掉了,使用上述命令进行排查。
因为该行为会被记录进系统日志,也可以使用如下命令查看,还可以看到发生时间:
sudo grep --color -C50 'killer' /var/log/kernlog
具体原理说明:dmesg排查消失的进程_tterminator的专栏-CSDN博客_dmesg oom
57. 进度条函数
function bar()
{
# 没有参数时,默认不使用带颜色的bar
# 有参数时,如果参数为0-7则使用对应颜色的bar;否则使用变色的bar
colorCode="false"
if (( $# > 0 ))
then
# 判断是否是数字
echo "$1" | grep -E "^[0-9][0-9]*$" > /dev/null
if (( $? == 0 ))
then
colorCode=$1
else
colorCode=-1
fi
fi
i=0
bar=""
label=('|' '\\' '-' '/')
while [[ $i -le 100 ]]
do
let index=i%4
if [[ "$colorCode" != "false" ]]
then
if (( "$colorCode" >= 0 && "$colorCode" <= 7 ))
then
echo -en "\e[1;3"$colorCode"m" #使用固定颜色
else
let color=30+i%8 #字体有8种状态30~37
echo -en "\e[1;"$color"m" #sleep一次,字体换一次颜色
fi
fi
printf "[%-100s][%d%%][%c]\r" "$bar" "$i" "${label[$index]}"
bar+='#'
sleep 0.1
let i++
done
echo "" #效果相当于一个换行
if [[ "$colorCode" != "false" ]]
then
echo -e "\e[0m" #回复到原来颜色
fi
}
58. 把批量机器表示形式处理为机器列表
例如:
把l-test[1-3].test.com处理为
l-test1.test.com
l-test2.test.com
l-test3.test.com
代码:
MACHINES_LIST=input.txt
while read line
do
echo "$line" | awk '{if(match($0, /\[(.*)\]/)){sep_ind=index(substr($0, RSTART, RLENGTH), "-");mac_start=substr($0, RSTART+1, sep_ind-2);mac_end=substr($0, RSTART + sep_ind, RLENGTH - sep_ind -1);prefix=substr($0, 1, RSTART - 1);suffix=substr($0, RSTART + RLENGTH);for(i=mac_start+0;i<=mac_end+0;i++){print prefix""i""suffix};} else {print $0}}' >> single-machine-list.txt
done < ${MACHINES_LIST}
59. 向文件追加多行内容(Here Document 特性)
Here Document是Shell脚本特性,用于输入多行文本。它以<<
后跟一个自定义标记(如EOF
)开始,接着是你要插入的文本内容,最后以相同标记结束(不带引号,单独一行),实现向命令或文件一次性输入多行信息。
最后使用 cat xxx >> target.txt 命令来将任意内容(包括Here Document内容)追加到目标文件中。
# 该命令的作用是向~/target.txt文件的末尾追加多行指定内容,包括具体内容、空格、空白行、Tab符等格式化内容,直到遇到EOF标记为止。
cat <<EOF >> ~/target.txt
第2行内容(第1行的空行也算)
第3行内容
。。。
EOF
60. 接受多个文件、目录做参数,并支持*匹配
方式1:
#!/bin/sh
# 函数处理单个文件
process_file() {
local file="$1"
# 做些单文件的处理工作
echo "Processed $file"
}
# 主程序开始
if [ "$#" -eq 0 ]; then
echo "Usage: $0 file1 file2 ..."
echo "Usage: $0 *.lpl"
exit 1
fi
# 遍历所有提供的文件模式,手动匹配并处理实际文件
for pattern in "$@"; do
# 使用ls命令配合通配符列出文件,注意这种方式在特殊字符处理上可能有限制
for file in $(ls -d "$pattern" 2>/dev/null); do
if [ -f "$file" ]; then
process_file "$file"
fi
done
done
echo "All specified patterns have been processed."
方式2:
#!/bin/sh
# 函数处理单个文件
process_file() {
local file="$1"
# 做些单文件的处理工作
echo "Processed $file"
}
# 函数处理单个目录
process_dir() {
local dir="$1"
# 做些单目录的处理工作
echo "Processed $dir"
}
# 确保脚本接收到了参数
if [ $# -lt 1 ]; then
echo "请提供文件名或通配符作为参数"
exit 1
fi
# 函数用于匹配和复制
match_and_deal() {
local pattern="$1"
local full_pattern="$source_dir$pattern"
# 分别处理文件和目录
local files=$(find "$source_dir" -maxdepth 1 -name "$pattern" -type f 2>/dev/null)
local dirs=$(find "$source_dir" -maxdepth 1 -name "$pattern" -type d 2>/dev/null)
# 处理文件
if [ ! -z "$files" ]; then
for file in $files; do
process_file "$file"
echo "$file 已处理"
done
fi
# 处理目录
if [ ! -z "$dirs" ]; then
for dir in $dirs; do
process_file "$dir"
echo "$dir 已处理"
done
fi
# 如果既没有匹配到文件也没有匹配到目录
if [ -z "$files" ] && [ -z "$dirs" ]; then
echo "没有匹配到文件或目录: $pattern"
fi
}
# 遍历所有参数,对每个参数尝试匹配并处理
for pattern in "$@"; do
match_and_deal "$pattern"
done
61. 为文件内每个匹配内容对(不在同一行的先后出现的2个内容)进行关联修改(使用内容队的第1个的内容修改第2个的内容)
local file="$1"
echo "Now is: ${file}"
awk '
BEGIN {inPath=0; inPrint=1}
/"path": "/ {
# 找到了匹配对的开始行,进行标记状态
inPath=1;
# 匹配对的开始行不使用默认打印
inPrint=0;
# 匹配对的开始行不做修改,则直接打印,否则在修改后再打印
print;
# 开始匹配对开始行的处理,!!!可改为其他所需的内容!!!
# 通过字符串操作,提取匹配行中的关键字 "path":"/xxx/xxx/xxx.zip", 中的目录内容(符号/分隔的倒数第2节内容)
gsub(/^[^{]*"path": "/, "", $0);
gsub(/".*/, "");
pathParts=split($0, parts, "/");
newLabel=parts[pathParts-1];
# 结束匹配对开始行的处理
}
inPath && /"label": "/ {
# 开始匹配对结束行的处理,!!!可改为其他所需的内容!!!
# 将匹配对的结束行中的内容 "label":"xxxx", 修改为 "label": ,从而方便后面拼接上文的变量进行打印
gsub(/"label":.*/, "\"label\": \"", $0);
# 结束匹配对结束行的处理
# 打印修改后的匹配对的结束行(拼接了上文变量,也就是匹配对开始行中提取出来的变量,一起进行进行打印)
print $0 newLabel "\",";
# 找到了匹配对的结束行,进行恢复状态
inPath=0;
# 匹配对结束行不使用默认打印
inPrint=0;
}
# 非匹配队行才进行默认打印全行
inPrint {print}
# 该行结束,立刻恢复为非匹配对行的默认打印
!inPrint {inPrint=1}
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
62. 提取文件中的第1列并使用空格拼接(方便作为参数输入)
# 使用cut提取每一行的第一列,自动处理空格和制表符作为分隔符,然后用tr命令将换行符替换为空格
result=$(cut -f1 "./input.txt" | tr '\n' ' ')
# 打印结果,去除最后一个多余的空格
echo "开始批量处理:${result% }"
63. 控制CPU使用率为指定数值
比较简单的是使用 cpulimit 命令来限制某个死循环脚本的占用使用率,不限制该脚本占用CPU比率为100%,限制到指定数值即可。
以下方法为纯shell实现,不需要安装额外的工具。
1. 以下代码命名为cpuRun-1stcore.sh、cpuRun-1stcore.sh,这2个文件可以更改为不同的目标CPU数值,分别控制双核CPU的使用率数值。更多核CPU同理。
#!/bin/bash
# 获取当前脚本的绝对路径,使用read -f而不是之后再cd一下来处理符号链接情况
current_script=$(readlink -f "$0")
current_dir=$(dirname "$current_script")
# 初始设置
TARGET_USAGE=80
INITIAL_LOOP_COUNT=$((100000)) # 初始循环次数稍作降低
SLEEP_TIME=0.1
ADJUSTMENT_STEP=$((100)) # 每次调整的步长,用于模拟平滑调整,扩大10倍
LOOP_COUNT=$INITIAL_LOOP_COUNT
USAGE_HISTORY=() # 引入历史记录数组
while true; do
# 获取当前CPU使用率
cpu_usage=$(<"$current_dir"/cpu_num.txt)
# 根据历史平均使用率与目标使用率的差异调整循环次数
diff=$((cpu_usage - TARGET_USAGE))
if [ "$diff" -gt 0 ]; then
# 向下调整时,减小步长
LOOP_COUNT=$((LOOP_COUNT - ADJUSTMENT_STEP))
elif [ "$diff" -lt 0 ]; then
# 向上调整时,增加步长
LOOP_COUNT=$((LOOP_COUNT + ADJUSTMENT_STEP))
fi
# echo $LOOP_COUNT
# 睡眠一段时间
sleep $SLEEP_TIME
# 限制LOOP_COUNT在合理范围内
LOOP_COUNT=$((LOOP_COUNT < 10000 ? 10000 : LOOP_COUNT))
LOOP_COUNT=$((LOOP_COUNT > 5000000 ? 5000000 : LOOP_COUNT))
# 执行计算循环
for ((i=0; i<$LOOP_COUNT; i++)); do
:
done
done
2. 以下代码命名为calCpuRate.sh,作为第三方独立统计CPU使用率的脚本,不在占用CPU使用率的脚本中处理,以防产生干扰。
#!/bin/bash
# 获取当前脚本的绝对路径,使用read -f而不是之后再cd一下来处理符号链接情况
current_script=$(readlink -f "$0")
current_dir=$(dirname "$current_script")
# 函数:获取CPU使用率(百分比,整数形式)
get_cpu_usage() {
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print int($2+$4)}')
echo $cpu_usage
}
# 循环:每秒获取并写入CPU使用率
while true; do
current_usage=$(get_cpu_usage)
# echo $current_usage
echo $current_usage > "$current_dir"/cpu_num.txt
sleep 1
done
3. 以下代码命名为runCpuRunBoth.sh,是启动脚本。它会在后台运行CPU使用率相关脚本,即使关闭终端也会继续执行。
#! /bin/sh
# 获取当前脚本的绝对路径,使用read -f而不是之后再cd一下来处理符号链接情况
current_script=$(readlink -f "$0")
current_dir=$(dirname "$current_script")
# 执行获取CPU使用率的第三方任务
nohup "$current_dir"/calCpuRate.sh &
# 将第一个脚本绑定到第一个CPU核心(核心编号0)
nohup taskset -c 0 "$current_dir"/cpuRun-1stcore.sh &
# 将第二个脚本绑定到第二个CPU核心(核心编号1)
nohup taskset -c 1 "$current_dir"/cpuRun-2ndcore.sh &
64. 快速生成一个大文件
# of 指定输出文件的名称
# bs 指定文件大小
dd if=/dev/zero of=bigfile bs=1G count=1
65. 测试多个ip的连接速度并按平均速度从快到慢排序
#!/bin/bash
# 检查参数数量
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <number_of_pings> <ips_file>"
exit 1
fi
# 获取参数
n="$1"
ips_file="$2"
# 创建临时文件来存储结果
temp_file=$(mktemp /tmp/tmp.XXXXXX)
# 定义函数来执行ping操作并收集统计信息
ping_and_collect_stats() {
local ip="$1"
# 执行ping操作并收集统计信息
ping -c "$n" "$ip" | tail -n2 | tr '\n' ' ' | cut -d ' ' -f 7,13 | tr '/' ' '
}
# 对文件中的每个IP执行ping操作并收集统计信息
while IFS= read -r ip; do
ping_result=$(ping_and_collect_stats "$ip")
if [ -n "$ping_result" ]; then
echo "$ip $ping_result" >> "$temp_file"
fi
done < "$ips_file"
# 按照平均ping时间排序
sorted_output=$(sort -n -k 2 -k 4 "$temp_file")
# 清理临时文件
rm "$temp_file"
# 输出排序后的结果
echo "$sorted_output"
66. 测试urls列表里的资源地址是否可用
将资源地址保存在 urls.txt 文件中,每行一个url,然后执行以下脚本:
#!/bin/bash
# 获取脚本的绝对路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# 定义输入文件和输出文件的路径
INPUT_FILE="$SCRIPT_DIR/urls.txt"
USABLE_URLS="$SCRIPT_DIR/usable_urls.txt"
UNUSABLE_URLS="$SCRIPT_DIR/unusable_urls.txt"
# 清空输出文件
> "$USABLE_URLS"
> "$UNUSABLE_URLS"
# 读取输入文件中的每一行URL
while IFS= read -r line
do
# 使用curl检查URL是否可用,跟随重定向,忽略SSL证书错误,只输出HTTP状态码
STATUS_CODE=$(curl --silent --head -L --insecure --write-out '%{http_code}' --connect-timeout 10 --max-time 10 --output /dev/null "$line")
# 判断状态码是否为200(表示URL可用)
if [ "$STATUS_CODE" -eq 200 ]; then
# 如果URL可用,则将其追加到可用URL的文件中
echo "$line" | tee -a "$USABLE_URLS"
else
# 如果URL不可用,则将其地址和状态一起追加到不可用URL的文件中
echo "$STATUS_CODE $line" | tee -a "$UNUSABLE_URLS"
fi
done < "$INPUT_FILE"
# 输出完成信息
echo "URL checking complete. Usable URLs are in $USABLE_URLS and unusable URLs are in $UNUSABLE_URLS."
67. 测试urls列表里的资源地址是否可用且返回指定类型内容(改进版)
#!/bin/bash
# 获取脚本的绝对路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# 定义输入文件和输出文件的路径
INPUT_FILE="$SCRIPT_DIR/urls.txt"
USABLE_URLS="$SCRIPT_DIR/usable_urls.txt"
UNUSABLE_URLS="$SCRIPT_DIR/unusable_urls.txt"
# 清空输出文件
> "$USABLE_URLS"
> "$UNUSABLE_URLS"
# 读取输入文件中的每一行URL
while IFS= read -r line
do
# 使用curl检查URL是否可用,跟随重定向,忽略SSL证书错误,只输出HTTP状态码和内容类型,并设置超时时间不超过10s
STATUS_CODE=$(curl --silent --head -L --insecure --write-out '%{http_code} %{content_type}' --connect-timeout 10 --max-time 10 --output /dev/null "$line")
# 判断状态码是否为200(表示URL可用)并且内容类型符合预期(此处为json文件)
if [[ "$STATUS_CODE" =~ ^200.*json.*$ ]]; then
# 如果URL可用,则将其追加到可用URL的文件中
echo "$line" | tee -a "$USABLE_URLS"
else
# 如果URL不可用,则将其地址和状态一起追加到不可用URL的文件中
echo "$STATUS_CODE $line" | tee -a "$UNUSABLE_URLS"
fi
done < "$INPUT_FILE"
# 输出完成信息
echo "URL checking complete. Usable URLs are in $USABLE_URLS and unusable URLs are in $UNUSABLE_URLS."
68. 读取字节设备(如镜像文件)的内容(最简语法实现,嵌入式Linux可用)
一般先要通过 cat /proc/mtd 来获取设备的情况,结果中:
size:这一列指定了设备的总大小,以字节为单位。注意:数字是十六进制表示的!
erasesize:这一列指定了设备上擦除操作的最小单位大小,同样以字节为单位,十六进制表示。
# 一般先通过MB为单位读取其有数据的区间,下例中:20不应大于设备size,128k一般是erasesize大小(可随意,无实质影响)
out_file="/tmp/mtd.dump-$(date +%Y%m%d%H%M%S).txt";for i in $(seq 1 1 20); do echo "${i}m: ";head -c ${i}m /dev/mtd10 | tail -c 128k | hexdump -C | tee -a $out_file; done
# 然后,在细分空间中使用erasesize大小遍历所有数据块,来找到开头的数据块,从而方便确认开头数据块内的镜像签名和magic num
# 16是起始查找的位置,即16MB处
# 17是终止查找的位置,即17MB处
# 多处的128是处理步长,和erasesize大小相同,此处即128k,此处必须精确为erasesize大小,否则无法无缝隙地遍历所有数据。
out_file="/tmp/mtd.dump-$(date +%Y%m%d%H%M%S).txt";for i in $(seq $((16*1024)) 128 $((17*1024))); do echo "${i}k: ";head -c ${i}k /dev/mtd10 | tail -c 128k | hexdump -C | tee -a $out_file; done
69. 提取urls列表的响应内容中的url
#!/bin/bash
# 获取脚本的绝对路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# 定义输入文件和输出文件的路径
INPUT_FILE="$SCRIPT_DIR/urls.txt"
SINGLE_URLS="$SCRIPT_DIR/single_urls.txt"
# 清空输出文件
> "$SINGLE_URLS"
# 读取输入文件中的每一行URL
while IFS= read -r line
do
# Fetch the content and extract the line with http...
curl -s "$line" | grep -o '"http[^"]*"' | sed -e 's/^"//' -e 's/"$//' | tee -a "$SINGLE_URLS"
done < "$INPUT_FILE"
# 输出完成信息
echo "URL parsing complete. Single URLs are in $SINGLE_URLS"
70. 提取Markdown文本中超链接的url
#!/bin/bash
# 获取脚本的绝对路径
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
# 定义输入文件和输出文件的路径
INPUT_FILE="$SCRIPT_DIR/urls.md"
SINGLE_URLS="$SCRIPT_DIR/single_urls.txt"
# 清空输出文件
> "$SINGLE_URLS"
# extract the markdown link with http...
cat "$INPUT_FILE" | grep -o '\(http[^)]*\)' | sed -e 's/^(//' -e 's/)$//' | tee -a "$SINGLE_URLS"
cat "$INPUT_FILE" | grep -o '<http[^>]*>' | sed -e 's/^<//' -e 's/>$//' | tee -a "$SINGLE_URLS"
# 输出完成信息
echo "URL parsing complete. Single URLs are in $SINGLE_URLS"