AIX shell 高级程序设计基础
shell
shell是一个命令解释器,是介于操作系统kernel与用户之间的一个绝缘层不使用shell
资源密集型的任务,尤其在需要考虑效率时(比如,排序,hash等等)
需要处理大任务的数学操作,尤其是浮点运算,精确运算,或者复杂的算术运算(这种情况一般使用C++或FORTRAN来处理)
有跨平台移植需求(一般使用C或Java)
复杂的应用,在必须使用结构化编程的时候(需要变量的类型检查,函数原型,等等)
对于影响系统全局性的关键任务应用。
对于安全有很高要求的任务,比如你需要一个健壮的系统来防止入侵,破解,恶意破坏等等.Vi编辑器使用
vi/vim 中可以使用
:s 命令来替换字符串。
:s/well/good/ 替换当前行第一个 well 为 good
:s/well/good/g 替换当前行所有 well 为 good
:n, s/well/good/替换第n行开始到最后一行中每一行的第一个well为good:n, s/well/good/g 替换第 n 行开始到最后一行中每一行所有 well 为 good
n 为数字,若 n 为 .,表示从当前行开始到最后一行
:%s/well/good/(等同于 :g/well/s//good/) 替换每一行的第一个 well 为 good
:%s/well/good/g(等同于 :g/well/s//good/g) 替换每一行中所有 well 为 good
可以使用 # 作为分隔符,此时中间出现的 / 不会作为分隔符
:s#well/#good/# 替换当前行第一个 well/ 为 good/
:%s#/usr/bin#/bin#g
可以把文件中所有路径/usr/bin换成/bin
剪切 拷贝 粘贴删除一行:dd
删除一个单词/光标之后的单词剩余部分:dw
删除当前字符:x
光标之后的该行部分:d 文本删除dd删除一行d 删除以当前字符开始的一行字符
ndd 删除以当前行开始的n行
dw 删除以当前字符开始的一个字
ndw 删除以当前字符开始的n个字
D 与d$同义
d) 删除到下一句的开始
d} 删除到下一段的开始
d回车 删除2行
ndw 或 ndW 删除光标处开始及其后的 n-1 个字符。
d0 删至行首。
d$ 删至行尾。
ndd 删除当前行及其后 n-1 行。
x 或 X 删除一个字符。
Ctrl+u 删除输入方式下所输入的文本。
^R 恢复u的操作
J 把下一行合并到当前行尾
V 选择一行
^V 按下^V后即可进行矩形的选择了
aw 选择单词
iw 内部单词(无空格)
as 选择句子
is 选择句子(无空格)
ap 选择段落
ip 选择段落(无空格)
D 删除到行尾
x,y 删除与复制包含高亮区
dl 删除当前字符(与x命令功能相同)
d0 删除到某一行的开始位置
d^ 删除到某一行的第一个字符位置(不包括空格或TAB字符)
dw 删除到某个单词的结尾位置
d3w 删除到第三个单词的结尾位置
db 删除到某个单词的开始位置
dW 删除到某个以空格作为分隔符的单词的结尾位置
dB 删除到某个以空格作为分隔符的单词的开始位置
d7B 删除到前面7个以空格作为分隔符的单词的开始位置
d) 删除到某个语句的结尾位置
d4) 删除到第四个语句的结尾位置
d( 删除到某个语句的开始位置
d) 删除到某个段落的结尾位置
d{ 删除到某个段落的开始位置
d7{ 删除到当前段落起始位置之前的第7个段落位置
dd 删除当前行
d/text 删除从文本中出现“text”中所指定字样的位置,
一直向前直到下一个该字样所出现的位置(但不包括该字样)之间的内容
dfc 删除从文本中出现字符“c”的位置,一直向前直到下一个该字符所出现的位置(包括该字符)之间的内容
dtc 删除当前行直到下一个字符“c”所出现位置之间的内容
D 删除到某一行的结尾
d$ 删除到某一行的结尾
5dd 删除从当前行所开始的5行内容
dL 删除直到屏幕上最后一行的内容
dH 删除直到屏幕上第一行的内容
dG 删除直到工作缓存区结尾的内容
d1G 删除直到工作缓存区开始的内容在vi/vim中,跳到文件首尾快捷键:
文件开始:shift + g
文件结束:g gbash script1 :激活脚本
chmod 755 ./script1
./script1
.script1
source script1使用.(dot) 或者source命令在当前shell环境中执行脚本
例如,为了不重起而让环境变量修改立即生效——可以使用source或者dot命令 (例如 #source /etc/profile)#!/bin/bash
脚本将总是在bash中运行,即使用户的默认shell是其它的shell
此时,使用dot在当前的shell中激活shell脚本不再可行了。Shell脚本参数
$1,$2,$3 指向每个参数
$#表示参数的个数
$*表示所有参数的整体如果有很多参数(例如,文件名),则可以用shift切换参数:
Ps
Ps a 显示现行终端机下的所有程序,包括其他用户的程序
Ps u 以用户为主的格式来显示
Ps 显示所有程序,不以终端机来区分- 元字符和通配字符
元字符(metacharacters)指的是在shell中有特殊含义的字符。
例如:< > | ; ! ? * [ ] $ \ ” ’ ` ~ ( ) { }
通配字符(wildcards)是转义字符的子集,用来查找匹配文件名
例如:? * [] [-] [!]
通配一个字符:”?”
通配多个字符:”*”
高级通配符扩展 保留字
/\
\ 转义字符,如\X等价于“X”或‘X’. 即去掉其后所相邻字符的特殊含义
/ 文件名路径分隔符.或用来做除法操作.#
#: 注释,行首以#开头为注释(#!是个例外).
# This line is a comment.“” ‘’
使用双引号只解释变量名 前缀( )、后引符(‘)和转义符(\)。单引号和双引号类似,但单引号不解释变量引用 .
;
命令分隔符,可以用来在一行中来写多个命令.
;;
终止”case”选项.
,
逗号链接了一系列的算术操作,虽然里边所有的内容都被运行了,但只有最后一项被返回.
如:
[root@localhost train]# let “t2 = (a = 9, 15 / 3)”
[root@localhost train]# echo $t2
5:
1 while : 2 do 3 operation-1 4 operation-2 5 ... 6 operation-n 7 done 8 9 # 与下边相同: 10 # while true 11 # do 12 # ... 13 # done
空命令,等价于”NOP”(no op,一个什么也不干的命令).也可以被认为与shell的内建命令(true)作用相同.”:”命令是一个bash的内建命令,它的返回值为0,就是shell返回的true.
1 while : 2 do 3 operation-1 4 operation-2 5 ... 6 operation-n 7 done 8 9 # 与下边相同: 10 # while true 11 # do 12 # ... 13 # done
$
变量替换
()
用在数组初始化,如:
1 Array=(element1 element2 element3)
cat {file1,file2,file3} > combined_file
# 把file1,file2,file3连接在一起,并且重定向到combined_file中.
{}
# cp file22.{txt,backup}
# 拷贝”file22.txt” 到”file22.backup”中{} \;
路径名.一般都在find命令中使用.
例: 查找del.txt并删除,删除前提示确认$ find . –name “del.txt” -ok rm {} \;
例:查找aa.txt 并备份为aa.txt.bak
$ find . –name “aa.txt” -exec cp {} {}.bak \;[ ]
test. test的表达式将在[]中.
[ ] 数组元素
Array[1]=slot_1
echo ${Array[1]}
[ ] 字符范围
在正则表达式中使用,作为字符匹配的一个范围find
find是个使用频率比较高的命令。常常用它在系统特定目录下,查找具有某种特征的文件。
find命令的格式:find [-path……] -options [-print -exec -ok]
path:要查找的目录路径。
~ 表示$HOME目录
. 表示当前目录
/ 表示根目录print:表示将结果输出到标准输出。
exec:对匹配的文件执行该参数所给出的shell命令。
形式为command {} \;,注意{}与\;之间有空格ok:与exec作用相同,
区别在于,在执行命令之前,都会给出提示,让用户确认是否执行
options常用的有下选项:-name:按照名字查找
-perm:安装权限查找
-prune:不再当前指定的目录下查找
-user:文件属主来查找
-group:文件所属组来查找
-nogroup:查找无有效所属组的文件
-nouser:查找无有效属主的文件
-type:按照文件类型查找下面通过一些简单的例子来介绍下find的常规用法:
1、按名字查找
在当前目录及子目录中,查找大写字母开头的txt文件find.−name‘[A−Z]∗.txt′−print 在/etc及其子目录中,查找host开头的文件 find /etc -name ‘host*’ -print
在 HOME目录及其子目录中,查找所有文件 find ~ -name ‘*’ -print
在当前目录及子目录中,查找不是out开头的txt文件
$ find . -name “out*” -prune -o -name “*.txt” -print2、按目录查找
在当前目录除aa之外的子目录内搜索 txt文件find.−path“./aa”−prune−o−name“∗.txt”−print 在当前目录及除aa和bb之外的子目录中查找txt文件 find . ( -path “./aa” -o -path “./bb” ) -prune -o -name “*.txt” -print
在当前目录,不再子目录中,查找txt文件
$ find . ! -name “.” -type d -prune -o -type f -name “*.txt” -print3、按权限查找
在当前目录及子目录中,查找属主具有读写执行,其他具有读执行权限的文件$ find . -perm 755 -print
4、按类型查找
在当前目录及子目录下,查找符号链接文件$ find . -type l -print
5、按属主及属组
查找属主是www的文件
find/−userwww−typef−print 查找属主被删除的文件 find / -nouser -type f -print
查找属组mysql的文件
find/−groupmysql−typef−print 查找用户组被删掉的文件 find / -nogroup -type f -print6、按时间查找
查找2天内被更改过的文件
find.−mtime−2−typef−print 查找2天前被更改过的文件 find . -mtime +2 -type f -print
查找一天内被访问的文件
find.−atime−1−typef−print 查找一天前被访问的文件 find . -atime +1 -type f -print
查找一天内状态被改变的文件
find.−ctime−1−typef−print 查找一天前状态被改变的文件 find . -ctime +1 -type f -print
查找10分钟以前状态被改变的文件
$ find . -cmin +10 -type f -print7、按文件新旧
查找比aa.txt新的文件
find.−newer“aa.txt”−typef−print 查找比aa.txt旧的文件 find . ! -newer “aa.txt” -type f -print
查找比aa.txt新,比bb.txt旧的文件8、按大小查找
查找超过1M的文件
find/−size+1M−typef−print 查找等于6字节的文件 find . -size 6c -print
查找小于32k的文件
find.−size−32k−print9、执行命令 查找del.txt并删除,删除前提示确认 find . -name ‘del.txt’ -ok rm {} \;
查找aa.txt 并备份为aa.txt.bak
$ find . -name ‘aa.txt’ -exec cp {} {}.bak \;<,>
ASCII比较
if [ “ veg1"<" veg2” ]后台执行命令
1、&命令#test.sh &
该命令将脚本放到后台执行,但是标准输出还是会显示到当前终端,影响用户操作,所以最好是将输出重定向到其他文件
#test.sh &>/dev/null
2、通过ctrl+z;bg等命令.
如果一个作业已经在前台执行,可以通过ctrl+z将该作业放到后台并挂起。然后通过jobs命令查看在后台执行的作业并找到对应的作业ID,执行bg %n(n为通过jobs查到的作业ID)唤醒该作业继续执行。
jobs————查看在后台执行的进程
fg %n———-将后台执行进程n调到前台执行,n表示jobnumber(通过jobs查看的进程编号,而非pid)
ctrl+z———-将在前台执行的进程,放到后台并挂起
bg %n———将在后台挂起的进程,继续执行
ctrl+c———-前台进程终止
kill %n———杀掉后台运行的进程,n表示jobnumber(通过jobs查看的进程编号,而非pid)
二、如果我们需要作业在后台执行并不受用户注销退出的影响,可以用下面方式
#nohup sh test.sh &>/dev/null &
nohup命令会忽略SIGHUP信号,从而终端退出时不会影响到后台作业-
.“cd -”将回到之前的工作目录
~
home目录.相当于$HOME变量.
~bozo是bozo的home目录,并且ls ~bozo将列出其中的内容.
~/就是当前用户的home目录,并且ls ~/将列出其中的内容,
如:bash$ echo ~bozo
/home/bozo
bash$ echo ~/
/home/bozo/Ctl-B 光标后退,这应该依赖于bash输入的风格,默认是 emacs风格的.
Ctl-C Break,终止前台工作.
Ctl-D 从当前shell登出(和exit很像)
Ctl-H backspace,删除光标前边的字符tee
tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。我们可利用tee把管道导入的数据存成文件,甚至一次保存数份文件。
: 列出文本文件slayers.story的内容,同时复制3份副本,文件名称分别为ss-copy1、ss-copy2、ss-copy3:$ cat slayers.story |tee ss-copy1 ss-copy2 ss-copy3
命令1的输出,成为命令2的输入
export
用于声明一个环境变量:export variable=value
如果在某一次运行中,手动export一个变量,则只在这次shell的使用中,才能访问这个变量,或者在该shell启动的其他程序中,也是可以访问这个变量的,因为它们是这个shell的子进程。该环境变量只在本进程和其子进程中可以访问。
如果是在系统级的配置文件中,如/etc/profile中export 一个变量,那么这个变量就会在整个系统运行期间都起作用。
如果在用户级~/.bash_profile之类的文件中,则每次启动shell都会去读这个文件,所以每次打开shell也是可以取到这个值的。$:当前shell的PID
PATH:用于搜索可执行程序的路径
PS1:主shell提示符显示用户名,主机名和动态显示当前目录
-bash-3.00# export PS1=”[/u@/h /w]”
[root@MagicLinux ~]cd /etc
[root@MagicLinux /etc]/d 代表日期,格式为weekday month date,例如:”Mon Aug 1”
/H 完整的主机名称。例如:我的机器名称为:fc4.linux,则这个名称就是fc4.linux
/h 仅取主机的第一个名字,如上例,则为fc4,.linux则被省略
/t 显示时间为24小时格式,如:HH:MM:SS
/T 显示时间为12小时格式
/A 显示时间为24小时格式:HH:MM
/u 当前用户的账号名称
/v BASH的版本信息
/w 完整的工作目录名称。家目录会以 ~代替
/W 利用basename取得工作目录名称,所以只会列出最后一个目录
/# 下达的第几个命令
/$ 提示字符,如果是root时,提示符为:# ,普通用户则为:$
/[ 字符”[”
/] 字符”]”
/! 命令行动态统计历史命令次数PS2:第二shell提示符
PWD: 当前工作目录
HOME:用户的主目录
LANG:用户的语言环境Exit状态
echo hello
echo $? # 返回0,因为执行成功
lskdf # 不认识的命令.
echo $? # 返回非0值,因为失败了.cut
下面例子提取第3,第4,第5和第8个字符:$ who | cut -c 3-5,8
croe
croe
croesed
sed 是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
结果一般输出到屏幕,但文件内容并没有改变,除非你使用重定向存储输出。
删除:d命令
*$ sed ‘2d’ example #删除example文件的第二行。
$ sed ‘2,$d’ example #删除example文件的第二行到末尾所有行。
$ sed ‘$d’ example #删除example文件的最后一行。
$ sed ‘/test/’d example #删除example文件所有包含test的行替换:s命令
$ sed ‘s/test/mytest/g’ example
#在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。多点编辑:e命令
$ sed -e ‘1,5d’ -e ‘s/test/check/’ example
#(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。Awk
awk也是一个强大的文本分析工具。
相比之下,sed侧重在编辑,而awk是把文件逐行的读入,以空格为默认分隔符将每行切片为列,再进行分析处理。下例只显示/etc/passwd的账户和账户对应的shell,而账户与shell之间以tab键分割:
cat /etc/passwd |awk -F ‘:’ ‘BEGIN {print “name,shell”} {print 1"," 7} END {print “blue,/bin/nosh”}’
搜索/etc/passwd有root关键字的所有行
搜索支持正则,例如找root开头的:
#awk -F: ‘/^root/’ /etc/passwd