bash shell认知
shell原理认知:
关于shell中的通配符*
shell先展开通配符后再传给命令,例如"ls -ld /usr/include/*"先展开为"ls -ld file-list,"
查看历史:
可以通过history命令来查看命令历史
可一使用!!执行上一条命令
bash启动:
查找全局设置/etc/profile,之后查找用户主目录下的设置,.bash_profile .bash_login .profile。按优先级,前面的文件执行了后面的就不会执行。
命令行提示符:
命令行提示符通过内建变量PS1和PS2定义,PS1是主提示符,PS2是同一条命令换行后显示的,叫从提示符或副提示符,更多详细信息可查看man bash PROMPTING段。通过export命令可修改变量
重定向:
使用>符号重定向会使覆盖原有文件,打开bash选项noclobber则不会
打开noclobber:set -o noclobber
关闭noclobber:set +o noclobber
>如果不指明,默认使用标准输出1>
把标准输出和错误输出指定为同一个:command > outputfile 2>&1
tee命令可以既在标准输出中输出又保存到文件
块语句重定向多个语句的输出一起重定向可以使用{}({ command;command;command;} >output.file)把语句括起来,然后使用重定向
另一种方式是把命令序列放到子shell上执行,用()括起(command;command;) >output.file
脚本中对语句块使用重定向:部分重要代码,注意理解:
while read line
do
count=$((count+1))
echo $(count):$(line)
done <$file >$filename.lined
管道:
让接受参数的命令接收来自管道的数据:rm -i $(find . -name ‘*.out’)
Here Document:
command << delimiter
......
>delimiter
文件描述符:
shell命令行每个命令自动打开3个描述符STDIN 0,STDOUT 1, STDERR 2
一个脚本需要把不同的数据输出到不同的文件:
echo "data to file descriptor 3" >&3
echo "data to file descriptor 4" >&4
echo "data to file descriptor 5" >&5
运行命令./shname 3>outputfile3 4>outputfile 5>outputfile
一个脚本多个命令输入或输出都使用同一个文件,但文件名很长:
exec 4>outfile.name exec 5>&4 echo "data to file descriptor" 1>&5 echo "data to file descriptor" >&4 exec 4>&- exec 5>&-
打开描述符:
exec fd>outputfile 如果文件已存在,则覆盖
exec fd>>outputfile 以追加方式
打开后就可以使用了:command 1>&fd
输入描述符的情况类似
exec fd<inputfile
exec fd2<&fd1
command <&fd2 = command <&fd1
使用<>可以同时读/写文件
使用exec fd&- 关闭描述符
进程:
列出进程:
ps -ef 查看系统所有进程,e为查看所有进程,相当于-A。f为使用完整格式显示每个进程(UID PID C-占用cpu时间百分比STIME-启动时间TTY TIME占用CPU时间 CMD-启动命令)
显示关联指定tty的程序 |
-t |
指定关心的PID列表 |
-p 后可接多个PID |
显示某用户的进程 |
-u |
显示某进程创建的进程 |
-C |
列出进程目录 |
相同的分支用[]括起并前面加上个数。子线程用进程名字表示并放在{}中,前面加上个数。-c选项可使分支不合并 |
command后面加& 在后台执行
jobs显示的信息:Running表示正在运行,Stoping表示已挂起,加号表示fg默认操作对象,数字表示任务编号,fg用法:fg %任务编号。bg命令把挂起的任务放到后台继续运行
放入后台的任务在bash结束时结束,可以使用nohup命令防止这种情况,bash结束时,任务的父进程将是1。nohup make &
杀死进程:
一次性杀死多个进程killall
/proc/文件系统:
虚拟文件系统,只在内存中存在,/proc/目录下的目录为数字的都代表一个进程(该数字就是PID),里面保存了所有进程的信息,所有进程的这些目录结构都是一样的。
进程目录内某些目录
cmdline |
该文件包含启动该进程的整个命令行。它没有经过格式化,及程序与其参数之间没有空格,尾行没有换行。 |
cwd |
该符号链接指向当前的工作目录 |
environ |
该文件包含为这个进程定义的所有环境变量,格式为“变量=值”,没有经过格式化 |
exe |
该符号链接指向该进程所执行的可执行文件 |
fd |
此目录包含该进程当前打开的所有描述符(里面为文件符号列表,每个打开的文件符号由一个符号链接表示,其名称为该文件描述符的编号,并指向该文件描述符打开的文件) |
maps |
打印该文件的内容时,将看到该进程的地址空间中当前映射到文件中的那部分自左到右各列为与该映射相关联的地址空间,与该映射关联的权限,该映射起始位置的偏移量(从文件的开始处算起),保存该映射文件设备的主、从序号(HEX),该文件的inode序号,以及该文件的文件名 |
root |
该符号链接指向进程使用的根目录 |
status |
该文件包含众多信息,包括可执行文件名、当前状态、PID、PPID、实际以及有效的UID和GID、内存使用情况 |
机器上的各种硬件信息:
cpuinfo |
该文件包含用户机器上CPU的信息 |
modules |
该文件包含内核当前使用的模块列表,以及每个模块的使用次数(lsmod报告的信息) |
meminfo |
该文件包含内存使用的信息(free命令只是一种易于阅读的格式显示) |
devices |
可用的设备,包括字符设备和块设备 |
filesystems |
系统支持的文件系统 |
ioports |
查看系统的I/O端口 |
interrupts |
查看中断信息 |
mounts |
查看挂载的文件系统 |
swaps |
查看交换分区使用的情况 |
partitions |
查看系统分区的信息 |
version |
查看内核版本 |
内核源码Documention/filesystems/proc.txt包括了完整的/proc/文件系统介绍,并解释了/proc/文件系统中所有文件的格式和意义
/proc/sys/是/proc特殊的子目录,通过它可以显示当前内核运行的参数,并且可以在系统运行中更改这些参数,而且会立即生效哦。
例如:sudo echo 1 >/proc/sys/net/ipv4/ip_forward
这仅仅当系统运行时有效,当系统重新启动之后会变回默认值,要想启动时就改动这些值,方法是修改配置文件/etc/sysctl.conf,可参考man sysctl.conf(5)
文本操作和字符串处理:
从一个目录中取出最近访问过的5个普通文件,并输出文件名和最后的访问时间:
ls -lut |grep "^-"|head -5 |cut -c 41-
将两个文本文件对应的行连接起来(只是连在一起)
paste -d ‘:‘ file1 file2
三个文本连接起来:
paste -d ‘<‘ file1 file2 |paste -d ‘>‘ - file3
检查当前系统中的各种shell并统计它们被多少个用户使用和按照从多到少排序打印出来:
cat /etc/passwd|cut -d: -f7 |sort|uniq -c|sort -nr
统计一个文本文件中各个单词出现的个数
#!/bin/bash
count(){
if [ $# != 1 ]
then
echo "Need one file parameter to work!"
exit 1;
fi
#删除标点符号和特殊字符
#构建一个很长的管道命令,每一段都单独写一行,增加可读性
tr ‘+-=*.,;:{}()#!?<>"\n\t‘ ‘ ‘ <$1 |\
#把所有大写字母转换为小写字母
tr ‘A-Z‘ ‘a-z‘ |\
#把连续的空格符转换为一个空格符
tr -s ‘ ‘ |\
#把空格符转换为换行符
tr ‘ ‘ ‘\n‘ |\
#把相同的单词放到一起
sort |\
#删除重复的单词,并进行统计
uniq -c |\
#根据重复的次数进行排序
sort -rn
}
echo
echo "This script can count words of a specified file."
#使用空命令冒号构建无限循环
while :
do
read -p "Enter the file path(or quit):"
case "$REPLY" in
[Qq]|[Qq][Uu][Ii][Tt])
echo "Bye."
exit 0
;;
*)
if [ -f "$REPLY" ] &&[ -r "$REPLY" ]&&[ -s "$REPLY" ]
then
count "$REPLY"
else
echo "$REPLY can not be dealed with."
fi
;;
esac
done
exit 0
tr命令提供字符集以方便使用:
alnum |
所有字母和数字 |
alpha |
所有字母 |
blank |
所有水平的空格符 |
cntrl |
控制字符 |
digit |
数字 |
graph |
可打印字符,但不包括空格 |
|
可打印字符,包括空格 |
lower |
小写英文字母 |
upper |
大写英文字母 |
punct |
所有标点符号 |
space |
所有水平和垂直的空格符 |
xdigit |
十六进制的数字 |
语法:tr [OPTION]... ‘[:classname:]‘ ‘SET2‘ |
用相同宽度的空格代替TAB:
使用expand命令。unexpand的相反,但默认只转换行首TAB使用unexpand -a进行全部转换
把输出格式化成一个表格:
(printf "PERMISSIONS LINKS OWNER GROUP SIZE DATE HH:MM FILE-NAME\n";ls -l |sed 1d)|column -t
debug:
bash -n 不真正的执行,只检查语法,也不做替换等操作
-v选项可以让Shell输出脚本中被处理过的每一行代码
-x选项可以让bash运行在trace下,输出每一条执行的语句,并做替换。
部分调试:
在脚本中加入set -option
option可以是-n、-v、-x中任意一个。
用set +option关闭
使用trap命令
3个伪信号:
EXIT 从一个函数中退出时及整个脚本执行完毕时
ERR 当一条命令执行失败返回非零状态时
DEBUG 脚本中的每一条命令执行前
可以捕获ERR信号,追踪执行不成功的命令,$LINENO是Shell的内置变量,代表Shell脚本的当前行号。
有趣的命令或用法:
cal :打印日历
ls 命令的输出被重定向后是一个文件一行的,相当于ls -1这是ls命令内部做了判断,可使用ls -C强制原样输出
expr命令可以对算数表达式和关系表达式进行运算,还可以用来计算一个字符串的长度,如:expr length STRING
basename 命令去除文件名中的路径,basename ./etc/init.d 输出为init.d basename ./etc/init.d .d 输出为 init。 去除了后缀。
cat命令-E选项可以看到脚步文件中各个换行符的位置
本文出自 “重剑无锋” 博客,请务必保留此出处http://qianyang.blog.51cto.com/7130735/1615564
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。