Linux shell介绍(转)

from http://www.cnblogs.com/hzl6255/archive/2013/02/23/2923850.html

1. 关于shell

在Linux系统中,shell是用户和Linux内核之间交互的接口 
- shell是一个命令语言解释器,它拥有自己内建的shell命令集,shell也能被系统中其他应用程序所调用。 
用户在提示符下输入的命令都由shell先解释然后传给Linux内核。 
当用户在shell下执行一条命令时,shell首先检查命令是否为内部命令,若不是则在搜索路径里寻找是否是一个应用程序。 
如果键入的命令不是一个内部命令并且在路径里没有找到这个可执行文件,将会显示一条错误信息;如果能够找到命令,该内部命令或应用程序将被分解为系统调用并传给Linux内核。

- shell同时也是一个解释型的程序设计语言 
shell程序设计语言支持绝大多数在高级语言中能见到的程序元素,如函数、变量、数组和程序控制结构。 
shell编程语言简单易学,任何在提示符中能键入的命令都能放到一个可执行的shell程序中。

Linux中的shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和Korn shell(ksh)。 
Linux操作系统缺省的shell是Bourne Again shell,它是Bourne shell的扩展,简称Bash

2. Bash

Linux系统中,当用户通过终端登录时,login程序会被执行 
login会验证用户名密码,当验证通过后先初始化环境,获取登录用户shell类型并启动,然后初始化shell环境进入交互终端。

shell类型的获取是由/etc/passwd文件来决定(/bin/bash)

Fixedsys:x:500:500:Fixedsys:/home/Fixedsys:/bin/bash
Bash启动过程:

首先寻找/etc/profile脚本文件,并执行它; 
然后如果存在~/.bash_profile,则执行它,否则执行 ~/.bash_login,如果该文件也不存在,则执行~/.profile文件。 
然后bash将作为一个交互式shell执行~/.bashrc文件(如果存在的话)。很多系统中,~/.bashrc都将启动 
/etc/bashrc作为系统范围内的配置文件。 
即启动过程如下 
/etc/profile -> (~/.bash_profile | ~/.bash_login | ~/.profile) -> ~/.bashrc -> /etc/bashrc -> ~/.bash_logout

tip: 我们可以通过[ echo $SHELL ]查看当前shell类型

shell中的特殊字符

shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的特殊字符。在使用它们时应注意其特殊的含义和作用范围。下面分别对这些特殊字符加以介绍。

1. 通配符 
通配符用于模式匹配,如文件名匹配、路经名搜索、字符串查找等。 
常用的通配符有*、?和括在方括号[ ]中的字符序列。用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的“模式串”,在执行过程中进行模式匹配。 
*  代表任何字符串例 
?  代表任何单个字符。 
[] 代表指定的一个字符范围。只要文件名中[]位置处的字符在[] 中指定的范围之内,那么这个文件名就与这个模式串匹配。方括号中的字符范围可以由直接给出的字符组成,也可以由表示限定范围的起始字符、终止字符及中间的连字符(-)组成。 
eg: f[a-d] 与 f[abcd]的作用相同。

2. 引号 
在shell中引号分为三种:单引号' ,双引号" 和反引号` 
* 单引号 ' 
由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。

* 双引号 " 
由双引号括起来的字符,除$ \ `这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待。 
tip: \是转义字符, 它告诉shell不要对其后面的那个字符进行特殊处理,只当作普通字符即可

* 反引号 ` 
反引号(`)这个字符所对应的键一般位于键盘的左上角。 
反引号括起来的字符串被shell解释为命令行,在执行时,shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。另,反引号还可以嵌套使用。

3. 注释符 
在shell编程中经常要对某些正文行进行注释,以增加程序的可读性。在Shell中以字符“#”开头的正文行表示注释行。

4. 其他特殊字符 
此外还有一些特殊字符如: 
"\"是转义字符, shell会把\后的特殊字符当作普通字符处理 
";"用来在一行内连接两个命令 
用于输入/输出重定向与管道的<、>、<<、>>和| 
执行后台命令的& 
命令执行操作符&&和||及表示命令组的{}

3. shell程序设计

变量

shell中的变量有多种 
本地变量: 也即局部变量,用户自定义的变量,只在创建它们的shell中可用 
环境变量: 也称为全局变量,通常为大写,用于所有用户进程(即可用于当前shell及派生出来的shell) 
位置变量: $0表示程序名, $1-$9参数 
特定变量: 脚本运行时的一些相关信息

特定变量

参数 含义
$# 传递到脚本的参数个数
$* 传递到脚本的参数, 即将所有参数作为一个字符串
$$ 脚本运行的当前进程号,常用作临时变量后缀
$@ 与$#相同,使用时加引号,并在引号中返回参数个数
$- 上一个命令的最后一个参数
$? 命令执行后返回的状态 一般为0(没有错误)
$! 后台运行的最后一个进程的进程ID
   

设置环境变量: 
- export 变量=值 
- 变量=值;export变量 
- declare –x 变量=值

tip:  
1. 通常在$HOME/.bash_profie和/etc/profile下设置环境变量 
3. 命令env/export可查看所有环境变量
 
2. 命令set可查看所有变量

shell中的变量名必须以字母或下划线字符开头。 
其余的字符可以是字母、数字(0~9)或下划线字符。 
任何其他的字符都标志着变量名的终止。 
名字是大小写敏感的 
shell中的变量是没有类型的,本质上都是字符串,但可以进行数学运算。

变量定义: 
用declare命令可以创建本地变量(加参数可设置特殊变量) 
declare  var(=value) 
也可以直接用'='进行变量定义并赋值

用readonly/ declare -r命令创建只读变量(不可复位) 
readonly var(=value) 
declare –r var(=value) 
tip: =左右两边不允许有空格

在定义字符串时可以用 
    " "(可以允许变量替换,即保留特殊字符的含义) 
或 
    ' '(不允许变量替换,即把特殊字符当作普通字符处理) 
来引。 
否则就需要对字符串中的空格进行转义

变量替换(变量引用): 
引用变量的时候 用 $ ,可以不使用{} 但在某些场合应该使用{ }以避免歧义。

$varname                返回变量实际值 
${varname}              返回变量实际值 
${var_name:+value}   若定义了变量,则返回value; 否则返回空 
${var_name:?value}    若未定义变量,则返回value 
${var_name:-value}    若未定义变量,则返回value; 否则返回实际值 
${var_name:=value}    若未定义变量, 定义并赋值为value, 并返回; 否则返回实际值 
eg: 
[Fixedsys@localhost ~]$ str="My Love" 
[Fixedsys@localhost ~]$ string=My\ Love 
[Fixedsys@localhost ~]$ x=12 

[Fixedsys@localhost ~]$ echo ${str} 
[Fixedsys@localhost ~]$ echo ${string} 
[Fixedsys@localhost ~]$ echo $x

[Fixedsys@localhost ~]$ dir=`ls -a` 
[Fixedsys@localhost ~]$ echo $dir 
tip: ``表示变量替换,即执行里面的内容并把结果赋值给变量

复位变量: 
本地变量和环境变量都可以用unset命令来清除 
注意:  具有只读属性的变量不可被清除

运算符

位运算符: 
~op           求反运算符 
op1 << op2 左移运算符 
op1 >> op2 右移运算符 
op1 & op2   与比较运算符 
op1 ^ op2   异或运算符 
op1 | op2    或运算符

逻辑运算符: 
&& ||

比较运算符: 
> == < !=

赋值运算符: 
=  +=  –=  *=  /=  
%=  &=  ^=  |=

运算符优先级 
image

简单计算

let表示数学运算, 
expr用于整数值运算,每一项用空格隔开, 
$[]将中括号内的表达式作为数学运算先计算结果再输出。 
tip: 
1. $[]同$(()) 
2. $[]可以接受不同基数的数字 [base#n] ,n为基数

let 命令格式中的语句不允许有空格。 
$()可以有空格,而且易于阅读。 
以上两种方式适用数字,位,逻辑运算。 
eg:

#!/bin/bash 
x=10
y=5
let sum=$x+$y          #15
diff=$(($x - $y))      #5
let mul=$x*$y          #50
exp=$(($x ** $y))      #1000000
echo $sum ; echo $diff ; echo $mul ; echo $exp
 
 

输入输出

echo命令: 
使用echo命令可以显示文本行或变量,或者把字符串输入到文件。 
格式: 
echo [option] string 
-e 解析转义字符(echo默认不解析转义字符) 
-n 回车不换行,linux系统默认回车换行 
转义符(\c,\f,\t,\n) 
  \c回车不换行 
  \f 禁止 
  \t Tab 
  \n回车换行

printf命令: 
格式化输出数据 
与C语言中的printf函数相似 
格式: 
printf FORMAT [ARGUMENT] … 

read命令: 
read命令可以从键盘或文件的某一行文本中读入信息,并将其赋值给一个或多个变量(用空格作为分隔符) 
如果只指定了一个变量,那么read将会把所有的输入赋给该变量,直至遇到第一个文件结束符或回车 
如果给出来多个变量,它们按顺序分别被赋予不同的变量 
格式: 
read varible1[ varible2 ...]

cat命令: 
cat可以用来显示文件内容,创建文件,还可以用来显示控制字符。 
注意: cat不会在文件分页符处停下来;它会一下显示完整个文件 
格式: 
cat [options] filename1 filename2 
-v 显示控制字符

管道: 
通过管道可以把一个命令的输出传递给另一个命令作为输入 
管道用竖杠" | "表示 
格式: 
命令1 | 命令2

tee命令: 
tee命令从标准输入读入,然后将输出的一个副本输送到标准输出,另一个副本拷贝到相应的文件 
格式: 
tee [options] files

标准输入、输出和错误: 
在shell中执行命令时,每个进程都和三个打开的文件相联系,并使用文件描述符来引用这些文件。 
由于文件描述符不容易记忆,shell同时也给出了相应的文件名。 
           文件                                    文件描述符 
输入文件——标准输入            0(缺省是键盘,也可以是文件或其他命令的输出) 
输出文件——标准输出            1(缺省是屏幕,也可以是文件) 
错误输出文件——表示错误      2(缺省是屏幕,也可以是文件)

文件重定向: 
在执行命令时,可以指定命令的标准输入、输出和错误,要实现这一点就需要使用文件重定向 
注意:  在对标准错误进行重定向时,必须要使用文件描述符;但是对于标准输入和输出来说,这不是必需的 
文件重定向使用符号 >  >>  <  <<

exec: 
exec命令可以用来替代当前shell 
换句话说,并没有启动子shell,使用这一命令时任何现有环境将会被清空,并重新启动一个shell 
格式: 
exec command  
其中的command通常是一个shell脚本。 
对文件描述符进行操作的时候(也只有在这时),它不会覆盖你当前的shell

 

条件结构

if语句: 
测试条件{用test 或[[ ]] (或[],在不引起歧义的情况下)引用起来} 
整数比较: -eq -ne -gt -ge -lt -le 
字符串比较:    = == != < > -z(字符串为空) -n(字符串非空) 
文件测试: -e -f -s -d    -h -r -w -x 
语句结构:  
   if/then[/else]/fi 
   if/then/elif/then/fi

#!/bin/bash 
x=5 ; y=6
if [[ $x -eq $y ]]
then
echo "$x equals to $y"
else
echo "$x doesn't equals to $y"
fi

if test -e test.sh ; then
echo "File Exists"
fi

case结构: 

#!/bin/bash 
var=2
case "$var" in
0) echo "This is 0" ;;    #其中0可以是形如 [0-9] 或是 [a-zA-Z] 及 用 | 等连接起来的表达式
1) echo "This is 1" ;;
2) echo "This is 2" ;;
*) echo "This is not 0, 1, 2" ;; # *表示默认匹配项,即上面都不匹配的时候。
esac
exit
 

循环结构 
while循环: while 测试条件 ; do ... ; done 
for循环: for/in/do/done 通过指定变量范围进行循环。 
-------------- 
#!/bin/bash 
for var in 1 2 3 4 5    # or like this for ((var=1 ; var <=5 ; var++)) 
do 
   echo -n "$var " 
done 
exit

--------------

函数 

function <name> () { 
sequence of command 

同C语言一样,在调用函数前应该申明它。 
----------- 
#!/bin/bash 
function sum () 

if [ $# -ne 2 ] ; then 
echo "Usage is sum <param1> <param2>" 
exit 
fi 
return $(( $1 + $2 )) 

sum 5 10 
ret=$? 
echo $ret 
------------

posted on 2013-10-22 15:13  无为在歧路  阅读(188)  评论(0编辑  收藏  举报

导航