• shell脚本-基础


    shell脚本-基础

    编程基础

    	程序是指令+ 数据
    	程序编程风格:
    		过程式:以指令为中心,数据服务于指令
    		对象式:以数据为中心,指令服务于数据
    	shell 程序提供了编程能力,解释执行。
    	计算运行二进制指令。
    	编译执行:
    		高级语言--> 编译器--> 目标代码
    		如java,C#
    	解释执行:
    		高级语言--> 解释器--> 机器代码
    		如shell, perl, python
    		
    	编程逻辑处理方式:
    		顺序执行
    		循环执行
    		选择执行
    	
    	shell 编程:
    		过程式、解释执行
    		
    	编程语言的基本结构:
    		各种系统命令的组合
    		数据存储:变量、数组等
    		表达式: a + b等
    		语句:if的等
    

    shell脚本说明

    	shell 脚本:
    		包含一些命令或声明,并符合一定格式的文本文件
    	shell 脚本的用途有:
    		自动化常用命令
    		执行系统管理和故障排除
    		创建简单的应用程序
    		处理文本或文件
    	格式要求:
    		首行shebang 机制
    		#!/bin/bash
    		#!/usr/bin/python
    		#!/usr/bin/perl
    		....
    		#! 就是告诉系统,这个脚本文件需要使用指定的命令解释器来执行。
    		紧随 #!的是一个路径名,此路径指向用来解释此脚本的程序,它可以是shell,可以是程序设计语言,也可以是实用程序。
    		这个解释器从头( #!的下一行)开始执行整个脚本的命令,同时忽略注释。 
    	shell脚本的创建和运行:
    		创建脚本:
    			使用文本编辑器vim等来创建文本。
    			第一行必须是shell声明序列#!,一般为#!/bin/bash。
    			其余行为执行的命令。
    			添加注释使用#,注释以#开头。
    		运行脚本:
    			给予执行权限,在命令行上指定脚本的绝对或相对路径
    				chmod +x FILE.sh
    				/PATH/TO/FILE.sh
    			直接运行解释器,将脚本作为解释器程序的参数运行
    				source or . +脚本,一般不这么用,这样会对当前环境进行影响
    				bash + 脚本,就不会影响外部工作环境
    	脚本规范:
    		脚本代码开头约定
    			1 、第一行一般为调用使用的语言
    			2 、程序名,避免更改文件名为无法找到正确的文件
    			3 、版本号
    			4 、更改后的时间
    			5 、作者相关信息
    			6 、该程序的作用,及注意事项
    			7 、最后是各版本的更新简要说明
    		脚本开头的示例:
    			#!/bin/bash
    			#-------------------------------------------------
    			#Filename:
    			#Description:
    			#Revision:
    			#Date:
    			#Author:
    			#Email:
    			#Phonenumb:
    			#Copyright:
    			#------------------------------------------------
    		脚本结构:
    			解释器:#!/bin/shell,等
    			配置变量:自己定义的变量,A=123等
    			功能描述:以#开头来说明接下来执行语句的作用
    			执行命令:指令+参数,包括各种语句表达式等
    	脚本调试:
    		检测脚本中的语法错误
    			bash -n /PATH/TO/FILE.sh
    		调试执行
    			bash -x /PATH/TO/FILE.sh
    		脚本中默认不支持别名
    			尽可能用命令的绝对路径
    

    变量介绍

    	变量的作用:
    		数据暂存
    		参与运算
    		表示数据范围
    	强类型变量:
    		变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。
    		一般定义变量时必须指定类型、参与运算必须符合类型要求。
    		调用未声明变量会产生错误。
    		如 java,c#的变量
    	弱类型变量:
    		语言的运行时会隐式做数据类型转换。
    		无须指定类型,默认均为字符型。
    		参与运算会自动进行隐式类型转换。
    		变量无须事先定义可直接调用
    		如bash,php的变量
    	变量的命名规则:
    		不能使程序中的保留字,如if、for等。
    		只能使用数字、字母及下划线,且不能以数字开头。
    		需见名知义。
    		统一命名规则,即驼峰命名法
    	bash中的变量种类
    		根据变量的生效范围作为标准
    		本地变量:	生效范围为当前shell进程。对当前shell之外的其它shell 进程,包括当前shell的子shell 进程均无效。
    		环境变量:	生效范围为当前shell进程及其子进程。
    		局部变量:	生效范围为当前shell进程中某代码片断( 通常指函数)。
    		位置变量:	$1, $2, ...来表示,用于让脚本在脚本代码中通过调用命令行传递给它的参数,大于9的数,就应该加大括号:${10}
    		特殊变量:	$?, $0, $*, $@, $#,$$
    	本地变量
    		变量赋值:
    			name=value
    		引用value:
    			直接字串:	name=“root"
    			变量引用:	name="$USER"
    			命令引用:	name=` COMMAND `; name =$(COMMAND)
    		变量引用:
    			${name}	 
    			$name	
    			"  " :	弱引用,其中的变量引用会被替换为变量值
    			 '  ':	强引用,其中的变量引用不会被替换为变量值,而保持原字符串
    			${name[$i]}	i是变量,name[$i]也是变量
    			' ':最傻的那个 ;" ":中间傻 ; ` `:聪明
    		显示已定义的所有变量:
    			set
    		删除变量:
    			unset name
    	环境变量
    		变量声明和赋值:
    			export  name=VALUE
    			declare -x  name=VALUE
    		变量引用:
    			$name, ${name},"$name"(尽量用带括和带双引号的)
    		显示所有环境变量:
    			env
    			printenv
    		bash内建的环境变量
    			PATH,SHELL,USER,UID,HOME,PWD,SHLVL,LANG,MAIL,HOSTNAME,HISTSIZE,—
    	只读变量
    		只能声明,但不能修改和删除。
    		声明只读变量:
    			readonly name
    			declare -r name
    				先赋值再声明或者是声明赋值一起做,不然,声明过后就不能再赋值了
    		查看只读变量:
    			readonly –p
    	位置变量
    		在脚本代码中调用通过命令行传递给脚本的参数
    		$1, $2, ... :	对应第1 、第2 等参数,是脚本后面跟着的参数,且9以后需要加大括号:${10}
    		shift [n] 	可以更换位置
    		$0:  	命令本身
    		$*:  	传递给脚本的所有参数,全部参数合为一个字符串
    		$@:  	传递给脚本的所有参数,每个参数为独立字符串
    		$#:  	传递给脚本的参数的个数
    		$@与$*  	只在被双引号包起来的时候才会有差异
    		set - -  	清空所有位置变量
    		涉及到位置参数,脚本前面放置这个
    			[ $# -lt 1 ] && echo "Usage:`basename $0` arg1... " && exit 10
    			
    	转换变量类型
    		可以使用declare或者typeset来转换变量类型
    			[root@localhost ~]# a=1;b=2;c=a+b;
    			[root@localhost ~]# echo $c
    			a+b
    			[root@localhost ~]# typeset -i a;typeset -i b;typeset -i c;
    			[root@localhost ~]# a=1;b=2;c=a+b;
    			[root@localhost ~]# echo $c
    

    退出状态

    	进程使用退出状态来报告成功或失败
    	0 代表成功,1 -255 代表失败
    	$?变量保存最近的命令退出状态
    	示例:
    		ping -c1 -W1 hostdown &> /dev/null
    		echo $?
    	bash 自定义退出状态码
    		exit [n]:自定义退出状态码
    		注意:
    			脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit 命令后面的数字
    			如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
    

    算术运算

    	help let
    	let arg [arg ...]
    	运算
    		+, -, *, /, % 取模(取余), ** (乘方)
    		注:乘法符号有些场景中需要转义 , 如*
    	增强型赋值:
    		+=, -=, *=, /=, %=
    	自增和自减:
    		let var+=1
    		let var++
    		let var-=1
    		let var--
    	实现算术运算
    		let var= 算术表达式
    		var=$[ 算术表达式]
    		var=$(( 算术表达式))
    		var=$(expr arg1 arg2 arg3 ...)    ##expr判断后面的变量是否为整数,但不能为0。
    		declare –i var =  数值
    		echo ‘ 算术表达式’ | bc
    		bc
    		$RANDOM (0-32767)  ##bash内建的随机数生成器
    			echo $[$RANDOM%50]  ##0-49 之间随机数
    

    逻辑运算

    	true和false
    		1, 0
    		输出0为假
    		设置空为假
    		设置0为真
    	与:
    		1  与 1 = 1
    		1  与 0 = 0
    		0  与 1 = 0
    		0  与 0 = 0
    	或:
    		1 或  1 = 1
    		1 或  0 = 1
    		0 或  1 = 1
    		0 或  0 = 0
    	非:!
    		! 1 = 0
    		! 0 = 1
    	短路运算
    		短路与
    		第一个为0 ,结果必定为0
    		第一个为1 ,第二个必须要参与运算
    		短路或
    		第一个为1 ,结果必定为1
    		第一个为0 ,第二个必须要参与运算
    	
    	异或:^
    		异或的两个值, 相同为假,不同为真
    		数值交换:		
    

    条件性执行操作符:&&和||

    	根据退出状态而定,命令可以有条件地运行。
    	&&  代表条件性的and、then,与
    	|| 代表条件性的or、else,或
    

    条件测试:

    	判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成测试过程
    	评估布尔声明,以便用在条件性执行中
    		若真,则返回0
    		若假,则返回1
    	测试命令和表达式
    		test EXPRESSION    
    		[ EXPRESSION ]
    		[[ EXPRESSION ]]     ##支持扩展的正则表达式算法
    		注意:
    			EXPRESSION 前后必须有空白字符
    			多测试在使用
    			![](http://images2017.cnblogs.com/blog/1250974/201802/1250974-20180207000632435-1219260200.png)
    	
    	数值测试:
    		-gt (great than)	大于
    		-ge (great equal)	大于等于
    		-eq  (equal)	等于
    		-ne (not equal)	不等于
    		-lt (lower than)	小于 
    		-le (lower equal)	小于等于
    	字符串测试:
    		== 	等于
    		>	ascii 码大于ascii码 
    		< 	小于
    		!= 	不等于
    		=~ 	左侧字符串能够被右侧的PATTERN所匹配
    		-z	"STRING“ 字符串为空,空为真,不空为假
    		-n	"STRING“ 字符串不空,不空为真,空为假
    		注意:  
    			此表达式一般用于[[ ]] 中;扩展的正则表达式。
    			用于字符串比较时,用到的操作数STRING都应该使用引号。
    	文件测试
    		存在为真,不存在为假
    		存在性和类别测试:
    			-a|-e FILE:  	是否文件存在
    			-b FILE :	是否存在且为块设备文件
    			-c FILE :	是否存在且为字符设备文件
    			-d FILE :	是否存在且为目录文件
    			-f FILE :	是否存在且为普通文件
    			-h|-L FILE :	存在且为符号链接文件
    			-p FILE :	是否存在且为命名管道文件
    			-S FILE :	是否存在且为套接字文件
    		文件权限测试:
    			-r FILE :	是否存在且可读
    			-w FILE:  	是否存在且可写
    			-x FILE:  	是否存在且可执行
    			测试的是实际权限,例如root就有大多数权限
    		文件特殊权限测试:
    			-u FILE :	是否存在且拥有suid 权限
    			-g FILE :	是否存在且拥有sgid 权限
    			-k FILE :	是否存在且拥有sticky 权限
    		文件大小测试:
    			-s FILE:  	是否存在且非空
    		文件是否打开:
    			-t fd:	fd表示文件描述符是否已经打开且与某终端相关
    			-N FILE:	文件自从上一次被读取之后是否被修改过
    			-O FILE :	当前有效用户是否为文件属主
    			-G FILE :	当前有效用户是否为文件属组
    		双目测试:
    			FILE1 -ef FILE2: 	FILE1与FILE2 是否指向同一个设备上的相同inode
    			FILE1 -nt FILE2: 	FILE1是否新于FILE2 (mtime) 
    			FILE1 -ot FILE2: 	FILE1是否旧于FILE2
    		
    	组合测试
    		命令
    			COMMAND1 && COMMAND2	 并且
    			COMMAND1 || COMMAND2 	 或者
    			! COMMAND 	 非
    			如:[[ -r FILE ]] && [[ -w FILE ]]
    		表达式
    			EXPRESSION1 -a EXPRESSION2  	并且
    			EXPRESSION1 -o EXPRESSION2  	或者
    			! EXPRESSION  	非
    			必须使用测试命令进行
    		示例:
    			[ -z “$HOSTNAME” -o $HOSTNAME "=="localhost.localdomain" ] && hostname shen
    			[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
    

    括号的用法

    	小括号()
    		(子进程),小括号是开子进程了,开子shell,小括号内值,只能在括号内用。
    	中括号[ ]
    		[表达式],用于测试
    	大括号{ }
    		{ cmd ; cmd ; …. ; }不会开子shell
    

    参数导入:read

    	使用read 来把输入值分配给一个或多个shell 变量。
    	使用read 从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量。
    	示例:
    		read -p “Enter a filename: “  FILE
    		read a b c <<< "xxx yyy zzz"
    

    展开命令行的优先级

    	优先级从高到低
    	把命令行分成单个命令词
    	展开别名
    	展开大括号的声明({}) 
    	展开波浪符声明(~) 
    	命令替换$() 和 (``) 
    	再次把命令行分成命令词
    	展开文件通配(* 、? 、[abc] 等等)
    	准备I/0 重导向(< 、>) 
    	运行命令
    

    防参数属性扩展

    	反斜线( )会使随后的字符按原意解释
    		$ echo Your cost: $5.00
    		Your cost: $5.00
    	加引号来防止扩展
    		单引号(’ )防止所有扩展
    		双引号(” )也防止所有扩展,但是以下情况例外:
    			$ (美元符号)#变量扩展
    			 ` (反引号)#命令替换
    			 (反斜线) #禁止单个字符扩展
    			! (叹号)#历史命令替换
    

    $- 变量

    	echo $-
    	himBH
    	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个历史命令
    
  • 相关阅读:
    UVA 10817 Headmaster's Headache(状压DP)
    UVA 11795 Mega Man's Mission(状态压缩DP)
    ZOJ3777 Problem Arrangement(状态压缩DP)
    NYOJ832 合并游戏(简单状压DP)
    UVA 1252 Twenty Questions(状压DP)
    UVA 10911 Forming Quiz Teams(状压DP)
    HDU 2196 Computer(经典树形DP)
    内连接、左外连接、右外连接、交叉连接区别 羽毛
    javaweb学习总结<转> 羽毛
    HIbernate基础 羽毛
  • 原文地址:https://www.cnblogs.com/shenxm/p/8424816.html
Copyright © 2020-2023  润新知