shell是UNIX/Linux系统的一个重要层次,它是用户与系统交互的界面;
特点:
种类:
#!/bin/bash
if test $#=0
then ls
else
for i
do
ls -l $i|grep `^d`
done
fi
建立:编辑器(如vi);
执行:
$bash < 脚本名
$ bash 脚本名 [参数]
/*1.更改权限*/
$ sudo chmod 777 文件名
/*2.将该脚本所在目录添加到命令搜索路径(PATH)中*/
$ PATH=$PATH:
/*3.执行还文件*/
$ 文件名
语法:history [option][arg...]
执行历史命令是命令替换方式之一,以“!”开头;
格式 | 意义 |
---|---|
!! | 重复上一条命令,也就是“!-1” |
!n | 重复执行第n条命令 |
!-n | 重新执行倒数第n条历史命令 |
!string | 重新执行以字符串“string”开头的最近的历史命令行 |
!?string? | 重新执行最近的、其中包含字符串string的那条历史命令 |
!# | 在现在为止所输入的整个命令行 |
在默认方式下,bash使用用户主目录下的文件“.bash_history”来保存命令历史;
更改:$ HISTFILE="路径"
更改后则存放在该“路径”下;
历史文件保留的命令有限,其默认值为500;
更改:$ HISTSIZE=600
Tab键
语法格式:alias [name[=value]]...
注:alias 后面没有指定参数——显示别名清单;
//例:
$alias ..='cd ..'//定义别名,需把代表内容有单引号括起
//注:赋值号"="两边不能有空格;
语法格式:unalias name..
一般通配符
模式匹配
三种:单引号、双引号和倒引号;
a.双引号
由双引号括起来的字符均作为普通字符对待;(”$、`、\“除外)
echo "current directory is `pwd`" //命令`倒引号
echo "home directory is $HOME"
echo "file*.?"
echo "directory '$HOME'"//变量倒引号
b.单引号
由单引号括起来的字符都作为普通字符出现;(特殊字符也失去原来的意义)
c.倒引号
带引号括起来的字符串被shell解析为命令行;在执行时先执行该命令行,并以结果代替括起部分;
//例
$today=`date`
$echo Today is $today
Today is 2017年 05月 14日 星期日 23:11:32 CST
倒引号还可以嵌套使用,嵌套使用时内层倒引号必须用反斜线(\)将其转义;
//例
$Nuser=`echo The number of users is \`who | wc -l\``
$echo $Nuser
The number of users is 1
补充:反斜线(\)是转义字符,能把特殊字符变成普通字符;
执行shell文件,通常打开三个标准文件:标准输入文件(stdin)、标准输出文件(stdout)和标准出错输出文件(stderr);分别对应键盘、屏幕和屏幕终端;
a.输入重定向
输入重定向符“<”,作用:把命令(或可执行程序)的标准输入重新定向到指定文件;
形式:命令 < 文件名
b.输出重定向
输出重定向符”>”,作用:把命令(或可执行程序)的标准输出重新定向到指定文件;
注:
形式:命令 > 文件名
c.输出附加重定向
输出重定向符”>>”,作用:把命令(或可执行程序)的标准输出附加到指定文件的后面;(类似追加)
形式:命令 >> 文件名
d.即时文件定向符
即使文件:由重新定向符“<<”、一对标记符以及若干输入行组成;
形式:命令 [参数]<< 标记符
作用:把预先处理的固定信息放入即时文件中,由相应命令执行时立即读取;
e.与文件描述字有关的重定向
文件描述字:每一个文件“打开”系统自动赋予的;
所以,三个标准文件的文件描述符分别是
//例:错误重定向
命令 2> 文件名 (注:“2”和“>”之间不能有空隙)
命令 2>> 文件名
$gcc m1.c 2>errfile
//对C语言源文件m1.c进行编译,将其产生的错误信息写入到文件errfile中;
//例:标准输出和标准错误输出重定向
$command $>file
$command>file 2>$1
//上面两条等价
//其中“2>$1”,表示把标准错误输出重定向到标准输出;
a.注释
shell程序以“#”开头的正文行表示注释;以“!#”开头的,后面所跟的字符串就是所使用shell的绝对路径名;
b.管道线
管道线由竖杠(|)隔开的若干命令组成的;
//例
$ls -l $HOME | wc -l
//在管道线中,每个命令执行时都由一个独立进程;
//前一个命令的输出是下一个命令的输入;
//“过滤器”,首先读取输入,然后将输入以某种简单方式进行变换,再将处理结果输出;
//grep、tail、sort和wc等均是过滤器
c.后台命令
系统执行方式:前台方式、后台方式:
前台:输入命令后立即执行;执行过程中用户与系统可以发生交互作用——用户输入数据;
后台:执行花费时间长,放置后台执行;方式:$gcc m1.c&
a.顺序执行
由上到下,由左到右,“;”分割;
b.逻辑与
逻辑与操作符“&&”把两条命令联系在一起;
一般形式:命令1 && 命令2
说明:先执行命令1,成功后才执行命令2;命令执行成功其返回值为0,不成功返回非0;
c.逻辑或
逻辑或操作符“||”把两条命令联系在一起;
一般形式:命令1 || 命令2
说明:先执行命令1,若不成功才执行命令2;否则,若命令1执行成功,则命令2不执行;命令执行成功其返回值为0,不成功返回非0;
a.{}形式
b.()形式
两种形式、作用相同;
区别:用{}括起来的成组命令只在本shell内执行,不产生新的进程;而用()括起来的成组命令是在新的shell内执行,是要建立新的子进程;所以使用()不会改变父shell的变量值及工作目录;
环境变量:永久性变量,其值不会随脚本的执行结束而结束;
临时变量:在shell内部定义,使用范围在其脚本内,随着脚本的存在而存在;
a.变量名
字母或下划线符打头的字母、数字和下划线符序列,并区分大小写;
b.变量赋值
一般形式:变量名=字符串
c.引用变量名
使用“$”替换;
//例1.显示变量值
$dir=/usr/meng/ff
$echo $dir
/usr/meng/ff ##显示结果
$echo dir
dir ##显示结果
//例2.变量值可作为某个长字符串的一部分
$s=ing
$echo read$s and writ$s
reading and writing
//例3.使用{}括起的变量
$dir=/usr/meng
$cat ${dir}qc/m1.c //将文件/usr/mengqc/m1.c 显示出来
//使用{}括起,以便不要混淆
d.命令替换
将命令的执行结果赋值给变量
1.命令表
,命令表使用倒引号引用命令;
2.$(命令表)
;
bash只提供一维数组,并且没有限定数组大小;
//显示声明
declare -a 数组名
//赋值
//单一赋值
数组名[下标]=值
//组合赋值
数组名=(值1 值2 值3 …… 值n)
//读取
${数组名[下标]}
注: 1.没有下标,则默认表示下标表示为0的数组元素;
2.使用*或@作为下标,则代表所有元素;
3.使用命令 unset 可以取消一个数组的定义;
有效的变量引用表达式有以下形式:
$name
${name#pattern}
${name}
${name##pattern}
${name[n]}
${name % pattern}
${name[*]}
${name %% pattern}
${name [@]}
${#@}
${name:-word}
${$#*}
${name:=word}
${# name }
${name:?word}
${# name[*]}
${name:+word}
${#name[@]}
①表达式$name表示变量name的值,若变量未定义,则用空值替换。
②表达式${name}将被变量name的值替换。用花括号括起name,目的在于把变量名与后面的字符分隔开,避免出现混淆。替换后花括号被取消。
③${name[n]}表示数组变量name中第n个元素的值。
④表达式${name[*]}和${name[@]}都表示数组name中所有非空元素的值,每个元素的值用空格分开。如果用双引号把它们都括起来,那么二者的含义就有区别:对于"${name[*]}",它被扩展成一个词(即字符串),这个词由以空格分开的各个数组元素组成;对于"${name[@]}",它被扩展成多个词,每个数组元素是一个词。如果数组name中没有元素,则${name[@]}被扩展为空串。
⑤表达式${name:-word}、${name:=word}、${name:+word}、${name:?word}的计算方法在4.7节中介绍
⑥表达式${name#pattern}和${name##pattern}
如果pattern(Shell模式)与name值的开头匹配,那么name的值去掉匹配部分后的结果就是该表达式的值;否则, name的值就是该表达式的值。在第一种格式中,name值去掉的部分是与pattern匹配的最少的部分;而第二种格式中,name值去掉的部分是与pattern匹配的最多的部分。
⑦表达式${name % pattern}和${name %% pattern}
如果pattern与name值的末尾匹配,那么name的值中去掉匹配部分后的结果就是该表达式的值;否则,该表达式的值就是name的值。在第一种格式中,去掉的部分是最少的匹配部分;而第二种格式中,去掉的部分是最多的匹配部分。
⑧表达式${#@}和${#*}
它们的值分别是由$@和$*返回的参数的个数。
⑨表达式${#name[i]}
该表达式的值是数组name第i个元素值的长度(字符个数)。
⑩表达式${#nane[*]}和${#name[@]}
它们的值都是数组name中已经设置的元素的个数。
a.read命令
从键盘读数据
形式:read 变量1~【变量2 ...】
(说明:“~”表示多数据时,使用空格或制表符隔开)
三种情况:
b.echo命令
显示数据
如echo带-e选项的话,那么在其后的参数中可以有以下转义字符;
\a 响铃警报;
\b 退一个字符位置
\c 光标不换行
如echo带-n选项的话:
\e 转义字符
\f 换页
\n 显示换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ 显示\
\m 是一个1、2或3位的八进制;
\xm 是一个1、2或3位的十六进制;
a.位置参数及其应用
命令行实参与脚本中位置变量的对应关系如下所示:
exam1 m1 m2 m3 m4
0 1 2 3 4 5 6 7 8 9 10 {11}
引用它们的方式依次是 0, 1, 2,…, 9, 10, {11}等。
其中,$0始终表示命令名或shell脚本名。
b.用set命令为位置参数赋值
在shell程序中可以使用set命令为位置参数赋值或重新赋值;
每执行一次shift命令,就把命令行上的实参向左移一位,即相当于位置参数向右移动一个位置。
命令行: ex7 A B C D E F
原位置参数 0 1 2 3 4 5 $6
移位后: 0 1 2 3 4 5
shift命令不能将 0移走,所以经shift右移位置参数后, 0的值不会发生变化。
shift命令可以带有一个整数作为参数
1.常用的环境变量
HOME:用户主目录的全路径名
LOGNAME:即你的注册名,由Linux自动设置
MAIL: 你的系统信箱的路径
PATH: shell从中查找命令的目录列表。可以设置它,如:PATH= PATH: HOME/bin
PS1:shell的主提示符。 bash默认的主提示符一般为“\s-\v$ ”。其中,\s表示shell的名称;\v表示bash的版本号PS1=”Enter Command> “
PWD:你当前工作目录的路径
SHELL:你当前使用的shell
TERM: 你的终端类型
2.使用环境变量
3.删除环境变量
unset
bash的环境文件包括.bash_profile文件、.bashrc文件、.bash_logout文件等;
在.bash_profile中,设置了环境变量和文件掩码(umask) 名为.bashrc的脚本,每次启动bash时便会执行它。它只含有针对bash的命令,可以用来设置别名;
.bashrc在.bash_profile之后执行;
.bash_logout,它仅在退出注册的时候运行;