⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shell编程.txt

📁 shell编程指南请详细阅读
💻 TXT
📖 第 1 页 / 共 5 页
字号:

.		.字符匹配,这是作为正则表达是的一部分,用来匹配任何的单个字符.

"		部分引用."STRING"阻止了一部分特殊字符,具体见第5章.

'		全引用. 'STRING' 阻止了全部特殊字符,具体见第5章.

,		逗号链接了一系列的算术操作,虽然里边所有的内容都被运行了,但只有最后一项被
		返回.

		如:
		1 let "t2 = ((a = 9, 15 / 3))"  # Set "a = 9" and "t2 = 15 / 3"

\		转义字符,如\X等价于"X"或'X',具体见第5章.

/		文件名路径分隔符.或用来做除法操作.

`		后置引用,命令替换,具体见第14章

:		空命令,等价于"NOP"(no op,一个什么也不干的命令).也可以被认为与shell的内建命令(true)作用相同.":"命令是一
		个bash的内建命令,它的返回值为0,就是shell返回的true.

		如:
		1 :
		2 echo $?   # 0

		死循环,如:

		 1 while :
		 2 do
		 3    operation-1
		 4    operation-2
		 5    ...
		 6    operation-n
		 7 done
		 8 
		 9 # 与下边相同:
		10 #    while true
		11 #    do
		12 #      ...
		13 #    done

		在if/then中的占位符,如:
		1 if condition
		2 then :   # 什么都不做,引出分支.
		3 else
		4    take-some-action
		5 fi

		在一个2元命令中提供一个占位符,具体见Example 8-2,和"默认参数".如:
		1 : ${username=`whoami`}
		2 # ${username=`whoami`}   如果没有":"的话,将给出一个错误,除非"username"是
		3 #                        个命令
		在here document中提供一个占位符,见Example 17-10.

		使用"参数替换"来评估字符串变量(见Example 9-14).如:
		1 : ${HOSTNAME?} ${USER?} ${MAIL?}
		2 #	 如果一个或多个必要的环境变量没被设置的话,
		3 #+ 就打印错误信息.

		"变量扩展/子串替换"
		在和 > (重定向操作符)结合使用时,把一个文件截断到0长度,没有修改它的权限.
		如果文件在之前并不存在,那么就创建它.如:
		1 : > data.xxx		#文件"data.xxx"现在被清空了.
		2
		3 #与 cat /dev/null >data.xxx 的作用相同
		4 #然而,这不会产生一个新的进程,因为":"是一个内建命令.
		具体参见Example 12-14.

		在和>>重定向操作符结合使用时,将不会对想要附加的文件产生任何影响.
		如果文件不存在,将创建.
		注意: 这只适用于正规文件,而不是管道,符号连接,和某些特殊文件.

		也可能用来作为注释行,虽然我们不推荐这么做.使用#来注释的话,将关闭剩余行的
		错误检查,所以可以在注释行中写任何东西.然而,使用:的话将不会这样.如:
		1 : This is a comment thar generates an error,(if [ $x -eq 3] ).

		":"还用来在/etc/passwd和$PATH变量中用来做分隔符.
		bash$	echo $PATH
		/usr/local/bin:/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games
!		取反操作符,将反转"退出状态"结果,(见Example 6-2).也会反转test操作符的意义.比
		如修改=为!=.!操作是Bash的一个关键字.

		在一个不同的上下文中,!也会出现在"间接变量引用"见Example 9-22.

		在另一种上下文中,!还能反转bash的"history mechanism"(见附录J 历史命令)
		需要注意的是,在一个脚本中,"history mechanism"是被禁用的.

*		万能匹配字符,用于文件名匹配(这个东西有个专有名词叫file globbing),或者是正则
		表达式中.注意:在正则表达式匹配中的作用和在文件名匹配中的作用是不同的.
		bash$ echo *
		abs-book.sgml add-drive.sh agram.sh alias.sh
*		数学乘法.
		**是幂运算.
?		测试操作.在一个确定的表达式中,用?来测试结果.
		(())结构可以用来做数学计算或者是写c代码,那?就是c语言的3元操作符的
		一个.
		在"参数替换"中,?测试一个变量是否被set了.
?		在file globbing中和在正则表达式中一样匹配任意的单个字符.

$		变量替换
		1 var1=5
		2 var2=23skidoo
		3 
		4 echo $var1     # 5
		5 echo $var2     # 23skidoo
$		在正则表达式中作为行结束符.
${}		参数替换,见9.3节.
$*,$@	位置参数
$?		退出状态变量.$?保存一个命令/一个函数或者脚本本身的退出状态.
$$		进程ID变量.这个$$变量保存运行脚本进程ID
()		命令组.如:
		1 (a=hello;echo $a)
		注意:在()中的命令列表,将作为一个子shell来运行.
		在()中的变量,由于是在子shell中,所以对于脚本剩下的部分是不可用的.
		如:
		1 a=123
		2 ( a=321; )	      
		3 
		4 echo "a = $a"   # a = 123
		5 # 在圆括号中a变量,更像是一个局部变量.

		用在数组初始化,如:
		1 Array=(element1,element2,element3)

{xxx,yyy,zzz...}
		大括号扩展,如:
		1 cat {file1,file2,file3} > combined_file
		2 # 把file1,file2,file3连接在一起,并且重定向到combined_file中.
		3 
		4 
		5 cp file22.{txt,backup}
		6 # 拷贝"file22.txt" 到"file22.backup"中

		一个命令可能会对大括号中的以逗号分割的文件列表起作用[1]. file globbing将对
		大括号中的文件名作扩展.
		注意: 在大括号中,不允许有空白,除非这个空白是有意义的.
		echo {file1,file2}\ :{\ A," B",' C'}
		file1 : A file1 : B file1 : C file2 : A file2 : B file2 : C
{}		代码块.又被称为内部组.事实上,这个结构创建了一个匿名的函数.但是与函数不同的
		是,在其中声明的变量,对于脚本其他部分的代码来说还是可见的.如:
		bash$ 
		{
			local a;
			a= 123;
		}
		bash中的local申请的变量只能够用在函数中.

		1 a=123
		2 { a=321; }
		3 echo "a = $a"   # a = 321   (说明在代码块中对变量a所作的修改,影响了外边的变量a)
		4 
		5 # Thanks, S.C.

		下边的代码展示了在{}结构中代码的I/O重定向.

Example 3-1. 代码块和I/O重定向
################################Start Script#######################################
 1 #!/bin/bash
 2 # 从 /etc/fstab中读行
 3 
 4 File=/etc/fstab
 5 
 6 {
 7 read line1
 8 read line2
 9 } < $File
10 
11 echo "First line in $File is:"
12 echo "$line1"
13 echo
14 echo "Second line in $File is:"
15 echo "$line2"
16 
17 exit 0
18 
19 # 现在,你怎么分析每行的分割域
20 # 暗示: 使用 awk.
################################End Script#########################################

Example 3-2. 将一个代码块的结果保存到文件
################################Start Script#######################################
 1 #!/bin/bash
 2 # rpm-check.sh
 3 
 4 # 这个脚本的目的是为了描述,列表,和确定是否可以安装一个rpm包.
 5 # 在一个文件中保存输出.
 6 # 
 7 # 这个脚本使用一个代码块来展示
 8 
 9 SUCCESS=0
10 E_NOARGS=65
11 
12 if [ -z "$1" ]
13 then
14   echo "Usage: `basename $0` rpm-file"
15   exit $E_NOARGS
16 fi  
17 
18 { 
19   echo
20   echo "Archive Description:"
21   rpm -qpi $1       # 查询说明
22   echo
23   echo "Archive Listing:"
24   rpm -qpl $1       # 查询列表
25   echo
26   rpm -i --test $1  # 查询rpm包是否可以被安装
27   if [ "$?" -eq $SUCCESS ]
28   then
29     echo "$1 can be installed."
30   else
31     echo "$1 cannot be installed."
32   fi  
33   echo
34 } > "$1.test"       # 把代码块中的所有输出都重定向到文件中
35 
36 echo "Results of rpm test in file $1.test"
37 
38 # 查看rpm的man页来查看rpm的选项
39 
40 exit 0
################################End Script#########################################
		注意: 与()中的命令不同的是,{}中的代码块将不能正常地开启一个新shell.[2]

{} \;	路径名.一般都在find命令中使用.这不是一个shell内建命令.
		注意: ";"用来结束find命令序列的-exec选项.

[]		test.
		test的表达式将在[]中.
		值得注意的是[是shell内建test命令的一部分,并不是/usr/bin/test中的扩展命令
		的一个连接.

[[]]	test.
		test表达式放在[[]]中.(shell关键字)
		具体查看[[]]结构的讨论.

[]		数组元素
		Array[1]=slot_1
		echo ${Array[1]}

[]		字符范围
		在正则表达式中使用,作为字符匹配的一个范围

(())	数学计算的扩展
		在(())结构中可以使用一些数字计算.
		具体参阅((...))结构.

>&>>&>><
		重定向.
		scriptname >filename 重定向脚本的输出到文件中.覆盖文件原有内容.
		command &>filename 重定向stdout和stderr到文件中
		command >&2	重定向command的stdout到stderr
		scriptname >>filename 重定向脚本的输出到文件中.添加到文件尾端,如果没有文件,
		则创建这个文件.

		进程替换,具体见"进程替换部分",跟命令替换极其类似.
		(command)>
		<(command)

		<和> 可用来做字符串比较
		<和> 可用在数学计算比较

<<		重定向,用在"here document"

<<<		重定向,用在"here string"

<,>		ASCII比较
		 1 veg1=carrots
		 2 veg2=tomatoes
		 3 
		 4 if [[ "$veg1" < "$veg2" ]]
		 5 then
		 6   echo "Although $veg1 precede $veg2 in the dictionary,"
		 7   echo "this implies nothing about my culinary preferences."
		 8 else
		 9   echo "What kind of dictionary are you using, anyhow?"
		10 fi

\<,\>	正则表达式中的单词边界.如:
		bash$grep '\<the\>' textfile
	
|		管道.分析前边命令的输出,并将输出作为后边命令的输入.这是一种产生命令链的
		好方法.
		1 echo ls -l | sh
		2 #  传递"echo ls -l"的输出到shell中,
		3 #+ 与一个简单的"ls -l"结果相同.
		4 
		5 
		6 cat *.lst | sort | uniq
		7 # 合并和排序所有的".lst"文件,然后删除所有重复的行.
		
		管道是进程间通讯的一个典型办法,将一个进程的stdout放到另一个进程的stdin中.
		标准的方法是将一个一般命令的输出,比如cat或echo,传递到一个过滤命令中(在这个
		过滤命令中将处理输入),得到结果,如:
		cat $filename1 | $filename2 | grep $search_word

		当然输出的命令也可以传递到脚本中.如:
################################Start Script#######################################
1 #!/bin/bash
2 # uppercase.sh : 修改输出,全部转换为大写
3 
4 tr 'a-z' 'A-Z'
5 #  字符范围必须被""引用起来
6 #+ 来阻止产生单字符的文件名.
7 
8 exit 0
################################End Script#########################################
		
		现在让我们输送ls -l的输出到一个脚本中.
		bash$ ls -l | ./uppercase.sh
		-RW-RW-R--    1 BOZO  BOZO       109 APR  7 19:49 1.TXT
		-RW-RW-R--    1 BOZO  BOZO       109 APR 14 16:48 2.TXT
		-RW-R--R--    1 BOZO  BOZO       725 APR 20 20:56 DATA-FILE

		注意:管道中的一个进程的stdout必须被下一个进程作为stdin读入.否则,数据流会阻
		塞,并且管道将产生非预期的行为.
		如:
		1 cat file1 file2 | ls -l | sort
		2 #从"cat file1 file2"中的输出并没出现

		作为子进程的运行的管道,不能够改变脚本的变量.
		1 variable="initial_value"
		2 echo "new_value" | read variable
		3 echo "variable = $variable"			#variable = initial_value
		如果管道中的某个命令产生了一个异常,并中途失败,那么这个管道将过早的终止.
		这种行为被叫做a broken pipe,并且这种状态下将发送一个SIGPIPE信号.

>|		强制重定向(即使设置了noclobber选项--就是-C选项).这将强制的覆盖一个现存文件.

||		或-逻辑操作.

&		后台运行命令.一个命令后边跟一个&,将表示在后台运行.
		bash$sleep 10 &
		[1] 850
		[1]+	Done			sleep 10
		在一个脚本中,命令和循环都可能运行在后台.

Example 3-3. 在后台运行一个循环
################################Start Script#######################################

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -