Linux Shell 程序设计 笔记

shell是UNIX/Linux系统的一个重要层次,它是用户与系统交互的界面;

1.shell 概述

1.1shell的特点和主要版本

特点:

  1. 对已有的命令进行组合;
  2. 提供文件名扩展字符;
  3. 可直接使用shell内置命令;
  4. 允许灵活地使用数据流;
  5. 程序模块结构化;
  6. 能在后台执行;
  7. 提供可配置环境;
  8. 提供一个高级命令语言;

种类:

  1. Bourne shell(sh)
  2. C shell(csh)
  3. Korn shell(ksh)
  4. Bourne Again shell(bash)

1.2 简单shell程序示范

#!/bin/bash 

if test $#=0
then ls 
else 
    for i
    do 
        ls -l $i|grep `^d`
    done
fi

1.1.3shell脚本的建立和执行

建立:编辑器(如vi);
执行:

  1. 输入定向到shell脚本;
    $bash < 脚本名
  2. 以脚本名作为bash参数;
    $ bash 脚本名 [参数]
    特点:可在脚本名后带参数,从而将参数值传递给程序中的命令;(如函数的调用)
  3. 将shell脚本的权限设置为可执行;
    /*1.更改权限*/
    $ sudo chmod 777 文件名
    /*2.将该脚本所在目录添加到命令搜索路径(PATH)中*/
    $ PATH=$PATH:
    /*3.执行还文件*/
    $ 文件名

2.命令历史

2.1 显示历史命令

语法:history [option][arg...]

  1. 不带参数
    显示所有历史命令清单
  2. 带一个整数X
    显示历史表中最后X行
  3. 带一个文件名X
    将X作为历史文件名
  4. 常有选项
    -a 在历史文件中添加“新”历史命令行;
    -n 从历史文件中读取尚未读入的历史命令行,添加到当前历史清单中;
    -r 读取历史文件的内容,并把它作为当前历史命令;
    -w 把当前历史文件写到历史文件中,覆盖原有内容;
    -c 删除历史清单中的所有项

2.2 执行历史命令

执行历史命令是命令替换方式之一,以“!”开头;

格式 意义
!! 重复上一条命令,也就是“!-1”
!n 重复执行第n条命令
!-n 重新执行倒数第n条历史命令
!string 重新执行以字符串“string”开头的最近的历史命令行
!?string? 重新执行最近的、其中包含字符串string的那条历史命令
!# 在现在为止所输入的整个命令行

2.3 配置历史命令环境

在默认方式下,bash使用用户主目录下的文件“.bash_history”来保存命令历史;
更改:$ HISTFILE="路径"更改后则存放在该“路径”下;

历史文件保留的命令有限,其默认值为500;
更改:$ HISTSIZE=600

3.命令补全

Tab键

4.别名

4.1 定义别名

语法格式:alias [name[=value]]...
注:alias 后面没有指定参数——显示别名清单;

//例:
$alias ..='cd ..'//定义别名,需把代表内容有单引号括起
//注:赋值号"="两边不能有空格;

4.2 取消别名

语法格式:unalias name..

5.shell 特殊字符

5.1通配符

