什么是 Shell
大纲
【前言】
1、Shell简介
2、Bash功能介绍
2.1、记录命令历史
2.2、命令和文件名补全
2.3、别名
2.4、管道符/重定向
2.5、快捷键
3、Bash使用技巧
3.1、重定向技巧
3.2、命令序列号使用技巧
3.3、作业控制技巧
3.4、花括号{}的使用技巧
前言:
Shell 脚本是日常Linux 系统管理工作中必不可少的。如果不会写shell脚本,你就不算是一个合格的管理员。目前很多单位在招聘Linux系统管理员时,Shell脚本的编写是必考的项目,总之只要Shell脚本写的好,Linux求职之路就轻松得多。
1、Shell 简介
- Shell是系统跟计算机硬件交互时使用的中间介质,它只是系统的一个工具。实际上,一个完整的计算机体系结构包括:硬件与软件,而软件又分为系统软件与应用软件,负责对硬件进行管理与操作的是系统软件的内核部分,用户是无法直接与硬件或内核打交道的,用户通过程序或部分系统软件发出指令(可能是通过浏览器发送一封邮件),这些指令会被翻译并传给内核,内核在得知用户的需求后调度硬件资源来完成操作(比如,使用网卡发送数据包)
- 在Linux环境下,我们可以通过Shell与内核进行交流,并最终实现我们想要使用计算机资源的目的。但是Linux的开放性特点,使得再Linux下对Shell的选择也有很多,CentOS 6.4系统中可以使用的Shell有/bin/sh、/bin/bash、/bin/tcsh、/bin/csh这几种,/etc/shells文件说明了当前系统有哪些可用的Shell。当然不同的Sehll有不同的特点以及操作方式。CentOS 默认以Bash。
2、Bash功能介绍
2.1、记录命令历史
Bash拥有自动记录命令历史的功能,用户所执行的命令会在注销时自动记录到自己的家目录下的 .bash_history[1]隐藏文件中,查看这些历史纪录的方法有很多,可以直接打开文件来查看,通过键盘的上下键来上翻动或下翻动历史纪录,还可以通过 history命令查看历史记录。所有的命令历史都有记录编号。命令历史能够记录的信息数量由HISTSIZE变量所决定的,Centos 6.4默认通过/etc/profile文件定义了HISTSIZE=1000,这里的1000也就是最多可以记录最近所使用的1000条命令,如果当有1001条命令时,第一条命令会被覆盖,执行命令 history-c 命令可以清空所有的历史命令
记录命令历史除了可以查看历史纪录,还可以在需要时直接调用历史记录再次执行命令。
- 上下键翻阅历史命令,找到合适的命令后直接回车键就可以执行。
- 输入 ! xxx 调用命令历史(xxx为关键字),如 ! ls将调用最后一次执行的以 ls开头的命令
[[email protected] ~]# !ls ls anaconda-ks.cfg install.log install.log.syslog
- 上面是调用关键字,还可以通过 !n 来准确定位历史纪录,如 !65
[[email protected] ~]# !65 ls -l total 20 -rw-------. 1 root root 1101 Jul 13 07:03 anaconda-ks.cfg -rw-r--r--. 1 root root 8838 Jul 13 07:03 install.log -rw-r--r--. 1 root root 3091 Jul 13 07:02 install.log.syslog
- 还有一个功能,通过Ctrl+r快捷键打开搜索功能,接着输入关键字,就可以在命令历史中搜索相关命令,按回车键完成执行操作。如果没有搜索到适合的命令,按Esc键推出搜索。
2.2、别名和文件名补全
- 按tab键可以帮助我们补全一个指令、一个路径或者一个文件名。连续按两次tab键,系统会把所有的命令或者文件名都列出来
2.3、别名
- 在Centos6.4 系统中,可以使用 ll命令来显示文件的详细信息,其实系统中并没有 ll 命令,它只是被提前定义好的一个别名。别名的好处就是可以把本来很长的指令简化缩写,为常用且复杂的命令及选项创建别名可以大大提高日常工作效率。
[[email protected] ~]# alias <==查看系统当前所有的别名 alias cp=‘cp -i‘ <==cp复制命令事实是 cp -i alias l.=‘ls -d .* --color=auto‘ alias ll=‘ls -l --color=auto‘ alias ls=‘ls --color=auto‘ alias mv=‘mv -i‘ alias rm=‘rm -i‘ alias which=‘alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde‘ [[email protected] ~]# alias h5=‘head -5‘ <==定义新的别名 [[email protected] ~]# unalias h5 <==取消定义别名
2.4、管道符/重定向
- 管道符:“|”他将前一个指令的输出作为后一个指令的输入
[[email protected] ~]# echo "xiaoling" | passwd --stdin vforbox <==设置vforbox密码为xiaoling Changing password for user vforbox. passwd: all authentication tokens updated successfully. [[email protected] ~]# rpm -qa | grep gcc <==查询计算机中是否安装了gcc软件 libgcc-4.4.7-11.el6.i686 gcc-4.4.7-11.el6.i686
- 重定向:输出重定向可以使用 >或>>符号,使用>可以将输出导入至文件,如果文件不存在,则创建该文件,如果文件已经存在,则会覆盖该文件的内容;而使用>>可以将输出追加至文件;对应错误信息的重定向需要使用2>或2>>。输入重定向可以使用<符号,它可以帮助我们从文件中提取输入信息。
[[email protected] ~]# ls <==查看当前文件列表 anaconda-ks.cfg install.log install.log.syslog list.txt [[email protected] ~]# ls > list.txt <==将输出保持至list.txt,屏幕无输出显示 [[email protected] ~]# hostname >> list.txt <==将主机名追加至list.txt文件末尾 [[email protected] ~]# mail -s test [email protected] < list.txt <==发送邮件,邮件内容来自文件 [[email protected] ~]# ls -l abc install.log <==查看文件详细信息,abc并不存在 ls: cannot access abc: No such file or directory -rw-r--r--. 1 root root 8838 Jul 13 07:03 install.log [[email protected] ~]# ls -l abc install.log 2> error.txt <==仅将错误重定向,不影响正常输出 -rw-r--r--. 1 root root 8838 Jul 13 07:03 install.log [[email protected] ~]# ls -l abc install .log > all.txt 2>&1 <==将正确输出和错误输出均导入all.txt [[email protected] ~]# ls abc install.log >> all.txt 2>&1 <==将正确输出和错误输出均追加至all.txt
2.5、快捷键
- Bash提供了大量的快捷键为用户所使用,熟练掌握这些快捷键可以提高工作效率
快捷键 | 功能描述 | 快捷键 | 功能描述 |
Ctrl+a | 光标移至行首 | Ctrl+k | 删除光标至行尾的字符 |
Ctrl+e | 光标移动至行尾 | Ctrl+c | 终止进程 |
Ctrl+f | 光标右移一格字符 | Ctrl+z | 挂起进程(jobs命令查看挂起进程) |
Ctrl+b | 光标左移一个字符 | Ctrl+w | 删除光标钱的一个单词 |
Ctrl+l | 清屏,等同于clear命令 | Alt+d | 删除光标后一个单词 |
Ctrl+u | 删除光标至行首的字符 | Tab | 自动补全 |
3、Bash使用技巧
- 3.1、重定向技巧
- 编写一个脚本实现自动修改系统账号的密码,那么默认当前密码修改成功后系统会出现 successfully 提示信息,如果需要修改20个用户账户密码,像这样的案例,大量的成功提示信息并不是我们关注的重点,管理员更多的是关心错误提示。所以这时可以考虑将标准正确输出屏蔽,Linux中提供了一个特殊设备/dev/null,它很向太阳黑洞,任何东西往里面写入将永远消失。对于大量无意义的输出信息,可以通过重定向导入/dev/null设备
[[email protected] ~]# echo "admin" | passwd --stdin root > /dev/null <==设置root的密码为admin输出的信息导入至/dev/null,无屏幕显示
- 标准输出与错误输出分离重定向,很多时候自动运行的脚本编写完成后,是在深夜服务器负载最低时以无人值守方式运行的,那么当管理员去检查脚本运行情况时,会希望看到哪些命令执行成功了,哪些出现了问题,并且为了方便管理,需要将正确输出和错误输出分别保存在两个不同的记录文件中,那么分离重定向就尤为重要了
[[email protected] ~]# id vforbox >> user 2>> error <==检查系统是否存在vforbox用户,如果存在则将记录信息至user文件,否则记录error
3.2、命令序列使用技巧
- 在Linux中,我们可以使用控制字符[;、&&、||、&]
[[email protected] ~]# sleep 100 & <==后台运行命令,不影响当前Shell的使用 [[email protected] ~]# ls /tmp ; ls /root ; ls /home <==所有的命令按顺序执行(不管前面是否成功,后面的命令一定正常执行) [[email protected] ~]# ls all.txt && cat all.txt <==如果某个文件存在,则显示该文件内容,否则报错(仅当ls执行成功才会执行ca) [[email protected] ~]# gedit || vim <==如果有gedit编辑器,则打开该程序,否则打开vim编辑器 [[email protected] ~]# id vforbox &>/dev/null && echo "Hi,tom" || echo "No such user" <==通过&>重定向符将id命令的的所有输出屏蔽,然后使用&&与||来判断id命令是否执行成功,成功就显示问候语,否则显示没有该用户
3.3、作业控制技巧
- 当运行一个进程时,你可以使它暂停(按Ctrl+z键),然后使用fg命令恢复它,或是利用bg命令使它到后台运行,你也可以使它终止,(按Ctrl+c)
[[email protected] ~]# sleep 100 & <==通过“&”符号放入后台运行 [1] 4694 [[email protected] ~]# jobs <==可以看到被暂停或被在后台运行的任务 [1]+ Running sleep 100 & [[email protected] ~]# sleep 200 <==休眠200秒然后使用ctrl+z暂停 ^Z [2]+ Stopped sleep 200 [[email protected] ~]# jobs <==可以看到被暂停或被在后台运行的任务 [1]- Running sleep 100 & [2]+ Stopped sleep 200 [[email protected] ~]# fg 1 <==恢复编号 1 调回前台
- 如果关掉后台的正在运行的任务呢?
- 1)如果没有退出当前Shell,那么应该先使用命令“fg+编号”把任务调到前台,然后按Ctrl+c结束
[[email protected] ~]# fg 1 <==恢复编号 1 调回前台 vmstat 1 > /tmp/1.log ^C
- 2)另一种情况就是,关闭当前Shell,再次打开另一个shell时,使用jobs命令并不会显示后台运行或者被暂停的任务,如果想要关闭这些任务,则必须知道它们的pid
[[email protected] ~]# vmstat 1 > /tmp/1.log & <==使用“&”把任务放到后台运行时会显示pid [1] 1184 [[email protected] ~]# ps aux |grep vmstat <==查看vmstat的进程pid root 1184 0.0 0.1 2016 560 pts/0 S 00:15 0:00 vmstat 1 root 1186 0.0 0.1 4356 728 pts/0 S+ 00:15 0:00 grep vmstat [[email protected] ~]# kill 1184 <==杀死vmstat进程
- 如果遇到 kill结束不了的进程,可以在后面加上一个选项 “-9”,即kill -9 pid
3.4、花括号{}的使用技巧
- 通过括号扩展可以生存命令行或脚本所需要的字串,括号中可以包含连续的序列号或使用逗号分隔的多个项目,连续的序列包括一个起点与一个终点,并使用 ... 分割
[[email protected] ~]# echo {a,b,c,d,e} <==输出 a b c d e a b c d e [[email protected] ~]# echo user{2,5,8,10} <==输出 user2 user5 user8 user10 user2 user5 user8 user10 [[email protected] ~]# echo {0..5} <==输出 0 1 2 3 4 5 0 1 2 3 4 5 [[email protected] ~]# echo {0..10..2} <==输出偶数 0 2 4 6 8 10 0 2 4 6 8 10 [[email protected] ~]# echo x{2..-1} <==输出 x2 x1 x0 x-1 x2 x1 x0 x-1 [[email protected] ~]# touch /tmp/{a1,a2,a3} <==创建 a1 a2 a3 等文件 [[email protected] ~]# ls -l /tmp/a{1,2,3} <==查看a1 a2 a3 属性 -rw-r--r--. 1 root root 0 Jul 20 02:41 /tmp/a1 -rw-r--r--. 1 root root 0 Jul 20 02:41 /tmp/a2 -rw-r--r--. 1 root root 0 Jul 20 02:41 /tmp/a3 [[email protected] ~]# chmod 777 /tmp/a{1,2} <==给予 a1 a2 满权限 [[email protected] ~]# ls -l /tmp/a{1,2,3} <==查看 a1 a2 a3 熟悉 -rwxrwxrwx. 1 root root 0 Jul 20 02:41 /tmp/a1 -rwxrwxrwx. 1 root root 0 Jul 20 02:41 /tmp/a2 -rw-r--r--. 1 root root 0 Jul 20 02:41 /tmp/a3