shell 编程规范
一, 前言
? 本文将对 shell 的编程规范与变量进行讲解并且进行实例验证, 适合初学者学习 shell 基础. 在学习过程中我们需要自己动手, 实际操作几次, 边做边体会其含义, 然后学会自我总结归纳, 逐步提升自己的能力. 相信自己你一定可以!
首先我们介绍一下强语言与弱语言类型的简单解释 (目前不太理解没关系):
强语言类型 -- 需要声明变量类型
弱语言类型 -- 无需声明变量类型
html 标记语言 标签 < head></head>
而 shell 脚本编程, 属于典型的弱语言类型, 其中的变量直接定义, 无需声明, 并且 shell 语言没有面向对象思想. 只需要将要执行的命令按顺序保存到一个文本文件, 给该文件可执行权限, 即可运行, 当慢慢深入学习 shell 编程, 可以结合各种 Shell 控制语句以完成更复杂的操作, 结合 shell 脚本编程, 可以将各种服务等大量操作通过一个脚本直接执行, 提高工作效率.
当然, 如果想要学好 shell, 一定需要对 shell 命令比较熟悉, 尤其是常用的一些命令以及一些重要的命令如: grep,egrep,sed,awk 等.
二, shell 的概念
2.1 什么是 shell?
? shell-- 在计算机科学中, Shell 俗称壳 (用来区别于核), 是指 "为使用者提供操作界面" 的软件 (命令解析器). 它类似于 DOS 下的 command.com 和后来的 cmd.exe. 它接收用户命令, 然后调用相应的应用程序.
2.2shell 的应用场景
重复性操作
批量事务处理
自动化运维
服务运行状态监控
定时任务执行
2.3shell 的作用 -- 命令解释器
介于系统内核与用户之间, 负责解释命令行, 一行执行多个不相关的命令使用 ";" 分隔开来执行
三, shell 编程规范
? Linux 系统中的 shell 脚本是一个特殊的应用程序, 其遵循标准的脚本结构, 而且能够输出友好的提示信息, 更加容易读懂. 对应代码较多, 结构复杂的脚本, 应当添加必要的注释文字. 实例如下:
- [[email protected] shell]# cat demo.sh
- #!/bin/bash // 特殊的脚本声明, 表示此行以后的语句通过 / bin/bash 程序解释
- #this is a demo shell script // 除了上方的 #号键其余的# 号键都表示改行是注释信息
- cd /boot
- echo "当前位于:"
- pwd
- echo "其中以 vml 开头的文件包括:"
- ls -lh vml*
? 那么该程序如何执行呢? 首先我们可以直接使用 source 或者 sh 命令直接执行 (注意差别!!!), 否则需要添加其执行权限, 然后执行.
[[email protected] shell]# ls -l
总用量 16
-rw-r--r--. 1 root root 134 11 月 25 19:59 demo.sh // 没有可执行权限
-rwxr-xr-x. 1 root root 274 11 月 25 18:58 state.sh
-rwxr-xr-x. 1 root root 208 11 月 25 19:17 sujiaju.sh
-rwxr-xr-x. 1 root root 345 11 月 25 19:11 welcome.sh
[[email protected] shell]# source demo.sh
当前位于:
/boot
其中以 vml 开头的文件包括:
-rwxr-xr-x. 1 root root 5.7M 11 月 14 11:41 vmlinuz-0-rescue-a33ccb7775134b0e83e04555d56fedb7
-rwxr-xr-x. 1 root root 5.7M 8 月 23 2017 vmlinuz-3.10.0-693.el7.x86_64
- [[email protected] boot]# cd -
- /root/shell
- [[email protected] shell]# sh demo.sh
当前位于:
/boot
其中以 vml 开头的文件包括:
-rwxr-xr-x. 1 root root 5.7M 11 月 14 11:41 vmlinuz-0-rescue-a33ccb7775134b0e83e04555d56fedb7
-rwxr-xr-x. 1 root root 5.7M 8 月 23 2017 vmlinuz-3.10.0-693.el7.x86_64
[[email protected] shell]#
? 经过实践操作, 可以作以下小结: 没有执行权限的 shell 脚本文件, 可以通过 source 或者 sh 命令执行, 但是 source 命令执行之后有路径切换的操作会切换到该路径下, 而 sh 命令不会, 而对文件直接执行是没有足够权限的, 需要更改权限才可执行.
四, 管道与重定向
? shell 的大部分操作过程都位于后台, 不需要用户干预, 因此学会提取, 过滤执行信息非常重要, 下面介绍 shell 环境中的两个 I/O 操作: 管道, 重定向.
4.1 管道操作
? 前面的结果作为后面命令的输入或者是处理对象, 同一行命令中可以使用多个管道符号.
? 看下面一实例:
- [[email protected] ~]# grep -v "/sbin/nologin$" /etc/passwd // 将系统中允许登录的用户检索出来
- root:x:0:0:root:/root:/bin/bash
- sync:x:5:0:sync:/sbin:/bin/sync
- shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
- halt:x:7:0:halt:/sbin:/sbin/halt
- lokott:x:1000:1000:lokott:/home/lokott:/bin/bash
- [[email protected] ~]# tail /etc/passwd | grep "/sbin/nologin$" | wc -l // 统计文件 passwd 中最后 10 行的不 9 允许登录的用户总数
4.2 重定向
? 用户通过操作系统处理信息的过程中, 有以下几类交互设备文件
标准输入: 键盘, 文件编号为 0
标准输出: 显示器, 文件编号为 1
标准错误: 显示器, 文件编号为 2
在实际 Linux 系统维护中, 可以改变输入, 输出内容的方向, 而不是使用默认的标准输入, 输出设备 (键盘和显示器), 这种操作称为 "重定向".
1) 重定向输入
重定向输入指的是将命令中接收输入的途径由默认的键盘改为指定的文件, 而不是等待键盘输入. 重定向输入使用 "<" 操作符.
如我们使用免交互给某个用户设置登录密码的操作实例:
[[email protected] shell]# echo "111111" |passwd --stdin zhangsan // 一般方法
更改用户 zhangsan 的密码 .
passwd: 所有的身份验证令牌已经成功更新.
- [[email protected] shell]# VIM pass.txt
- [[email protected] shell]# cat pass.txt
- 123456
- [[email protected] shell]# passwd --stdin zhangsan <pass.txt // 使用重定向输入会失败
更改用户 zhangsan 的密码 .
passwd: 鉴定令牌操作错误
根据以上操作, 我们发现会失败, 这并不是我们命令写错了, 而是我们 Linux 系统中的 SELinux 在作怪:
- [[email protected] shell]# tail /var/log/messages // 查看系统日志文件
- Nov 26 14:10:09 localhost python: SELinux is preventing /usr/bin/passwd from ioctl access on the file /root/shell/pass.txt.#012#012***** Plugin catchall (100. confidence) suggests **************************#012#012If you believe that passwd should be allowed ioctl access on the pass.txt file by default.#012Then you should report this as a bug.#012You can generate a local policy module to allow this access.#012Do#012allow this access for now by executing:#012# ausearch -c 'passwd' --raw | audit2allow -M my-passwd#012# semodule -i my-passwd.pp#012
然后查看 tail /var/log/audit/audit.log 内容就会发现一个修改密码 failed 报告信息. 因此我们需要关闭 SELinux , 再执行.
错误信息如下:
- type=USER_CHAUTHTOK msg=audit(1574750006.593:666): pid=53587 uid=0 auid=0 ses=11 subj=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 msg='op=PAM:chauthtok grantors=? acct="zhangsan"exe="/usr/bin/passwd"hostname=localhost.localdomain addr=? terminal=pts/2 res=failed'
- type=USER_CHAUTHTOK msg=audit(1574750008.850:667): pid=53587 uid=0 auid=0 ses=11 subj=unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023 msg='op=change password id=1001 exe="/usr/bin/passwd"hostname=localhost.localdomain addr=? terminal=pts/2 res=failed'
关闭之后执行结果:
- [[email protected] shell]# setenforce 0
- [[email protected] shell]# passwd --stdin zhangsan < pass.txt
更改用户 zhangsan 的密码 .
passwd: 所有的身份验证令牌已经成功更新.
(2) 重定向输出
">"-- 表示覆盖
">>"-- 表示追加
实例:
- [[email protected] shell]# uname -p> kernel.txt
- [[email protected] shell]# cat kernel.txt
- x86_64
- [[email protected] shell]# uname -p>> kernel.txt
- [[email protected] shell]# cat kernel.txt
- x86_64
- x86_64
- [[email protected] shell]# uname -p> kernel.txt
- [[email protected] shell]# cat kernel.txt
- x86_64
(3) 错误重定向
将出错的信息存放到指定文件, 而不是直接显示到屏幕上. 错误重定向使用 "2>" 操作符.
实例:
- [[email protected] shell]# tar jcf /nonedir/ex.bz2 /etc/ 2> error.log
- [[email protected] shell]# cat error.log
tar: 从成员名中删除开头的 "/"
tar (child): /nonedir/ex.bz2: 无法 open: 没有那个文件或目录
tar (child): Error is not recoverable: exiting now
重定向与管道操作是 shell 环境中十分常用的功能, 需要熟练掌握.
来源: http://www.bubuko.com/infodetail-3305262.html