资源描述
#!/bin/sh
第一某些 UNIX和SHELL工具
[1] 四、使用文献
ls
ls –F 用附加字符来标示列出来条目文献类型。
ls –d 只显示目录名字,不显示它内容。
mkdir –p /dir1/file1 如果父目录不存在,创立父目录
cat
cat –n file1 输出每一行带编号
cat –b file1 输出空白行不编号
wc
参数: -l 记录行数
-w 记录单词数
-m 记录字符数 linux中没有
-c 记录字符数 linux中有
cp
cp src1 … srcN dest 拷贝各种文献
cp –i file1 file2 交互模式,覆盖会提问
cp –r dir1 dir2 拷贝目录
mv
mv src1 … srcN dest 移动各种文献
mv –i file1 file2 交互模式,覆盖会提问
rm
rm –i file1 交互模式,覆盖会提问
[2] 五、输入与输出
1、输出到终端
echo
echo str 输出str
echo命令使用转义序列(在ksh中有效,bash中无效)(该转义序列也可用于printf)
\n 打印换行
\t 打印tab字符
\c 背面不默认跟随换行,打印一种字符串
echo “Your fruit basket contains:\napple orange pear”
printf
printf命令要在字符串后输出换行,必要在所要打印字符串后明确指定\n转义序列,而echo命令会自动打印出换行。
e.g. echo “Is that a mango?” 等于 printf “Is that a mango?\n”
printf 基本语法
printf format arguments
format格式序列形式如下:
%[-]m.nx
%标示格式序列开始,x指明格式序列类型,下表给出了x也许得值
字母
描述
字母
描述
s
字符串
o
八进制数
c
字符
e
指数浮点数
d
十进制整数
f
固定浮点数
x
十六进制数
g
紧密浮点数
依照x值不同,整数m和n有不同解释。普通,m是域最小长度,而n是域最大长度。如果你指定一种实数,n就被作为应当用到精度,连字符 – 表在左边对齐一种域。默认状况下,所有域都是在右边对齐.
e.g. printf “%-16s\t%-16s\n” “Name” “User Name”
表达左对其,输出被分隔为两列,每16个字符长度被空格分隔开。
2、输出重定向
cmd > file
可以将命令列表输出重定向
e.g. { date ;uptime ;who ;} > mylog
cmd >> file 追加到文献
cmd | tee file 将输出从定向到文献和屏幕,使用tee 命令
e.g. date | tee now 输出到屏幕同步写入文献now
3、输入重定向
cmd < file
cmd << delimiter
shell将操作符<<解释为如下指令:shell读取顾客输入,直到遇到某一行,其中包括指定delimiter。直到浮现包括delimiter行,前面所有输入行都作为命令cmd原则输入。delimiter必要是不涉及空格或tab单词。
e.g. cat > file1 <<MYURLS
MYURLS
输入MYURLS后,退出
4、读取顾客输入
read name
该命令读取顾客输入,直到顾客按回车键,命令将把输入字符串分派到name指定变量。
| 管道
e.g. ps –ael |grep “$UID” |more
5、文献描述符 ,也叫文献句柄
3个原则文献描述符
当执行任何命令时,3个文献被打开并和该命令有关联。3个原则文献描述符如下
阐明
文献名
文献描述符
原则输入
STDIN
0
原则输出
STDOUT
1
原则错误
STDERR
2
使用文献描述符和文献关联
能使用exec命令将任何文献和文献描述符关联
exec n>file
exec n>>file
其中n为文献描述符
e.g. exec 4>file.out 把文献file.out和文献描述符4关联起来
注意: exec 1>file.out 则所有输出都将被放到file.out中,在终端屏幕上将什么也看不见
普通输入/输出重定向
将指定命令cmd输出重定向到指定文献
cmd n> file
cmd n>> file
e.g. ls 1>file 将ls命令原则输出到file.
重定向原则输出和原则错误到单独文献
cmd 1> file1 2>file2
由于文献描述符1可以被省略,上面命令可以简化为 cmd >file1 2>file2
cmd 1>>file1 2>>file2
cmd >>file1 2>>file2
重定向原则输出和原则错误到同一种文献
cmd 1>file 2>&1 等于 cmd >file 2>&
cmd 1>>file 2>&1 等于 cmd >>file 2>&
打印消息到原则输出
echo str 1>&2 等于 echo str >&2
printf format args 1>&2 等于 printf format args >&2
重定向一种文献描述符输出到另一种文献描述符
格式为: n>&m n和m都是文献描述符,
exec n>&m 关联所有n输出到m
重定向输入来自另一种文献描述符
格式为: n<&m n和m都是文献描述符
exec n<&m 关联所有n输入到m
关闭文献描述符
exec n>-
[3] 六、操作文献属性
命名管道
mkfifo file 在这里,file是给于该管道文献名。
SUID 和 SGID
SUID 当你执行一种设立了SUID位程序时,你就继承了该程序属主权限,而没有设立SUID位程序在执行时只拥有执行该程序顾客权限。
SGID 设立了SGID位程序将以程序属主所属顾客组权限来执行。
如果一种目录设立了SGID位,任何加到该目录下新文献自动继承该目录组,来代替生成文献顾客组。
SUID 和 SGID 位以字母s和S来表达。如果文献SUID或SGID权限被激活,SUID位就在文献属主执行权限位。
e.g. ls –l /usr/bin/passwd
-r-sr-xr-x 1 root bin 19031 Feb 7 13:47 /usr/bin/passwd*
如果大写字母S代替了小写字母s,则表达该文献属主执行位没有被激活。
粘滞位
如果目录粘滞位被设立,则只有当你是如下顾客时,文献才干被删除:
设立粘滞位目录属组
要被删除文献属组
超级顾客root
粘滞位以字母t和T表达。如果大写字母代替了小写字母s,则表达该文献属主执行位没有被激活。
chmod
e.g. chmod go-w,a+x a.out
e.g. chmod –R o+r pub 变化pub目录及其子目录下所有文献权限
使用8进制办法设立SUID和SGID位时,把这些位数值放在原则权限位前面,SUID和SGI分别取数字4和2。
e.g. chmod 2444 *
[4] 七、进程
切换前台进程到后台 bg
e.g. bg %2 切换2号任务进程到后台
切换后台进程到前台 fg
e.g. fg %2 切换2号后台任务进程到前台
保持后台进程 nohup
e.g. nohup ls &
等待后台进程结束 wait
此命令会等待所指定任务或者进程执行完毕。
wait命令有3种形式:无选取(缺省) 等待所有进程结束,
通过进程ID e.g. wait 15060 等待15060进程结束
通过百分号%作为前缀任务号 e.g. wait %2 等待2号任务
显示后台任务 jobs
该命令显示哪些进程被悬挂,哪些在后台运营。
e.g. jobs
[3] + Running first_one &
[2] – Stopped (SIGTSTP) second_one
[1] Stopped (SIGTTIN) third_one &
任务3正在运营;任务2是一种前台进程,被Ctrl+Z进行悬挂;任务1是一种后台进程,正在等待键盘输入
列出所有运营进程 ps
UID 进程所有者; PID 进程标记符 ;PPID 父进程标记符;C 进程CPU占用率
STIME 进程开始时间; CMD 开始进程命令
关闭进程 kill
e.g. kill %1 关闭任务号为1进程
subshell 概念
当你运营一种shell脚本时候,除了脚本中命令之外,另一种shell解释器拷贝也会产生。设个新shell被称为subshell。
覆盖当迈进程 exec
该命令可以用一种新进程来覆盖当迈进程。使用时要务必小心!!!
可以exec来彻底更改你shell解释器而不需要此外产生subshell。 e.g. exec csh
第二某些 SHELL编程
[5] 八、变量
标量变量
一次只能被赋予一种值
变量名
只能包括字母、数字和下划线 _ 。只能以字母或下划线作为开始。
变量值
可以存储或分派任何值到变量中。
带空格变量值需要用单引号或双引号引起来。 E.g. ¥ FRUIT=”apple orange plum”
访问变量
要获取变量值,只要在变量名之前加上美元符号$作为前缀即可
建立数组变量
办法一: 直接给一种索引赋值,格式为 name[index]=value
e.g. $ FRUIT[0]=apple ;FRUIT[1]=banana ;FRUIT[2]=orange
办法二:在 ksh中为 set –A name value1 value2 … valueN
e.g. $ set –A band derri terry mike gene
在bash中为 name=(value1 … valueN)
e.g. $ band=(derri terry mike gene)
在bash中设定多重数组元素,需要在赋值之前建立一种数组索引:
e.g. $ myarray=([0]=derri [3]=gene [2]=mike [1]=terry)
数组索引不必安装顺序
注意:索引必要是一种整数
如果一种数组变量名和一种已经被定义了标量变量名重名,那么标量变量值就变成了数组变量中索引0值。
访问数组值
办法为: ${name[index]}
e.g. $ echo ${FRUIT[2]}
使用 ${name[*]} 和 ${name[@]} 可以访问数组中所有项目
${name[*]}以为实际有几种索引就与否几项
${name[@]}以为实际有几种索引项加上空格分开项目
e.g. $ FRUIT=(apple banana “orange passion”)
${name[*]}以为有3项
${name[@]}以为有4项
只读变量 readonly
变量可以通过readonly命令被标记为只读.可用来标记数组或标量变量为只读
e.g. $ FRUIT=kiwi ;readonly FRUIT
删除变量 unset
格式: unset name
e.g. $ unset FRUIT
只读变量是无法被删除,它将始终保持到shell退出为止。
输出环境变量
办法一: name=value ;export name
办法二: export name=value
shell 变量
是在shell初始化时被设定并内部运用变量。
附录:惯用shell变量
$PWD 指出当前工作目录
$UID 指出当前顾客数字顾客标示符
$SHLVL 每次bash打开一种历程就自动加1,这个变量作用在于拟定内建exit命令与否关闭了当前会话。
$REPLY 若不给定参数,会让read命令读到输入最后一行
$RANDOM 产生0到32767随机数
$SECONDS 返回shell启动秒数。
$IFS shell使用该变量IFS值把一种字符串分隔为单独词。IFS默认设立是空格和tab键.
e.g. dirs() {
OLDIFS=”$IFS”
IFS=:
for I in $_DIR_STACK
do
echo “$I \c”
done
echo
IFS=”$OLDIFS”
}
$PATH 搜索途径
$HOME 当前顾客主目录。
附录:特殊变量
$?
上一条命令退出状态保存在变量$?中,为0表达到功,非0表达失败可以用变化量来检测 一条命令与否执行成功。
e.g. if [ $?–eq 0 ] ;then
echo “Command was successful.”;
else
echo “An error was encountered.”
exit
fi
$-
专用变量$-是一种包括所有shell选项列表。检查$-与否包括字母i是判断shell是运营在交互模式下还是非交互模式下最简便办法。
e.g. case $- in
*i*)
PS1=”’uname –n’$ “
PATH=”$PATH:$HOM#/bin”
Export PS1 PATH;;
Esac
$PS3
变化脚本运营提示符
e.g PS3=”New prompt” ;export PS3;
注意shell变量PS3把空格也作为最后一种字符。
[6] 九、置换
元字符* 匹配0到各种任意字符
匹配一种前缀
cmd prefix*
匹配一种后缀
cmd *suffix
匹配前缀和后缀
cmd prefix*suffix
元字符? 匹配1个任意字符
如果shell不能发现任何文献名可以匹配包括一种?元字符表达式,shell就会把?看作文献名中字符。由于这个因素,如果一种shell脚本使用匹配文献名作为参数,则需要验证文献与否存在,以免出错。
匹配字符集合 cmd [char]
匹配字符范畴
e.g. ls ch0[0-9].doc ;ls [a-zA-Z]*
取消一种集合,即不涉及一种集合 !
cmd [!char]
e.g. $ ls [!a]* 列出不以a开头文献名
高档变量置换
有两大类高档变量置换:
1、 当一种变量获得一种值时,发生动作
2、 当一种变量失去一种值时,发生动作
名称
语法
描述
缺省值置换
${param:-word}
如param值为空或未赋值,word取代param,但param值不变
缺省值赋值
${param:=word}
如param值为空或未赋值,word被赋给param
空值错误
${param:?msg}
如param值为空或未赋值,将msg信息输出到STDERR,并退出shell
有值置换
${param:+word}
如param有值,word取代param值,但param值不变
e.g. FRUIT=${MYFRUIT:-APPLE}
命令置换 (用反引号 `)
`command`
shell执行命令集合,然后将命令输出成果置换。注意使用是反引号`
e.g. UP=`date ;uptime`
e.g. grep `id –un` /etc/passwd
算式置换
$((exp))
exp为一种数学表达式,可以使用/ * - + ()。
返回值不是四舍五入;在小数点后任何值都会被丢弃。
e.g. $ echo $(( ((5+3*2)-4)/2 ))
注意 最前面2个左括号中不可有空格,最背面2个有括号中也不可有空格。
[7] 十、引用
关闭对特殊字符含义解析解决被称为引用
需要引用解决元字符如下: * ? [ ] ‘ “ \ $ ;& ( ) |^ !#
使用反斜线 \
使用反斜线 \可以使一种特殊字符被引用
e.g. echo A:\\ is my floppy drive
使用单引号 ‘
在字符串先后使用单引号,可以使整个字符串被引用
单引号必要成对浮现
e.g. echo ‘<-$1250.**>;(update?) [Y|N]’
使用双引号 “
禁止除了$和’以外所有元字符。因而可以引用变量。
双引号中反斜线可以起作用,只在下面4个符号之前起作用 $ ‘ “ \
引用解决换行以在下一行中继续
e.g. echo 12345\
>67890
输出为
e.g. echo ‘Line 1
>Line 2’
输出为 Line1
Line2
引用解决正则表达式通配符
e.g. grep ‘[0-9][0-9]*$’ report2 report7
注意:象find等命令,通配符必要使用单引号、双引号或反斜线进行引用解决,这样通配符才干传递给find而不会被shell将其扩展开。
[8] 十一、流控制
if语句
if语法
代码返回0表达真,而非0为假。语法如下:
if list1
then
list2
elif list3
then
list4
else
list5
fi
也可写成一行:
if list1 ;then list2 ;elif list3 ;then list4 ;else list5 ;fi ;
常用错误
在单行形式中 then语句前面忽视了分号
使用test
文献测试
语法: test option file 或 [ option file ]
option为下表中一种选项, file 是一种文献或目录名字
选项
描述
-b file
当file存在并且是块文献时返回真
-c file
当file存在并且是字符文献时返回真
-d pathname
当pathname存在并且是目录时返回真
-e pathname
当由pathname指定文献或目录存在时返回真
-f file
当file存在并且是正规文献时返回真
-g pathname
当由pathname指定文献或目录存在并且设立了SGID位时返回真
-h file
当file存在并且是符号联接时返回真
-k pathname
当由pathname指定文献或目录存在并且设立了粘滞位时返回真
-p file
当file存在并且是命名管道时返回真
-r pathname
当由pathname指定文献或目录存在并且可读时返回真
-s file
当file存在并且是文献大小不不大于0时返回真
-u pathname
当由pathname指定文献或目录存在并且设立了SUID位时返回真
-w pathname
当由pathname指定文献或目录存在并且可写时返回真
-x pathname
当由pathname指定文献或目录存在并且可执行时返回真
-o pathname
当由pathname指定文献或目录存在并且被当迈进程有效顾客ID所指定顾客所拥有时返回真
字符串比较
检查字符串与否为空 –n -z
语法: test -z str 或 [ -z str ]
str 是要检测字符串。当str长度为0时返回真。
语法: test -n str 或 [ -n str ]
str 是要检测字符串。当str长度为非0时返回真。
e.g. if [ -z “$FRUIT_BASKET”] ;then
echo “Your fruit basket is empty”
else
echo “Your fruit basket contains :$FRUIT_BASKET”
fi
注意:str必要被引号括起来,否则str会被shell变量置换,而无法交给test。因此 这里为 [ -z “$FRUIT_BASKET”]
字符串相等
语法: test str1=str2 或 [ str1 = str2 ]
e.g. if [ “$portmap” = “YES” ] ;then …
if [ X$portmap =X“YES”] ;then …
注意上述2个例子都可以防止由于$portmap为空而报
字符串不等
语法: test str1 != str2 或 [ str1 != str2 ]
e.g. if [ “$portmap” != “YES” ] ;then …
if [ X$portmap !=X“YES”] ;then …
注意上述2个例子都可以防止由于$portmap为空而报错
数字比较
语法: test int1 op int2 或 [ int1 op int2 ]
int1和int2可以是任何正整数或负整数,op为下表中一种操作符。如果int1或int2是一种字符串而不是整数,它就被作为0来对付。
操作符
描述
int1 –eq int2
如果int1等于int2,返回真。 也可用 = 符号
int1 –ne int2
如果int1不等于int2,返回真
int1 –lt int2
如果int1不大于int2,返回真
int1 –le int2
如果int1不大于等于int2,返回真
int1 –gt int2
如果int1不不大于int2,返回真
int1 –ge int2
如果int1不不大于等于int2,返回真
上一条命令退出状态保存在变量$?中,为0表达到功,非0表达失败可以用变化量来检测 一条命令与否执行成功:
e.g. if [ $?–eq 0 ] ;then
echo “Command was successful.”;
else
echo “An error was encountered.”
exit
fi
复合表达式
用内建操作符创立复合表达式
语法: test expr1 op expr2 或 [ expr1 op expr2 ]
expr1 和 expr2 是任何有效test表达式,op为-a 或 -o。
expr1 –a exprt2 表达 expr1 和 expr2都为真时返回真
expr1 –o exprt2 表达 expr1 或 expr2都为真时返回真
用条件操作符创立复合表达式
语法: test expr1 op test expr2 或 [ expr1 ] op [ expr2 ]
expr1 和 expr2 是任何有效test表达式,op为 && 或 ||。
&& 表达 expr1 和 expr2都为真时返回真
|| 表达 expr1 或 expr2都为真时返回真
使用条件操作符能提高效率,推荐使用。
否定一种表达式
语法: test !expr 或者 [!expr ]
expr是任何有效test表达式
case语句
语法如下: case word in
pattern1)
list1
;;
pattern2)
list2
;;
…
patternN)
listN
;;
esac
或
case word in
pattern1) list1 ;;
…
patternN) listN ;;
esac
e.g. case $- in
*i*)
PS1=”’uname –n’$ “
PATH=”$PATH:$HOM#/bin”
Export PS1 PATH;;
Esac
专用变量$-是一种包括所有shell选项列表。检查$-与否包括字母I是判断shell是运营在交互模式下还是非交互模式下最简便办法。
[9] 十二、循环
while循环
while循环语法
while cmd
do
list
done
或 while cmd ;do list ;done
这里,cmd表达一种单一命令(普通是test表达式),而list表达一种或各种命令列表。
执行环节:1、执行cmd。
2、如cmd退出状态为非0,则退出循环。
3、如cmd退出状态为0,则执行list。
4、当list结束时,回到第一步
应用:while合法顾客输入
RESPONSE=
while [ -z “$RESPONSE” ] ;
do
echo “Enter the name of a directory where your files are located:”
read RESPONSE
if [!–d “RESPONSE” ] ;then
echo “ERROR:please enter a directory pathname. “
RESPONSE=
Fi
done
应用:输入重定向和while结合,从文献中一次读出一行
语法如下: while read LINE
do
:# manipulate file here
done < file
while和子shell间变量传递 ?????????
当while循环结束时,循环内变量不被保存。解决办法是当进入循环时重定向STDIN指针,然后在结束时恢复STDIN。语法如下:
exec n<&0 < file
while read LINE
do
:# manipulate file here
done
exec 0<&n n<&-
这里,n是一种不不大于2整数,file是你想要读取文献名。
e.g. 构造一种cat命令shell版本,如下所示:
#!/bin/sh
if [ “$#” –ge 1 ] ;then
for FILR in $@
do
exec 4<&0 < “$FILE”
while read LINE ;do echo $ LINE ;done
exec 0<&4 4<&-
done
fi
until 循环
while循环非常适合于当某条件为真时执行命令;而until适合执行命令,直到条件为真。
until循环相称于用!操作符对cmd成果取反while循环。不推荐使用。
until语法
until cmd
do
list
done
for循环
for循环语法
for name in word1 word2 … wordN
do
list
done
或 for name in word1 word2 … wordN ;do list ;done
for循环用于使你能对列表中每一项重复执行一系列命令。
select循环
select循环提供了一种简朴方式来创立一种顾客可选取有限菜单。
select 循环语法
select name in word1 word2 … wordN
do
list
done
循环控制
break命令
break命令表达退出当前循环。
break命令也可以接受一种整数作为参数,不不大于等于1整数,标记着退出循环层数。
e.g. 例如有3层循环。break 2 表达退出2层;break 3则退出3层。
continue命令
退出循环当前重复过程,而不是整个循环。
[10] 十三、参数
特殊shell变量 $0 $n $# $* $@ $?$$ $!
变量
描述
$0
被执行命令名字。 对于shell脚本来说,这就是调用它途径。
$n
这些变量相应是被一种脚本调用参数。这里n是一种十进制正数,相应是参数位置。 e.g. 第一种参数是$1,第二个参数是$2,以此类推。
$#
脚本支持参数个数
$*
所有参数被双重引用。如果脚本接受到两个参数,$*等于$1 $2
$@
所有参数都被独立地双重引用。如果一种脚本接受到两个参数,$*等于$1 $2
$?
最后一种被执行命令退出状态。
$$
当前shell进程号。对于shell脚本来说,这就是她们执行进程号。
$!
最后一种后台命令进程号。
shift命令
语法: shift [n]
After a shift n,all parameters in $* are moved to the left n positions,and $# is decremented by n. The default for n is 1.The shift command does not affect the positional parameter 0.
basename
命令basename获得一种文献或者目录绝对或者相对途径,仅仅返回该途径下面文献或目录名。
e.g. #!/bin/sh
case `basename $0` in
listtar) TARGS=”-tvf $1”;;
maketar) TARGS=”-cvf $1.tar $1”;;
*) echo “Usaged:$0 [file|directory]”
exit 0
;;
esac
tar $TARGS
仿效basename(用于没有basename命令系统)脚本
#!/bin/sh
if [ -n “$1”] ;then
echo “$1” | sed –e ‘s/^.*\///’
else
echo “Usage:basename [file] “ 1>&2
exit 1
fi
exit 0
检查变元数目与否与规定数目匹配 $#应用举例
#!/bin/sh
USAGE=”Usage:`basename $0` [-c|-t] [file|directory]”
If [ $# -lt 2] ;then
echo “$USAGE”
exit 1
fi
case “$1” in
-t) TARGS=”-tvf $2” ;;
-c) TARGS=”-cvf $2.tar $2” ;;
*) echo “$USAGE”
exit 0
;;
esac
tar $TARGS
$*和$@区别
为shell脚本指定变元被存在两个特殊变量$*和$@中。这两个变量之间差别在于如何存储变元: $*不保存引用,而$@则保存。
getopts命令
getopts语法格式如下:
getopts option-string var
这里option-string是一种字符串,它涉及了getopts所应当考虑所有单个选项字符。var是该选项应当被设立变量名字。推荐,var处用一种名为OPTION变量。
getopts对命令行中给出选项进行解析环节如下:
1 getopts检查所有命令行参数,查找以 – 字符开头参数。
2 当发现一种以 – 字符开头参数时,它比较 – 之后紧接着字符与给定 option-string中所有字符。
3 如果发现该字符在 option-string中有匹配,则把该选项字符赋予变量var;否则,var值设立为?字符。
4 重复 1~3,直到命令行中给出所有选项都被检查完。
5 当完毕后,getopts返回一种非0退出码。此外,它将变量OPTIND值设立为最后一种参数下标。
getopts可以指出哪些选项规定附带参数
通过在选项背面附加一种冒号 :字符来实现。在这种状况下,解析一种选项后,附带参数就会设立为变量OPTARG值。
getopts举例
脚本如下:
#!/bin/sh
USAGE="Usage:`basename $0` [-v] [-f] [filename] [-o] [filename]";
VERBOSE=false
while getopts f:o:v OPTION:
do
case "$OPTION" in
f) INFILE="$OPTARG";;
o) OUTFILE="$OPTARG";;
v) VERBOSE=true;;
\?) echo "$USAGE"
exit 1
;;
esac
done
shift 'echo "$OPTIND -1"|bc'
if [ -z "$1" ] && [ -z "$
展开阅读全文