shell中的循环语法
Posted 尹正杰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell中的循环语法相关的知识,希望对你有一定的参考价值。
SHELL脚本编程配置环境
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.bash如何展开命令行
1>.bash的优先级
把命令行分成单个命令词
展开别名
展开大括号的声明({})
展开波浪符声明(~)
命令替换$() 和 ``)
再次把命令行分成命令词
展开文件通配(*、?、[abc]等等)
准备I/0重导向(<、>)
运行命令
2>.反斜线(\\)会使随后的字符按原意解释
[root@node101.yinzhengjie.org.cn ~]# echo Your cost:\\$15.00 Your cost:$15.00 [root@node101.yinzhengjie.org.cn ~]#
3>.加引号来防止扩展
单引号(\'\')防止所有扩展 双引号("")也可防止扩展,但是以下情况例外: $(美元符号):
变量扩展 ` `(反引号):
命令替换 \\(反斜线):
禁止单个字符扩展 !(叹号):
历史命令替换
二.bash的配置文件
按生效范围划分,存在两类: 全局配置: /etc/profile /etc/profile.d/*.sh /etc/bashrc 个人配置: ~/.bash_profile ~/.bashrc
三.shell登录两种方式
交互式登录: (1)直接通过终端输入账号密码登录 (2)使用"su -l UserName"切换的用户 执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc 非交互式登录: (1)使用"su UserName"切换的用户 (2)图形界面下打开的终端 (3)执行脚本 (4)任何其它的bash实例 执行顺序: /etc/profile.d/*.sh --> /etc/bashrc -->~/.bashrc
四.Profile类和Bashrc类
按功能划分,存在两类: 即profile类和bashrc类 profile类:为交互式登录的shell提供配置 全局: /etc/profile, /etc/profile.d/*.sh 个人: ~/.bash_profile 作用: (1)用于定义环境变量 (2)运行命令或脚本 bashrc类:为非交互式和交互式登录的shell提供配置 全局: /etc/bashrc 个人: ~/.bashrc 作用: (1)定义命令别名和函数 (2)定义本地变量 修改profile和bashrc文件后需生效 两种方法: (1)重新启动shell进程 (2)使用"."或"source" 例: [root@node101.yinzhengjie.org.cn ~]# . ~/.bashrc [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# source ~/.bashrc
五.Bash退出任务
保存在~/.bash_logout文件中(用户)
在退出登录shell时运行
用于"创建自动备份"或者"清除临时文件"。
六.set 命令
1>."$-"变量
h:
hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭 i:
interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的。 m:
monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。 B:
braceexpand,大括号扩展 H:
history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令
[root@node101.yinzhengjie.org.cn ~]# echo $- himBH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# hash hits command 1 /usr/bin/ls [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# set +h [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- imBH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# hash -bash: hash: hashing disabled [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# set -h [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- himBH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# hash hits command 1 /usr/bin/ls [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# echo $- himBH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo {a..z} #支持大括号扩展功能 a b c d e f g h i j k l m n o p q r s t u v w x y z [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# set +B #禁用大括号功能 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- himH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo {a..z} #发现禁用大括号功能后,只能原样输出啦~ {a..z} [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# history | tail 1233 echo {a..z} 1234 set +B 1235 echo $- 1236 echo {a..z} 1237 history 1238 echo $- 1239 set -B 1240 echo $- 1241 history | tail -5 1242 history | tail [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# !-7 #可以正常使用histrory相关命令 echo {a..z} a b c d e f g h i j k l m n o p q r s t u v w x y z [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- himBH [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# set +H #禁用history [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- himB [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# history | tail 1240 echo $- 1241 history | tail -5 1242 history | tail 1243 echo {a..z} 1244 echo $- 1245 set -H 1246 echo $- 1247 set +H 1248 echo $- 1249 history | tail [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# !-2 #发现history相关语法命令不可用啦~ -bash: !-2: command not found [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# vim shell/test.sh [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat shell/test.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-21 #FileName: test.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** echo $- [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/test.sh #我们发现脚本中是没有"-i,-m和-h"选项的 hB [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# echo $- #查看当前shell支持的功能 himBH [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# cat -n /etc/profile #注意观察第67行就用到咱们这里说的"$-"变量哟~ 1 # /etc/profile 2 3 # System wide environment and startup programs, for login setup 4 # Functions and aliases go in /etc/bashrc 5 6 # It\'s NOT a good idea to change this file unless you know what you 7 # are doing. It\'s much better to create a custom.sh shell script in 8 # /etc/profile.d/ to make custom changes to your environment, as this 9 # will prevent the need for merging in future updates. 10 11 pathmunge () { 12 case ":${PATH}:" in 13 *:"$1":*) 14 ;; 15 *) 16 if [ "$2" = "after" ] ; then 17 PATH=$PATH:$1 18 else 19 PATH=$1:$PATH 20 fi 21 esac 22 } 23 24 25 if [ -x /usr/bin/id ]; then 26 if [ -z "$EUID" ]; then 27 # ksh workaround 28 EUID=`/usr/bin/id -u` 29 UID=`/usr/bin/id -ru` 30 fi 31 USER="`/usr/bin/id -un`" 32 LOGNAME=$USER 33 MAIL="/var/spool/mail/$USER" 34 fi 35 36 # Path manipulation 37 if [ "$EUID" = "0" ]; then 38 pathmunge /usr/sbin 39 pathmunge /usr/local/sbin 40 else 41 pathmunge /usr/local/sbin after 42 pathmunge /usr/sbin after 43 fi 44 45 HOSTNAME=`/usr/bin/hostname 2>/dev/null` 46 HISTSIZE=1000 47 if [ "$HISTCONTROL" = "ignorespace" ] ; then 48 export HISTCONTROL=ignoreboth 49 else 50 export HISTCONTROL=ignoredups 51 fi 52 53 export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL 54 55 # By default, we want umask to get set. This sets it for login shell 56 # Current threshold for system reserved uid/gids is 200 57 # You could check uidgid reservation validity in 58 # /usr/share/doc/setup-*/uidgid file 59 if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then 60 umask 002 61 else 62 umask 022 63 fi 64 65 for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do 66 if [ -r "$i" ]; then 67 if [ "${-#*i}" != "$-" ]; then 68 . "$i" 69 else 70 . "$i" >/dev/null 71 fi 72 fi 73 done 74 75 unset i 76 unset -f pathmunge 77 78 #Add by yinzhengjie 79 JAVA_HOME=/home/softwares/jdk1.8.0_201 80 PATH=$PATH:$JAVA_HOME/bin 81 82 [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]#
2>.脚本安全
-u:
在扩展一个没有设置的变量时,显示错误信息 等同set -o nounset
-e:
如果一个命令返回一个非0退出状态值(失败)就退出 等同set -o errexit
[root@node101.yinzhengjie.org.cn ~]# vim shell/test.sh [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat -n shell/test.sh 1 #!/bin/bash 2 # 3 #******************************************************************** 4 #Author: yinzhengjie 5 #QQ: 1053419035 6 #Date: 2019-11-21 7 #FileName: test.sh 8 #URL: http://www.cnblogs.com/yinzhengjie 9 #Description: The test script 10 #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. 11 #******************************************************************** 12 13 set -u #在扩展一个没有设置的变量时,显示错误信息 14 DIR=/tmp 15 unset DIR #此处为我们故意将变量名称删除掉,让下一行指令引用时找不到该变量 16 rm -rf $DIR/test/* [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/test.sh shell/test.sh: line 16: DIR: unbound variable [root@node101.yinzhengjie.org.cn ~]#
[root@node101.yinzhengjie.org.cn ~]# vim shell/test.sh [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# cat shell/test.sh #!/bin/bash # #******************************************************************** #Author: yinzhengjie #QQ: 1053419035 #Date: 2019-11-21 #FileName: test.sh #URL: http://www.cnblogs.com/yinzhengjie #Description: The test script #Copyright notice: original works, no reprint! Otherwise, legal liability will be investigated. #******************************************************************** set -ue #"-e"表示如果一个命令返回一个非0退出状态值(失败)就退出当前脚本,即不会继续执行脚本. xxx ls cat /etc/profile DIR=/tmp rm -rf $DIR/test/* [root@node101.yinzhengjie.org.cn ~]# [root@node101.yinzhengjie.org.cn ~]# bash shell/test.sh shell/test.sh: line 14: xxx: command not found [root@node101.yinzhengjie.org.cn ~]#
七.小试牛刀
(1)让所有用户的PATH环境变量的值多出一个路径,例如:/usr/local/apache/bin (2)用户 root 登录时,将命令指示符变成红色,并自动启用如下别名:
rm=‘rm –i’ cdnet=‘cd /etc/sysconfig/network-scripts/’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (如果系统是CentOS7) (3)任意用户登录系统时,显示红色字体的警示提醒信息“Hi,dangerous!” (4)编写生成脚本基本格式的脚本,包括作者,联系方式,版本,时间,描述等 (5)编写用户的环境初始化脚本reset.sh,包括别名,登录提示符,vim的设置,环境变量等
以上是关于shell中的循环语法的主要内容,如果未能解决你的问题,请参考以下文章
将vscode打造成无敌的IDE打造shell IDE--三大神器
Shell编程Shell中for循环while循环until循环语句
Shell编程Shell中for循环while循环until循环语句
shell中的for循环出现语法错误(syntax error: bad for loop variable)