shell编程第二讲(灵魂の低调)
文件描述符(文件句柄)
重要: 标准输入 0
标准输出 1
标准错误 2
1.使用文件描述符和文件关联
用exec命令将任何文件和文件描述符关联,语法是:$ exec n>file (n是整数,file是 文件名)如:$ exec 4>fd4.out 把文件fd4.out和文 件描述符4关联起来。
2.重定向标准输出和标准错误到单独文件
文件描述符最常用的将标准输出和标准错误重定向到单独文件,基本语法为:
cmd 1>file1 2>file2 在这里,命令的标准输出被重定向到文件file1,标准错误被重定 向到文件file2。当然我们也可以用追加操作符代替标准的重定向操作符(追加操作符在 第一讲已经提及,这儿就不重复了)
3.重定向标准输出和标准错误到同一个文件
由上面我们已经知道如何把stdout(标准输出)和stderr(标准错误)重定向到不同的文 件,但是我们如何将他重定向到一个文件呢?基本语法:cmd>file 2>& 这样cmd的文件描 述符1和文件描述符2都被重定向文件file
4.重定向两个文件描述符
我们也可以将一个文件描述符重定向到另一个文件描述符:n>&m
输出重定向的普通格式经常和exec命令结合来复制一个已经打开的文件描述符:exec n>&m (这里m是一个已经打开的文件描述符)
下面我来举个例子让大家能更好的理解:
如果文件描述符4被打开,exec 4> a.txt
接着的命令: exec 5>&4, 这样描述符5成为文件描述符4的复制品了
5.关闭文件描述符
基本语法:
exec n>- (n是一个已打开的文件描述符)
学完的问题:
给出下列脚本:
exec 4>out.txt
exec 5>&4
exec 1>&5
date
请问date命令的输出将在哪儿结束?
shell编程第三讲(灵魂の低调)
上期答案:out.txt
进程
1.前台进程:默认情况下,进程都是前台运行的,从键盘输入而从屏幕输出。
但是当你运行一个进程的时候不能运行另一个进程,你可以键入命令,但
是不会有任何提示,幸运的是unix提供后台进程的转换。
2.后台进程:开始一个后台进程最简单的办法是在命令后加&符号,例如:
$ ls &
输出如下语句:
[1] 3821
模板,桌面,下载,图片
输出的第一列是由shell产生的,表示这段进程在后台运行。其中[1] 3821包含任务标识 符和进程标识符,如果这时按回车,会出现 [1]+ Done ls&(说明任务成功完成)
$
3.切换前台和后台
除了使用&运行一个后台程序外,还可以切换一个前台进程到后台,但是前台进行的时候 ,shell不能建立新的命令,我们可以通过悬挂前台进程来获得命令,悬挂键ctrl+z。
提示:我们可以利用stty命令来决定哪个键实现哪个功能。如:stty -a
当一个前台被悬挂后,就可以输入命令了,通过bg命令可以运行被悬挂的进程,通过fg命 令可以在前台运行
4. 下面我先介绍bg命令:
假设你运行一个程序:
$ long_runging_process
按下ctrl+z
这样前台进程就会被终止,我们如何在后台重新开始这个任务呢,看:
$bg
这样进程就在后台进行了,如果我们要同时悬挂多个进程,我们可以用%作为前缀的任务 号
5.切换后台进程到前台(fg)
我们只要用%作为前缀,后面加上任务号即可
例如:$ fg %1
6.保持后台进程(nohup命令)
要在后台使用nohup的进程,代码如下:
$ nohup ls &
它会被自动重定向到nohup.out的文件中
shell编程第四讲(灵魂の低调)
今天是学shell编程前基础的最后一讲了。
列出和终止进程
1.jobs命令
使用这个命令可以显示哪些进程被悬挂,哪些在后台运行。当然由于jobs命令是一个前台 进程,所以无法显示前台进程。显示后我们可以用fg和bg命令来操作他们,这在第三讲已 说过,不再重复。
2.ps命令
这也是一个可以显示所有运行中的进程的命令ps(process status的缩写),缺省状况下, 它能显示所有正在运行的进程
该命令语法格式如下:
ps [选项]
下面对命令选项进行说明:
-e 显示所有进程。
-f 全格式。
-h 不显示标题。
-l 长格式。
-w 宽输出。
a 显示终端上的所有进程,包括其他用户的进程。
r 只显示正在运行的进程。
x 显示没有控制终端的进程。
我这里介绍的比较简单,具体的大家可以查资料。
3.关闭进程(kill命令)
$ kill &任务号
4.父进程和子进程
我们知道的进程标识符是pid,而父进程标识符是ppid,系统中每一个用户进程都有父进程
他们的关系是管理和被管理的关系,当父进程终止时,子进程也随之而终止。但子进程终 止,父进程并不一定终止。
shell编程第五讲(灵魂の低调)
变量的操作
在shell编程中,我们用到两种变量:标量变量和数组变量
一.标量变量
定义格式:name=value
1.变量名
变量的名称只能包含字母,数字和下划线,且第一个字符只能是字母或下划线
2.变量值
你可以分配任何值到变量中(记住赋值中不能加空格符号)如:$name=ling hun di diao
这个就是错误的。
3.访问变量
例如:$name=hacker
$echo $name
hacker
这个例子中,shell首先确定变量name被引用,继而开始寻找name的值,最后用echo打印 出来
二.数组变量
1.建立数组变量
格式:name[index]=value
2.访问数组的值
一个数组变量的值可以通过:${name[index]}
例如:
$name[0]=hacker1
$name[1]=hacker2
$ echo ${name[1]}
结果为:hacker2
访问数组中的所有元素可以用命令: $ {name}或者$ {name[@]}
三.只读变量(变量被定义后不能再修改或去掉)
我们用命令readonly标为只读
例如: $name=hacker
$ readonly name
$echo $name
hacker
$ name=hacker3
执行最后一条命令会报错!!
四.删除变量
命令:unset
如:删除 name变量则该如此:unset name
不过有一点得记住 unset命令不能删除只读变量
shell编程第六讲(灵魂の低调)
环境和shell变量
当shell运行一个程序时,它传递给这个程序的一组变量称为环境,在环境中的每一个变量都被称为环境变量
1.输出环境变量
命令:export name
由name指定的变量被放置在环境里,输出变量表示为:
name=value;export name
注意:单个export命令可以用来输出多个变量。
2.shell变量
shell变量是指shell初始化的时候设定并内部运用的变量
变量名有:PWD,UID,SHLVL,REPLY,RANDOM,SECONDS,IFS,PATH,HOME
具体用法大家可以在网上自行搜索!
环境和shell变量就这么多
现在留个问题给大家:环境变量和局部变量有什么区别?
shell编程第七讲(灵魂の低调)
文件名置换
最常用到的置换就是文件名称的置换或通配。
一.元字符 *
简单的文件名置换就是*号,这里*代表0个或多个任意字符。
如:$ ls * 会列出当前目录下的所有文件。
1.匹配一个前缀
为了匹配一个文件前缀,可以这样使用*:
cmd aa*
其中cmd是指一个命令名,aa是匹配的文件夹前缀
如:我们要列出当前目录下以CGI开头的文件名,可以这样,$ls CGI*
2.匹配一个后缀
cmd *aa,方法与上述类似,不多解释
3.匹配前缀和后缀
cmd aa*bb
注意点:通配符是大小写敏感的。
二.元字符 ?
元字符*有个限制就是它匹配0个或多个字符,那么有时我们要是只想匹
配一个字符该怎么办?那就要用到元字符?
例如:$ ls ch??.doc
结果为:ch01.doc ch02.doc ch03.doc
三.匹配字符集合
用*和?有潜在的问题:不能匹配字母或数字,那么我们可以用[]这对元字符
语法如下:
cmd [chars] chars是字符集合
四.字符的范围
1.0-9
2.a-z
3.A-Z
五.取消一个集合
操作语法:
cmd [!chars]
例如:列出不以字母a开头的文件名: $ls [!a]
shell编程第八讲(灵魂の低调)
变量置换
有两类高级变量置换
1.当一个变量获取一个值时,发生动作
2.当一个变量失去一个值时,发生动作
1.缺省值置换:
语法:
$ {aa:-word}其中,aa是变量的名称,word是缺省值,而且当aa没有值时,置换才会发生。word也不会传给aa,只会代替表达式
例如:
unset fruit
fruit=${aa:-pear}
echo aa is $aa,fruit is $fruit
结果:fruit is pear
2.缺省值赋值
语法:
${aa:=word}
例如:
unset fruit
echo fruit is $fruit
结果: fruit is
unset furit
echo fruit is ${fruit:=apple}
结果是:fruit is apple
3.空值错误
有时,置换或赋值可能隐藏shell脚本中的问题,可以采用这个方法,在一个变量未赋值时,输出错误信息到STDERR.语法如下:
$ {aa:?msg}
4.有值置换
用法:
${aa:+word}