Shell 语法


  •   	Shell  之 语法
    

解释器:
1)Bourne Shell(/usr/bin/sh或/bin/sh)
2)Bourne Again Shell(/bin/bash)
3)C Shell(/usr/bin/csh)
4)K Shell(/usr/bin/ksh)
5)Shell for Root(/sbin/sh)

Shell 注释:
1. 单行注释
在一行的字符最前面加 #
2. 多行注释
:<<a
注释内容...
a

		a:
			a可以换成其他任意合法的符号
	eg:
		:<<EOF
		注释内容...
		注释内容...
		注释内容...	
		EOF

I/O:
输入:
read 变量 命令从标准输入中读取一行到变量中
输出:
echo 字符串 输出 echo 后面的内容(字符串)

	echo参数:
		-e		开启转义
	字符串:
		支持转义字符:
			\n	换行
			\c	不换行
	echo `命令`:
		打印命令执行后的结果

语法:
1. 变量
1)变量类型:
1)局部变量
2)环境变量
3)shell变量
$n 传入脚本的参数 $0 为脚本本身
$# 传递到脚本的参数个数
\(* 以一个单字符串显示所有向脚本传递的参数。 如"\)"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
\(@ 与\)
相同,但是使用时加引号,并在引号中返回每个参数。
如"$@"用「"」括起来的情况、以"$1" "\(2" … "\)n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
2)自定义变量
声明创建:
变量名=值
用法:
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
1. 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
2. 中间不能有空格,可以使用下划线(_)。
3. 不能使用标点符号。
4. 不能使用bash里的关键字(可用help命令查看保留关键字)。
eg:
name="GAME"
只读变量:
readonly 变量名 在变量前加 readonly 命令
----> 将变量变为只读变量
----> 在变为只读变量时,应当初始化一下
使用变量:
1. $(var) --- 一般这样就可以
2. \({(var)} --- 加{} 只是区分变量边界 删除变量: unset 变量名 在变量前加 unset 注: 1. unset 不能删除 readonly变量 2. 变量删除后不能在再次使用 3)字符串 声明方法: 1> var='varValue' 2> var="varValue" 注: 1. 单引号 '' 方式的字符串,只视为字符串,不做其他处理 2. 双引号 "" 方式的字符串,可处理变量,转义字符 字符串拼接: "\){var1} \(var2" 引号内使用变量就是 '\){var} \(var2' eg: your_name="runoob" # 使用双引号拼接 greeting="hello, "\)your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1

				# 使用单引号拼接
				greeting_2='hello, '$your_name' !'
				greeting_3='hello, ${your_name} !'
				echo $greeting_2  $greeting_3
		字符串长度:
			${#变量}     字符串前加 # 字符
			eg:
			string="abcd"
			echo ${#string} #输出 4
		提取子字符串:
			变量:start:end    
				截取从start 到 end 位置的子字符串
			
			eg:
				string="runoob is a great site"
				echo ${string:1:4} # 输出 unoo
		查找子字符串:
			eg:
				string="runoob is a great site"
				echo `expr index "$string" io`  # 输出 4
	4)数组
		数组定义:
			1)数组名=(值1 值2 ... 值n)
			2)数组名[下标]=值 等多个组成
		数组访问:
			${数组名[下标]}
			
			注:
				1.下标n    是有效的数字
				2. @ 符号  获取所有元素
		数组长度:
			1. 取得所有长度		
				${#数组名[@或*]}
			2. 取得数组单个元素的长度
				${#数组名[n]}
				n 为下标
2. 运算符
	
	原生bash不支持简单的数学运算,但是可以通过其他命令来实现,
	例如 awk 和 expr,expr 最常用
	expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
	
	在以下的a,b分别为以下值
	a=10
	b=20
	算数运算符
		和 C 完全一样
		(+ - * / % = == !=)
	关系运算符
		关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
		-eq	检测两个数是否相等,相等返回 true。	[ $a -eq $b ] 返回 false。
		-ne	检测两个数是否不相等,不相等返回 true。	[ $a -ne $b ] 返回 true。
		-gt	检测左边的数是否大于右边的,如果是,则返回 true。	[ $a -gt $b ] 返回 false。
		-lt	检测左边的数是否小于右边的,如果是,则返回 true。	[ $a -lt $b ] 返回 true。
		-ge	检测左边的数是否大于等于右边的,如果是,则返回 true。	[ $a -ge $b ] 返回 false。
		-le	检测左边的数是否小于等于右边的,如果是,则返回 true。	[ $a -le $b ] 返回 true。
	布尔运算符
		!	非运算,表达式为 true 则返回 false,否则返回 true。	[ ! false ] 返回 true。
		-o	或运算,有一个表达式为 true 则返回 true。	[ $a -lt 20 -o $b -gt 100 ] 返回 true。
		-a	与运算,两个表达式都为 true 才返回 true。	[ $a -lt 20 -a $b -gt 100 ] 返回 false。
	逻辑运算符
		&&	逻辑的 AND	[[ $a -lt 100 && $b -gt 100 ]] 返回 false
		||	逻辑的 OR	[[ $a -lt 100 || $b -gt 100 ]] 返回 true
	字符串运算符
		假定变量 a 为 "abc",变量 b 为 "efg":
			=	检测两个字符串是否相等,相等返回 true。	[ $a = $b ] 返回 false。
			!=	检测两个字符串是否相等,不相等返回 true。	[ $a != $b ] 返回 true。
			-z	检测字符串长度是否为0,为0返回 true。	[ -z $a ] 返回 false。
			-n	检测字符串长度是否为0,不为0返回 true。	[ -n "$a" ] 返回 true。
			$	检测字符串是否为空,不为空返回 true。	[ $a ] 返回 true。
	文件测试运算符
		文件测试运算符用于检测 Unix 文件的各种属性。
			-b file	检测文件是否是块设备文件,如果是,则返回 true。	[ -b $file ] 返回 false。
			-c file	检测文件是否是字符设备文件,如果是,则返回 true。	[ -c $file ] 返回 false。
			-d file	检测文件是否是目录,如果是,则返回 true。	[ -d $file ] 返回 false。
			-f file	检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。	[ -f $file ] 返回 true。
			-g file	检测文件是否设置了 SGID 位,如果是,则返回 true。	[ -g $file ] 返回 false。
			-k file	检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。	[ -k $file ] 返回 false。
			-p file	检测文件是否是有名管道,如果是,则返回 true。	[ -p $file ] 返回 false。
			-u file	检测文件是否设置了 SUID 位,如果是,则返回 true。	[ -u $file ] 返回 false。
			-r file	检测文件是否可读,如果是,则返回 true。	[ -r $file ] 返回 true。
			-w file	检测文件是否可写,如果是,则返回 true。	[ -w $file ] 返回 true。
			-x file	检测文件是否可执行,如果是,则返回 true。	[ -x $file ] 返回 true。
			-s file	检测文件是否为空(文件大小是否大于0),不为空返回 true。	[ -s $file ] 返回 true。
			-e file	检测文件(包括目录)是否存在,如果是,则返回 true。	[ -e $file ] 返回 true。
			
			-S: 判断某文件是否 socket。
			-L: 检测文件是否存在并且是一个符号链接。
3. 流程控制
	1) if...else
		单一判断:
			if condition
			then
				command1 
				command2
				...
				commandN 
			fi
		多层判断:
			else、elif
		
		和C  语法差不多嵌套进去
	2) case
		case 值 in
		匹配1)
			command1
			command2
			...
			commandN
			;;
		匹配2)
			command1
			command2
			...
			commandN
			;;
		esac
		
	2) for 循环
		for var in item1 item2 ... itemN
		do
			command1
			command2
			...
			commandN
		done
	3) while 循环
			while condition
			do
				command
			done
			
			eg:
				while(( $int<=5 ))
				do
					echo $int
					let "int++"
				done

			
	4)死循环
			while :
			do
				command
			done
		
		或者
		
			while true
			do
				command
			done
		
		或者
		
			for (( ; ; ))
	5) until 循环
			until condition
			do
				command
			done
			a=0
		
		eg:
			until [ ! $a -lt 10 ]
			do
			   echo $a
			   a=`expr $a + 1`
			done
	6) 跳出循环关键字:
		break	跳出循环
		continue	跳出本次循环
4. 函数
	[ function ] funname [()]

	{

		action;

		[return int;]

	}
	说明:
		1、可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
		2、参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
		3、函数返回值在调用该函数后通过 $? 来获得。
		
	函数传参:
		利用$n 的形式传参 $1第一个参数 $2 第二参数
		eg:
			funWithParam(){
				echo "第一个参数为 $1 !"
				echo "第二个参数为 $2 !"
				echo "第十个参数为 $10 !"
				echo "第十个参数为 ${10} !"
				echo "第十一个参数为 ${11} !"
				echo "参数总数有 $# 个!"
				echo "作为一个字符串输出所有参数 $* !"
			}
			funWithParam 1 2 3 4 5 6 7 8 9 34 73
			
		
5.命令
	输入、输出重定向:
		command > file	将输出重定向到 file。
		command < file	将输入重定向到 file。
		command >> file	将输出以追加的方式重定向到 file。
		n > file	将文件描述符为 n 的文件重定向到 file。
		n >> file	将文件描述符为 n 的文件以追加的方式重定向到 file。
		n >& m	将输出文件 m 和 n 合并。
		n <& m	将输入文件 m 和 n 合并。
		<< tag	将开始标记 tag 和结束标记 tag 之间的内容作为输入。
		
		如果希望对 stdin 和 stdout 都重定向,可以这样写:
			$ command < file1 >file2
			command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2。
			
		Here Document:
		  Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。
			
			它的基本的形式如下:
				command << delimiter
					document
				delimiter
			它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。
			注意:
			结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。
			开始的delimiter前后的空格会被忽略掉。
			
			eg:
				$ wc -l << EOF
					欢迎来到
					菜鸟教程
					www.runoob.com
				EOF
				3          # 输出结果为 3 行
				$
	printf:
		printf  format-string  [arguments...]
		参数说明:
			format-string: 为格式控制字符串
			arguments: 为参数列表。
			
			1)%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),
			任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,
			超过也会将内容全部显示出来。
			
			2)%-4.2f 指格式化为小数,其中.2指保留2位小数。
			
			\a	警告字符,通常为ASCII的BEL字符
			\b	后退
			\c	抑制(不显示)输出结果中任何结尾的换行字符(只在%b格式指示符控制下的参数字符串中有效),而且,任何留在参数里的字符、任何接下来的参数以及任何留在格式字符串中的字符,都被忽略
			\f	换页(formfeed)
			\n	换行
			\r	回车(Carriage return)
			\t	水平制表符
			\v	垂直制表符
			\\	一个字面上的反斜杠字符
			\ddd	表示1到3位数八进制值的字符。仅在格式字符串中有效
			\0ddd	表示1到3位的八进制值字符
	test:
		Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
		
		数值测试:
			-eq	等于则为真
			-ne	不等于则为真
			-gt	大于则为真
			-ge	大于等于则为真
			-lt	小于则为真
			-le	小于等于则为真
			
			eg:
				num1=100
				num2=100
				if test $[num1] -eq $[num2]
				then
					echo '两个数相等!'
				else
					echo '两个数不相等!'
				fi
				
		字符串测试:
			=	等于则为真
			!=	不相等则为真
			-z 字符串	字符串的长度为零则为真
			-n 字符串	字符串的长度不为零则为真
			
		文件测试:
		-e 文件名	如果文件存在则为真
		-r 文件名	如果文件存在且可读则为真
		-w 文件名	如果文件存在且可写则为真
		-x 文件名	如果文件存在且可执行则为真
		-s 文件名	如果文件存在且至少有一个字符则为真
		-d 文件名	如果文件存在且为目录则为真
		-f 文件名	如果文件存在且为普通文件则为真
		-c 文件名	如果文件存在且为字符型特殊文件则为真
		-b 文件名	如果文件存在且为块特殊文件则为真
	
	文件包含:
			. filename   # 注意点号(.)和文件名中间有一空格

		或

			source filename
posted @ 2019-07-19 19:33  Kernel001  阅读(308)  评论(0编辑  收藏  举报