Linux运维第二阶段(八)shell基础
一、bash特性:
1、GUI(gnome,KDE,Xfce);CLI(sh,csh,ksh,bash,tcsh,zsh)
2、程序、进程(进程是程序的副本,进程是程序的实例,在每一个进程看来,当前主机上只存在内核和当前进程)
3、#type bash(查看当前shell)
#bash(进入子shell,子shell认为当前系统仅内核与他自己)
#pstree(display a tree ofprocesses查看系统进程树)
#exit(退出子shell)
4、命令行编辑快捷键:
ctrl+a光标跳至行首
ctrl+e光标跳至行尾
ctrl+u删除光标到行首的内容
ctrl+K删除光标至行尾的内容
ctrl+l清屏
5、命令历史:
#history(查看历史命令,属内置命令,新使用的命令在内存缓冲区,过段时间才会同步至数据文件中.bash_history)
#history -c(清空历史命令)
#history -d n(仅删除第n条历史命令)
#history -w(保存命令历史至历史文件中)
#echo $HISTSIZE(查看命令保存条数)
6、命令历史的使用技巧:
上下箭头,上一个命令或下一个命令
!n执行历史命令中第n条命令
!-n执行历史命令中倒数第n条命令
!!执行上一条命令
!string执行命令历史中最近一个以指定字符串开头的命令
!$引用上一个命令的最后一个参数
7、命令别名(别名的有效范围仅为当前shell,配置文件~/.bashrc):
#alias CMDALIAS=’COMMAND [option] [arguments]’(设置命令别名)
#unalias CMDALIAS(删除命令别名)
例:#alias cdnet=’cd /etc/sysconfig/network-scripts/’或在~/.bashrc中添加此句
8、命令替换($(COMMAND)、`COMMAND`反引号):
#touch file-`date +%F_%T`或#touch file-$(date +%F_%T)
注:bash中支持的引号,``反引号(命令替换),””双引号(弱引用,可以实现变量替换),’’单引号(强引用,不可以变量替换)
9、文件名通配(#man 7 glob):
*任意长度任意字符
?任意单个字符
[]匹配指定范围内的任意单个字符,如[abc],[a-z],[A-Z],[0-9],[a-zA-Z],[0-9a-zA-Z]
[^]匹配指定范围外的任意单个字符,如[^0-9]非数字
字符集合:[:space:]空白字符,[:punct:]标点符号,[:low:]小写字母,[:upper:]大写字母,[:alpha:]大小写字字母,[:digit:]数字,[:alnum:]大小写字母数字
[[:space:]]外面的中括号表示引用
例:#touch ‘a b’
#ls [[:alpha:]]*[[:space:]]*[[:alpha:]](查找以字母开头字母结尾中间有空白字符)
10、站在用户登录的角度来说,shell的类型:登录式SHELL(正常在某终端登录,#su -[l] USERNAME是完全切换);非登录式SHELL(图形终端中打开的命令行窗口;自动执行的SHELL脚本;#su USERNAME是半切换)
11、bash的配置文件:
全局配置:/etc/profile,/etc/profile.d/*.sh,/etc/bashrc
个人配置:~/.bash_profile,~/.bashrc
profile类的文件:设定环境变量;运行命令或脚本
bashrc类的文件:设定本地变量;定义命令别名
12、登录式SHELL如何读取配置文件:
/etc/profile-->/etc/profile.d/*.sh-->~/.bash_profile-->~/.bashrc-->/etc/bashrc
非登录式SHELL如何读取配置文件:
~/.bashrc-->/etc/bashrc-->/etc/profile.d/*.sh
二、输入输出重定向、管道:
1、 CPU(运算器、控制器);寄存器(CPU暂时存储器);RAM(存储器);输入设备、输出设备(I/O);程序(指令+数据);地址总线(内存寻址)、数据总线(传输数据)、控制总线(控制指令);
2、 系统设定的默认输入设备(键盘)、输出设备(显示器,廉价)
3、 标准输入(stdin,描述符0,<);
标准输出(stdout,描述符1,>,>>);
标准错误输出(stderr,描述符2,2>,2>>);
另:&>(重定向标准输出或错误输出至同一个文件);
>|(强制覆盖输出);
<<(此处文档,Here document);
/dev/null(软件设备,位桶bit bucket,数据黑洞)
举例:
#ls /var > /tmp/var.out (会将显示结果重定向至指定文件)
#ls /varr > /tmp/var1.out (由于/varr目录不存在,则用>不会重定向至指定文件,是不同的数据流)
#ls /varr 2> /tmp/var2.out (/varr目录不存在则会将结果重定向至指定文件,2>仅重定向错误输出)
#ls /var 2> /tmp/var.out (会输出到屏幕,不会重定向)
#ls /varr > /tmp/var3.out 2> /tmp/var3.out (都保存至文件,无论执行正确或错误,也可指定为不同的文件)
#ls /varr &> /tmp/var4.out (同上例)
#cat < /etc/issue (输入重定向)
#tr ‘a-z’ ‘A-Z’ < /etc/issue (将指定文件全部中的小写字符全转为大写字符,不改变源文件,仅显示输出)
举例:
#type set (set为内置命令)
#set -C (禁止把已存在文件覆盖重定向,默认为不开启,+C为关闭此项)
#ls /etc > /tmp/var.out (确认/tmp/var.out存在,若开启上句中的功能,此句无法执行,会报错,提示-bash: /tmp/var.out: cannot overwrite existing file)
#ls /etc/ >| /tmp/var.out (>|表示强制覆盖,就算已设置#set -C,也可覆盖重定向至指定文件)
#cat << EOF
>the first line.
>the second line.
>EOF (<<表示Here document,此例在输完EOF回车后,以上两行会显示到屏幕上)
#cat >> /tmp/file.txt << EOF
>the first line.
>the second line.
>EOF (此例用于在脚本中生成文件,结束符EOF可自定义,常用的EOF、END,此例中会将以上两行写入指定文件/tmp/file.txt)
4、 管道(|):前一个命令的输出,作为后一个命令的输入
举例:
#echo ‘hello,world!’ | tr ‘a-z’ ‘A-Z’
#echo ‘redhat’ | passwd --stdin root
#cat /etc/passwd | sort
#cat -d: -f1 /etc/passwd | sort | tr ‘a-z’ ‘A-Z’
#echo ‘hello,world!’ | tee /tmp/hello.txt (tee:read fromstandard input and write to standard output and files,从标准输入读入数据,一份输出至屏幕一份保存至指定文件)
#wc -l /etc/passwd | cut -d: -f1
#ls /usr/bin | wc -l
#ll /usr/bin | wc -l (与上句比较出差别)
#cut -d: -f7 /etc/passwd | sort -u (-u,unique重复项只显示一次)
#file /var/log/*
#cd /var/log; file `ls /var/log`
#head -6 /etc/inittab | tail -1
#tail -9 /etc/inittab | head -1 | cut -d: -f1,7 | tee /tmp/user.txt
#ls -d /etc/pa* | wc -l (比较有-d与无-d的差别)
三、grep的使用、正则表达式REGEXP:
grep(global researchexpression):
默认grep工作在贪婪模式下;
文本查找的需要;
根据模式(pattern)搜索文本,并将符合模式的行显示出来);模式:文本字符和正则表达式(REGEXP:regular expression)元字符组合而成的匹配条件;
‘’,“”:只要不涉及到变量,单双引号都可用,单引号(强引用),双引号(弱引用);
#fgrep(不支持正则表达式,没有元字符时使用fgrep速度更快);
#grep [options] pattern FILE
-i(--ignore-case,忽略大小写)
--color
-v(显示没有被模式匹配到的行)
-o(只显示被模式匹配到的字符串,与行无关)
-E(--entended REGEXP,或#egrep)
-A #(显示匹配到字符串所在行以及其后的几行)
-B #(显示匹配到字符串所在行以及其前的几行)
-C #(显示匹配到字符串所在行以及其前后的几行)
REGEXP:basic REGEXP;extendedREGEXP(#egrep或#grep -E);
1、 basic REGEXP:
字符匹配:
.(匹配任意单个字符);
[](匹配指定范围内的任意单个字符;
[^](匹配指定范围外的任意单个字符);
[:digit:][:lower:][:upper:][:punct:][:space:][:alpha:][:alnum:](字符集合)
次数匹配:
*(匹配其前面的字符任意次);
.*(任意长度任意字符);
\?(匹配其前面的字符0次或1次);
\{m,n\}(匹配其前面的字符至少m次,最多n次);
位置锚定:
^(锚定行首,此字符后面的任意内容必须出现在行首);
$(锚定行尾,此字符前面的任意内容必须出现在行尾);
^$(空白行)
锚定词:
\<或\b(词首,其后的任意字符必须作为单词的首部出现);
\>或\b(词尾,其前的任意字符必须作为单词的尾部出现);
分组:
\(\) \1,\2,\3,....(向后引用,例如:匹配like和liker,love和lover:#grep ‘\(l..e\).*\1’ test.txt)
举例:
#grep ‘[[:digit:]]$’ /etc/inittab
#grep ‘[[:space:]][[:digit:]]’ /etc/inittab
#grep ‘\
#grep ‘r\b’ /etc/passwd
#grep ‘\ 2、 extended REGEXP: 字符匹配: . [] [^] 次数匹配: * ? +(匹配其前字符至少1次); {m,n} 位置锚定: ^ $ \<(词首); \>(启尾); 分组: () \1,\2,\3,... 或者: | 举例:精确匹配#ifconfig中所有IP地址(不包括广播地址及子网掩码) #ifconfig | egrep -o '\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>){2}\.\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\>' sed(stream editor):行编辑器、全屏编辑器,把每行读到内存空间(模式空间),默认不编辑源文件,仅对模式空间的数据作处理,处理结束将模式空间打印至屏幕; #sed [options] ‘AddressCommand’ file1... options: -n(静默模式,不再显示模式空间的行,不加-n默认是打印模式空间); -i(直接修改源文件); -e(后接脚本或编辑好的语句,如#sed -e SCRIPT -e SCRIPT FILE,可以同时执行多个脚本); -f(后接脚本文件,如#sed -f /PATH/TO/FILE FILE); -r(表示使用扩展正则表达式) Address: start line,end line;(起始行,结束行,例如:1,13) /pattern/(//中间是正则表达式)参照shell基础中正则表达式的用法 /pattern1/,/pattern2/(第一次被模式1匹配到的行开始到第一次被模式2匹配到的行结束,中间的所有行); linenumber(指定行); startline,+N(从startline开始向后N行) Command: d(删除符合条件的行); P(显示符合条件的行); a \string(在指定的行后追加新行,内容为string); i \string(在指定的行前添加新行,内容为string); r FILE(将指定文件的内容添加至符合条件的行处); w FILE(将指定范围内的行另存至指定的文件中); s/pattern/string/修饰符(查找并替换,不加修饰符g默认只替换第一次被模式匹配到的字符串,修饰符(g全局替换,i查找时忽略大小写),s///也可用s###,s@@@等其它符号) 举例: #sed ‘/^\//a # hello linux’ /etc/fstab (在行首是/的行后追加# hello linux) #sed ‘/^\//a # hello linux\n# hello world’ /etc/fstab (在行首是/的行后追加两行) #sed ‘$r /etc/issue’ /etc/fstab (在末行后添加指定文件内容,此例可用做文件合并) #sed ‘1,2r /etc/issue’ /etc/fstab (在第一行和第二行后都追加指定文件的内容) #sed ‘/oot/w /tmp/oot.txt’ /etc/fstab (将查询到的含oot的行另存至指定文件/tmp/oot.txt) #sed ‘s/oot/OOT/g’ /tmp/oot.txt (将查询到含oot的全部替换为大写) #sed ‘s/^\//#/g’ /etc/fstab (将行首的/全部替换为#) #sed ‘s#l..e#&r#g’ test.txt (&r匹配模式里的整个字符串,将文件中like或love均替换为liker或lover) #sed ‘s#\(l..e\)#\1r#g’ test.txt (同上例) #sed ‘s#l\(..e\)#L\1#g’ test.txt (将文件中like或love替换为Like或Love) #sed -r ‘s/^[[:space:]]+//g’ /etc/grub.conf (删除行首的空白字符) #history | sed ‘s#^[[:space:]]##g’ (功能同上例) #sed ‘s@\(id:\)[0-9]\(:initdefault\)@\15\2@g’ /etc/inittab (将行id:3:initdefault中的3替换为5) #sed ‘/^$/d’ /etc/inittab (删除空白行) #sed ‘s/^#//g’ /etc/inittab (删除文件中开头的#) #sed -r ‘s/^#[[:space:]]+//g’ /etc/inittab (删除文件中开头的#,且#后必须有空白字符) #sed -r ‘s@^[[:space:]]+#@@g’ test.txt (删除文件中以空白字符开头后跟#的行) #echo “/etc/rc.d/” | sed -r ‘s@^(/.*/)[^/]+/?@\1@g’ (取出一路径中上一层目录的名称) 扩展:取路径名或基名另一种方法 #FILE=/etc/init.d/php-fpm #echo ${FILE%/*}(得到结果/etc/init.d) #echo ${FILE##*/}(得到结果php-fpm) 以上是学习《马哥运维课程》做的笔记。 一、shell的两种主要语法:Bourne家族(sh/ksh/bash/psh/zsh);C家族(csh/tcsh)。 注:bash和zsh在不同程度上支持csh的语法。 #vi /etc/shells (可查询linux支持的shell) 二、1、#echo -e|-n 输出内容 -e 可支持反斜线\控制的字符转换(\\,\a,\b,\c,\e,\f\,\n,\r,\t,\v,\0mmm,\xhh) -n 取消输出行末的换行符号,内容输出后不换行 例:#echo -e “ab\bc” #echo -e “a\tb\tc\nd\te\t\f\” #echo -e “\e[1;31mabcd \e[0m” (输出内容加颜色) 注:字体颜色(30m-37m分别代表:黑、红、绿、黄、蓝、洋红、青、白);背景颜色(40m-47m). 2、shell脚本的运行方式: 赋予权限直接运行(通过绝对路径或相对路径); 通过bash调用执行(#bash hello.sh) 三、bash的基本功能: 1、#history 选项 -c (清空历史命令 -w历史命令保存文件 (缓存中的历史命令写入文件,默认保存位置:~/.bash_history #vi /etc/profile (可修改文件历史命令保存条数 注:用history命令查看到的是缓存中的,可用#history –w 直接写入文件 历史命令的调用:上下键;!n重复执行第n条历史命令;!!重复执行上一条命令;!字串,重复执行最近一次以该字串开关的命令;!$重复上一条命令的最后一个参数 2、命令与文件的补全(tab键) 3、命令别名:#alias 别名=‘原命令’(unalias取消别名 例:#alias vi=’vim’ (临时生效 命令执行顺序:绝对路径、相对路径;别名;bash内部命令;环境变量PATH定义的路径依次查找。 4、常用快捷键:ctrl+A,ctrl+E,ctrl+C,ctrl+L,ctrl+u,ctrl+K(删除或剪切光标之后的内容),ctrl+Y(粘贴),ctrl+S(暂停屏幕输出),ctrl+Q(恢复屏幕输出),ctrl+D(退出当前终端),ctrl+Z(暂停放入后台),ctrl+R(在历史命令中搜索) 5、设备 设备文件名 文件描述符 类型 键盘 /dev/stdin 0 标准输入 显示器 /dev/stdout 1 标准输出 显示器 /dev/stderr 2 标准错误输出 命令>文件|设备 错误命令2>文件|设备 覆盖方式 命令>>文件|设备 错误命令2>>文件|设备 追加方式 命令>文件 2>&1 命令&>文件 覆盖方式正确输出错误输出都保存 命令>>文件 2>>&1 命令&>>文件 追加方式正确输出错误输出都保存 命令>>文件1 2>>文件2 正确输出追加至文件1,错误输出追加至文件2 #wc 选项 文件 -c 统计字节数byte -w 统计单词数word -l 统计行数line 6、多命令顺序执行: ; 命令1;命令2 (多个命令顺序执行,命令之间没有任何逻辑关系 && 命令1&&命令2 (当命令1正确执行($?=0)命令2才会执行;命令1执行不正确($?!=0)命令2不会执行 || 命令1||命令2 (当命令1执行不正确($?!=0)命令2才会执行;当命令1正确执行($?=0)命令2不会执行 注:一般情况下最好让&&在前||在后,否则会错误执行,例:命令&&命令||命令 7、 #grep 选项 “搜索内容” -A number 列出符合条件的行,并列出后续n行 -B number 列出符合条件的行,并列出前n行 -i ignore忽略大小写 -v invert-match取反 -c 统计找到符合条件的字符串的次数 -n line-number输出行号 --color=auto 搜出的关键字用颜色显示 例:#grep –A 3 “root”/etc/passwd #grep –n “/bin/bash” /etc/passwd #grep –v “/bin/bash” /etc/passwd #netstat –an | grep “ESTABLISHED” | wc –l #rpm –qa | grep httpd 8、通配符: * 匹配0个或任意多个字符,可匹配任何内容 ? 匹配1个任意字符 [] 匹配括号中任意一个字符,例:[abc]中的一个 [-] 匹配括号中范围内的一个字符,例:[a-z]中的一个字符 [^] 匹配不是括号中的一个字符,例:[^0-9]代表不是数字的字符 9、bash中的其它特殊符号 ‘’ 单引号内的所有特殊符号都没有特殊含义,包括$、``反引号 “” 双引号中的特殊符号都没有特殊含义,除$、``反引号、\转义符外 `` 反引号里的内容是系统命令,在bash中会先执行,同$()一样 $() 引用系统命令,与反引号作用一样 \ 在转义符\之后的特殊符号将失去特殊含义,变为普通字符,例:\$,输出$ $ 调用变量的值,例:$name () 一串命令执行时,()内的命令在子shell中执行 {} 一串命令执行时,{}内的命令在当前shell中执行,也可用于变量变形与替换 [] 用于变量的测试 # shell中表示注释 注:()与{}的区别:执行一串命令时()里的命令需重新开一个子shell执行,而{}里的命令是在当前shell下执行;两者都把命令放在括号里,且命令之间用;分号隔开,()内最后一个命令可以不用分号,{}内最后一个命令要加上分号;{}内的第一条命令与左括号之间必须要有一个空格,()内则不用;两者括号里的某个命令的重定向只影响该命令,但括号外的重定向则影响括号里的所有命令。 例: #name=sb #(name=sd;echo $name) #echo $name #{ name=sd;echo $name;} #echo $name 四、bash的变量和运算符 1、变量: 变量名称由字母、数字、下划线组成,不能以数字开头,例:2name; 变量的默认类型是字符串型,如要进行数值运算,则必须指定为数值型; 变量用等号连接,且左右两侧不能有空格; 变量值中若有空格,要用单引号或双引号包括,例:test=”hello world”,注意双引号里有三个特殊符号拥有特殊含义:$、``反引号、\; 在变量的值中,不能有转义符\; 如需增加变量的值,可进行变量值的叠加,两种格式:”$变量名”、${变量名},例:#test=”$test”456、#test=${test}456; 如要把命令的结果作为变量值赋予变量,则要使用``反引号或$(),例:#test=$(date)、#test=`date`; 环境变量名建议大写,便于区分。 2、变量的分类: 用户自定义变量:最常见的,由用户自由定义变量名和变量值; 环境变量:保存系统操作环境的相关数据,可自由定义,如当前登录用户、家目录、命令提示符; 位置参数变量:主要用来向脚本传递参数和数据,变量名不能自定义,变量作用是固定的; 预定义变量:bash中已定义好的变量,变量名不能自定义,变量作用是固定的。 3、 #set (查看系统中所有变量 #env (仅查看环境变量environment #set –u|-x (-u,有此项调用未声明变量时会报错,默认无任何提示;-x,有此项在命令执行之前会把命令先输出一次 #unset 变量名 (变量删除 4、 #export AGE=”18” (声明为环境变量 #env | grep AGE (查询环境变量 #unset AGE (删除AGE变量 PATH变量:系统查找命令的路径,用冒号分隔 注:在命令行中输入了一个命令,没写绝对路径,系统就会到PATH定义的路径中寻找,有则执行。无则提示“Command not fount”;脚本可拷贝至PATH定义的某一路径中,也可通过变量的叠加实现。 例:#cp /root/sh/hello.sh /bin #PATH=”$PATH”:/root/sh 仅临时生效,永久生效写入配置文件/etc/profile #echo $PATH PS1变量:命令提示符设置,默认:[\u@\n \W]\$ #echo $PS1 #PS1=’[\u@\h \W]\$ ‘ LANG语系设置 #echo $LANG (对当前系统生效,由配置文件i18n赋予变量LANG #locale –a | wc-l (可支持的所有语系 #locale (当前系统的语系 /etc/sysconf/i18n (系统默认语系,重启后生效 注:纯字符界面下显示中文:en_US.UTF-8改为zh_CN.UTF-8,并安装zhcon中文插件;图形界面和远程连接登录,需先工具配置正确并设为中文环境zh_CN.UTF-8。 5、位置参数变量 $n n为数字,$0代表命令本身,$1-$9为第一到第九个参数,10以上的参数表示方法为:${10} $* 代表命令行中所有参数,$*把所有的参数看作一个整体 $@ 代表命令行中所有参数,$@把每个参数区分对待 $# 代表命令行中所有参数的个数 6、预定义变量: $? 最后一次执行命令的返回状态,0表示上一个命令正确执行,非0上一个命令执行不正确 $$ 当前进程的PID $! 后台运行的最后一个进程的PID 7、接收键盘输入: #read 选项 变量名 -p 在等待read输入时,输出提示信息 -t秒数 指定等待时间 -n字符数 只接受指定的字符数 -s 隐藏输入的数据,适用于机密信息的输入 注:变量名可以自定义,如不指定,则保存至默认变量REPLY;如果只提供一个变量名,则整个输入行赋予该变量,如有多个变量,则输入行分为若干字,一个接一个的赋予各个变量,而命令行上的最后一个变量取得剩余的所有字。 例:#vi read.sh #!/bin/bash #Author: read –t 30 –p “please input your name: “name echo “Name is $name” read –t 30 –p “please input your age: “ age echo –e “\n” echo “Age is $age” read –t 30 –n 1 –p “please select yourgender[m/f]: “ gender echo –e “\n” echo “Sex is $gender” 8、#declare +/-选项 变量名 - 设定 + 取消 -a array数组 -i integer整数 -x environment环境变量 -p print显示被声明为什么变量 -r 声明为只读变量,一旦为只读,不能修改变量的值,不能删除不能取消只读属性 > 数值运算方式: #aa=11 #bb=22 #cc=$(( $aa+$bb)) #cc=$[ $aa+$bb] #declare–i cc=$aa+$bb #cc=$(expr $aa + $bb) #letcc=$aa+$bb >数组变量类型: #name[0]=sz #name[1]=sd #name[2]=sb #echo ${name}(仅输出第一个下标变量 #echo ${name[*]} (输出数组所有内容 注:调用数组时使用${数组[下标]}的方式。 >环境变量 #declare–x test=123 (同#exporttest=123 >#declare–r test (设为只读,不能修改,不能取消,不能删除 >#decalre–p name(查询变量属性 #declare+x test (取消环境变量属性 9、变量的测试与内容置换 五、环境变量配置文件 1、使配置文件立刻生效: #source 配置文件 #.配置文件 2、登录时生效的环境变量配置文件: /etc/profile、/etc/profile.d/*.sh、~/.bash_profile、~/.bashrc、/etc/bashrc /etc/profile:调用/etc/profile.d/*.sh和~/.bash_profile ~/.bash_profile:在PATH变量后加入:HOME/bin这个目录,脚本可放至~/bin下,可直接执行 ~/.bashrc:定义默认别名 /etc/basrc:定义PS1变量;定义了umask默认权限,non-login过程生效;定义了PATH变量,non-login过程生效调用/etc/profile.d/*.sh。 ~/.bash_logout:注销时生效的环境变量配置文件; ~/.bash_history:历史命令保存文件。 3、/etc/issue:tty1-tty6本地终端欢迎界面,支持的转义符可用#man agetty查询 /etc/issue.net:远程登录欢迎信息,如ssh/telnet。需同时更改配置文件/etc/ssh/sshd_config在#Banner none下加入Banner/etc/issue.net,不支持/etc/issue中的转义符 /etc/motd:用户登录之后显示的欢迎信息,本地远程都可显示,前两个文件/etc/issue、/etc/issue.net是在用户登录之前显示的。 #stty–a (查询所有快捷键 #stty关键字 快捷键 (设置快捷键:#stty intr^p(^p是手工输入的),强制中止改为ctrl+p 注:本文由互联网收集整理(51CTO、360DOC、chinaunix、百度百科、兄弟连免费视频等)。