一般通配符

  • *(星号)——匹配任意字符的0次或多次出现;
    注:文件名前面的圆点(.)和路径名中的斜线(/)必须显式匹配;
    例:“f*”可匹配“f,fa,f1等”
    “*file” 不可匹配“.profile”,“.*file” 才可匹配“.profile”
    “/ect*.c”不能匹配“/ect/”目录下有后缀“.c”的文件;
    “/ect/*.c”可以;
  • ?(问号)——匹配任意一个字符;
  • [字符组]——匹配该字符组所限定的任何一个字符;
  • !(惊叹号)——否定

模式匹配

  • *(模式表)——匹配给定模式表中0次或多次出现的模式;
  • +(模式表)——匹配给定模式表中一次或多次出现的“模式”;
  • ?(模式表)——匹配模式表中任何一种0次或1次出现的”模式“;
  • @(模式表)——仅匹配模式表中给定一次出现的”模式“;
  • !(模式表)——除给定模式表中的的一个模式外,它可以匹配其他任何东西;

5.2 引号

三种:单引号、双引号和倒引号;

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 20170514日 星期日 23:11:32 CST

倒引号还可以嵌套使用,嵌套使用时内层倒引号必须用反斜线(\)将其转义;

//例
$Nuser=`echo The number of users is \`who | wc -l\``
$echo $Nuser
The number of users is 1

补充:反斜线(\)是转义字符,能把特殊字符变成普通字符;

5.3 输入/输出重定向

执行shell文件,通常打开三个标准文件:标准输入文件(stdin)、标准输出文件(stdout)和标准出错输出文件(stderr);分别对应键盘、屏幕和屏幕终端;

a.输入重定向

输入重定向符“<”,作用:把命令(或可执行程序)的标准输入重新定向到指定文件;

形式:命令 < 文件名

b.输出重定向
输出重定向符”>”,作用:把命令(或可执行程序)的标准输出重新定向到指定文件;

注:

  1. 该命令输出不显示在屏幕上,而是写入文件中;
  2. 若多个命令的输出都定向同一个文件,那么只有最后输出结果保留在文件中;
  3. 若定向到不存在的文件上,将会创建一个新文件;

形式:命令 > 文件名

c.输出附加重定向

输出重定向符”>>”,作用:把命令(或可执行程序)的标准输出附加到指定文件的后面;(类似追加)

形式:命令 >> 文件名

d.即时文件定向符

即使文件:由重新定向符“<<”、一对标记符以及若干输入行组成;

形式:命令 [参数]<< 标记符

作用:把预先处理的固定信息放入即时文件中,由相应命令执行时立即读取;

e.与文件描述字有关的重定向

文件描述字:每一个文件“打开”系统自动赋予的;

所以,三个标准文件的文件描述符分别是

  • 标准输入文件(stdin)——0
  • 标准输出文件(stdout)——1
  • 标准出错输出文件(stderr)——2
//例:错误重定向
命令 2> 文件名  (注:“2”和“>”之间不能有空隙)
命令 2>> 文件名
$gcc m1.c 2>errfile
//对C语言源文件m1.c进行编译,将其产生的错误信息写入到文件errfile中;

//例:标准输出和标准错误输出重定向
$command $>file
$command>file 2>$1
//上面两条等价
//其中“2>$1”,表示把标准错误输出重定向到标准输出;

5.4 注释、管道线和后台命令

a.注释

shell程序以“#”开头的正文行表示注释;以“!#”开头的,后面所跟的字符串就是所使用shell的绝对路径名;

b.管道线

管道线由竖杠(|)隔开的若干命令组成的;


//例

$ls -l $HOME | wc -l

//在管道线中,每个命令执行时都由一个独立进程;
//前一个命令的输出是下一个命令的输入;
//“过滤器”,首先读取输入,然后将输入以某种简单方式进行变换,再将处理结果输出;
//grep、tail、sort和wc等均是过滤器

c.后台命令

系统执行方式:前台方式、后台方式:
前台:输入命令后立即执行;执行过程中用户与系统可以发生交互作用——用户输入数据;
后台:执行花费时间长,放置后台执行;方式:$gcc m1.c&

5.5 命令执行操作符

a.顺序执行

由上到下,由左到右,“;”分割;

b.逻辑与

逻辑与操作符“&&”把两条命令联系在一起;

一般形式:命令1 && 命令2

说明:先执行命令1,成功后才执行命令2;命令执行成功其返回值为0,不成功返回非0;

c.逻辑或

逻辑或操作符“||”把两条命令联系在一起;

一般形式:命令1 || 命令2

说明:先执行命令1,若不成功才执行命令2;否则,若命令1执行成功,则命令2不执行;命令执行成功其返回值为0,不成功返回非0;

5.6 成组命令

a.{}形式
b.()形式

两种形式、作用相同;

区别:用{}括起来的成组命令只在本shell内执行,不产生新的进程;而用()括起来的成组命令是在新的shell内执行,是要建立新的子进程;所以使用()不会改变父shell的变量值及工作目录;

6.shell变量

环境变量:永久性变量,其值不会随脚本的执行结束而结束;
临时变量:在shell内部定义,使用范围在其脚本内,随着脚本的存在而存在;

6.1 用户定义的变量

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.$(命令表)

6.2 数组

bash只提供一维数组,并且没有限定数组大小;

//显示声明
declare -a 数组名

//赋值
//单一赋值
数组名[下标]=值
//组合赋值
数组名=(值123 …… 值n)

//读取
${数组名[下标]}

注: 1.没有下标,则默认表示下标表示为0的数组元素;
2.使用*或@作为下标,则代表所有元素;
3.使用命令 unset 可以取消一个数组的定义;

6.3 变量的引用

有效的变量引用表达式有以下形式:

$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中已经设置的元素的个数。

6.4 输入/输出命令

a.read命令

从键盘读数据

形式:read 变量1~【变量2 ...】(说明:“~”表示多数据时,使用空格或制表符隔开)

三种情况:

  1. 一对一;
  2. 一对多;
  3. 一对0;

b.echo命令

显示数据

如echo带-e选项的话,那么在其后的参数中可以有以下转义字符;
\a 响铃警报;
\b 退一个字符位置
\c 光标不换行

如echo带-n选项的话:
\e 转义字符
\f 换页
\n 显示换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ 显示\
\m 是一个1、2或3位的八进制;
\xm 是一个1、2或3位的十六进制;

6.5 位置参数

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命令为位置参数赋值或重新赋值;

6.6 移动位置参数

每执行一次shift命令,就把命令行上的实参向左移一位,即相当于位置参数向右移动一个位置。

命令行: ex7 A B C D E F

原位置参数 0 1 2 3 4 5 $6

移位后: 0 1 2 3 4 5

shift命令不能将 0shift 0的值不会发生变化。

shift命令可以带有一个整数作为参数

6.7 预先定义的特殊变量

  1. $# 表示命令行上的个数;
  2. $? 表示上一条命令执行后的返回值;
  3. $$ 表示当前进程的进程号;
  4. $! 表示上一个后台命令对应的进程号;
  5. $- 是由当前shell设置的执行标志名组成的字符串;
  6. $* 表示在命令行中实际给出的所有实参字符串;
  7. $@ 同上

6.8 环境变量

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

6.9环境文件

bash的环境文件包括.bash_profile文件、.bashrc文件、.bash_logout文件等;

在.bash_profile中,设置了环境变量和文件掩码(umask) 名为.bashrc的脚本,每次启动bash时便会执行它。它只含有针对bash的命令,可以用来设置别名;

.bashrc在.bash_profile之后执行;

.bash_logout,它仅在退出注册的时候运行;

6.10 export语句与环境设置

你可能感兴趣的:(Linux)