linux shell学习笔记

《linux shell 脚本攻略》



一、小试牛刀


1、脚本是使用一种特定的描述性语言,依据一定的格式编写的可执行文件,又称作宏或批处理文件。

(1)脚本简单的说就是一条条的文字指令,这些命令是可以看到的,如可以用记事本打开、查看、编辑,脚本程序执行时,由系统的一个解释器,将其一条条的翻译成机器可识别的指令,并按程序顺序执行,因为脚本在执行多了一道翻译的过程,所以它比二进制程序执行效率要稍低一些;


(2)UNIX风格的操作系统架构最重要的一个特性是命令行界面或shell;

shell环境使得用户能与操作系统的内核进行交互操作。术语“脚本”更过涉及的是这类环境;编写脚本通常使用某种基于解释器的编程语言,而shell脚本不过是一些文件,我们能将一系列需要执行的命令写入其中,然后通过shell来执行这些脚本。


(3)$表示普通用户,#表示超级用户即root user,

shell脚本通常是一个以#!为起始的文本文件,如下所示:

#!/bin/bash

linux环境下的任何脚本语言都是以这样一个被称为shebang的特殊行作为起始的。字符#!被置于解释器路径之前,/bin/bash是Bash的路径


(4)脚本执行方式

有两种脚本执行的方式:一种是将脚本作为sh的命令行参数,另一种是将脚本作为具有执行权限的可执行文件。


第一种:将脚本作为命令行参数时的运行方式如下:

$ sh script.sh                                     假设脚本位于当前目录下

$ sh /home/path/script.sh               使用sript.sh的完整路径

如果将脚本作为sh的命令行参数来运行,那么脚本中的shebang行也就没什么用处了。


第二种:将脚本作为可执行文件来执行:

为了使shell脚本能够自己独立运行,需要具备可执行权限。要使脚本独立运行,必须利用shebang行,它通过使用位于#!之后的解释器来运行脚本,至于脚本的可执行权限,可以通过以下方式设置:

$ chmod a+x script.sh

该命令赋予所有用户script.sh文件的可执行权限,这个脚本能以下列方式执行:

$ ./script.sh                                        ./表示当前目录

或者

$ /home/path/script.sh                      使用脚本的完整路径

shell程序读取脚本的首行,查看shebang行是否为#!/bin/bash,它会识别/bin/bash,并且在内部以如下命令执行该脚本:

$ /bin/bash   script.sh

当打开一个终端时,该终端最初会执行一组命令来定义诸如提示文本、颜色等各类设置。这组命令来自位于用户home目录中的.bashrc脚本文件(~/.bashrc)。Bash还维护了一个历史记录文件~/.bash_history,用于保存用户运行过的命令,~是一种简写,代表用户home目录的路径。


注:chmod命令解释:

变更文件或目录的权限。在UNIX系统家族里面,文件或目录权限的控制分别以读取、写入、执行3种一般权限来区分,另有三种特殊权限可供运用,再搭配拥有者与所属群组管理权限范围。你可以使用chmod指令去变更文件与目录的权限,设置方式采用文字或数字代号皆可。

权限范围的表示法如下:

u:user,即文件或目录的拥有者

g:Group,即文件或目录的所属群组

o:other,除了文件或目录拥有者或所属群组之外,其他用户皆属于这个范围

a:all,即全部用户,包含拥有者,所属群组以及其他用户

有关权限的代号,列表如下:

r:读取权限,数字代号为4

w:写入权限,数字代号为2

x:执行或切换权限,数字代号为1

-:不具任何权限,数字代号为0

s:特殊功能


范例一 :将档案 file1.txt 设为所有人皆可读取 :
chmod ugo+r file1.txt
将档案 file1.txt 设为所有人皆可读取 :
chmod a+r file1.txt
将档案 file1.txt 与 file2.txt 设为该档案拥有者,与其所属同一个群体者可写入,但其他以外的人则不可写入 :
chmod ug+w,o-w file1.txt file2.txt
将 ex1.设定为只有该档案拥有者可以执行 :
chmod u+x ex1
将目前目录下的所有档案与子目录皆设为任何人可读取 :
chmod -R a+r *
当其他用户执行oracle的sqlplus这个程序时,他的身份因这个程序暂时变成oracle
chmod u+s sqlplus



此外,chmod也可以用数字来表示权限:如 chmod  777  file

此外,chmod也可以用数字来表示权限如 chmod 777 file
语法为:chmod abc file
其中a,b,c各为一个数字,分别表示User、Group、及Other的权限。
r=4,w=2,x=1
若要rwx属性则4+2+1=7;
若要rw-属性则4+2=6;
若要r-x属性则4+1=5。




(5)Bash,每个命令或是命令序列是通过使用分号或换行符来分隔的。比如:

$  cmd1; cmd2

他等同于:

$ cmd1

$ cmd2




2、终端打印  

       终端作为交互式工具,用户可以通过它与shell环境进行交互,在终端中打印文本是绝大多数shell脚本和工具日常需要进行的基本任务。

       echo是用于终端打印的的基本命令。


(1)只需要使用带双引号的文本,结合echo命令就可以将该文本在终端中打印出来。类似的,不带双引号的文本也可以得到同样的输出结果:

$ echo "welcome to Bash"

welcome to Bash

$ echo welcome to Bash

welcome to Bash

使用单引号也可以:

$ echo 'welcome to Bash'

welcome to Bash

注:当双引号和单引号之间没有字符时,不打印任何东西,但是双引号或单引号必须是偶数个,不然会一直提示你输入,知道你输入双引号或单引号

$ echo 'welcome to Bash'''

welcome to Bash

$ echo """"welcome to Bash ''''

welcome to Bash

$echo welcome to '''B

>a

>s

>h'

输出:

welcome to B

a

s

h


如果你希望打印!,那就不要将其放入双引号,或者是将其放入双引号时,在其之前加上一个特殊的转义字符\,将!转义:

$ echo !

!

$echo '!'

!

$echo "!"

-bash: !:event not found 

$echo "\!"

!

但是在我的ubuntu上打印出来的是:

$echo "\!"

\!

$echo \!

!



printf在我的ubuntu上不能用


(2)默认情况下,echo会将一个换行符追加到输出文本的尾部,可以使用标志-n来忽略结尾的换行符。

如:

test@ubuntu:~$ echo -n "1234"

1234test@ubuntu:~$ 

而:

test@ubuntu:~$ echo "1234"

1234

test@ubuntu:~$ 


echo同样接受双引号字符串内的转义序列作为参数。如果需要使用转移序列,则采用

echo -e "包含转义序列的字符串"

例如:

echo -e  “1\t2\t3”

1        2        3

这里就将\t作为制表符


(3)打印彩色输出:

打印彩色字体:

 每种彩色都有对应的彩色码:比如:重置=0,黑色=30,红色=31,绿色=32,黄色=33,蓝色=34,洋红=35,青色=36,白色=37;

打印彩色字体可以输入:

echo  -e "\e[31m This is a red text \e[0m"

This is a red text

其中\e[31m是将颜色设置成红色,\e[0m是将颜色重新置回,你只需要将颜色替换成你想要的颜色码就可以了。


要想设置彩色背景,经常使用的颜色码是:重置=0,黑色=40,红色=41,绿色=42,黄色=43,蓝色=44,洋红=45,青色=46,白色=47;

echo  -e "\e[41m This is a red text \e[0m"

This is a red text


3、变量和环境变量

脚本语言中,通常不需要在使用变量之前声明其类型,只需要直接赋值就可以了;

在Bash中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。

有一些特殊的变量会被shell环境和操作系统环境用来存储一些特别的值,这类变量就称为环境变量

(1)预备知识

对于每个进程,在其运行时的环境变量可以使用下面的命令来查看:

$ cat  /proc/$PID/environ

其中,将PID设置成相关进程的进程PID,PID总是一个整数。


假设有一个叫做gedit的应用程序正在运行,我们可以使用pgrep命令获得gedit的进程ID:

$ pgrep gedit 

12506

那么,你就可以通过以下命令获得与该进程相关的环境变量:

$ cat   /proc/12506/environ



(2)实战演练

变量赋值:var=value

var是变量名,value是赋给变量的值,如果value不包含任何空白字符例如空格,那么它不需要使用引号进行引用,反之,则必须使用双引号。

注:var = value不同于var=value,把var=value写成var = value是一个常见的错误,前者是赋值操作,后者是比较相等操作

在变量名前加上$前缀就可以打印出变量内容:

$ var="welcome"

$ echo $var

welcome

或者:

$ echo ${var}

welcome



环境变量是未在当前进程中定义,而从父进程中继承而来的变量。

export命令用来设置环境变量,至此之后,从当前shell脚本执行的任何程序都会继承这个变量。

$PATH通常定义在/etc/environment或/etc/profile或~/.bashrc中;

如果需要在PATH中添加一条新路径,可以使用:

$ export PATH="$PATH:/home/user/bin"

也可以使用:

$ PATH="$PATH:/home/user/bin"

$ export PATH


显示环境变量

$ echo $PATH

显示HOME:

$ echo $HOME

显示当前工作目录

$ echo $PWD

显示当前用户名

$ echo $USER

显示当前用户的ID

$ echo $UID

显示当前进程号

$ echo $PID

显示当前进程父进程号

$ echo $PPID


(3)补充内容

获得字符串长度:

length=${#var}

例如:

$ var=012346789

$ echo ${#var}

10

或者

$ var=0123456789

$ length=${#var}

$ echo $length

10

length就是字符串所包含的字符数。


(4)识别当前的shell版本,看一下使用的是那种shell

$ echo $SHELL

/bin/bash

或者使用:

echo $0

bash


(5)检查是否为超级用户

UID是一个重要的环境变量,可以用于检查当前脚本是以超级用户还是以普通用户的身份运行的。

if [ $UID -ne 0 ] ;then

echo Non root user.Please run as root.

else 

echo "Root user"

fi


root用户的UID是0.



(6)修改Bash提示字符串

先列到这里



4、利用shell进行运算

利用let、[]、{}、()进行基本的算术运算

(1)使用let的时候,变量名之前不需要再添加$:

$ no1=4

$ no2=5

$ let result=no1+no2

$ echo $result

9

自加操作:

$ let no1++

$ let no2++

$ echo $no1;echo $no2

5

6

自减操作:

$ let no1--;let no2--

4

5

简写形式

$ let no1+=6;let no2-=6

$ echo $no1;echo $no2

10

-1

分别等同于:let  no1=no1+6;let no2=no2-6

(2)操作符[ ]的使用方法和let命令类似:

$ result=$[no1+no2];echo $result

9

或者:

$ result=$[$no1+no2];echo $result

9

也可以使用(()):

$ result=$((no1+no2));echo $result

9


(3)也可以使用expr命令:

expr命令介绍:一般用于整数值计算,也可用于字符串操作;使用权限是所有使用者;格式是:

expr argument  operator argument

参数说明:argument:第一个操作数

                   operator:为操作运算符

                   argument:第二个操作数


数学运算器:

注意运算符左右要有空格

$ expr 13 + 12

25

$ expr 13 - 12

$ expr 30 / 3

10

$ expr 30 / 2 / 5 可以使用这种连续的计算,加减乘除法均可以

3

$ expr 12 \* 5 使用乘号时,必须使用反斜线屏蔽其特定含义,因为shell可能会误解显示星号的含义。

60


增量计数:

        expr在循环中用于增量计算,首先,循环初始化为0,然后循环值加1,反引号的用法意即替代命令,最基本的一种是从expr命令接受输出并将之放入循环变量。

$LOOP=0
$LOOP=`expr $LOOP + 1`
注意上面的 ` 是与 ~ 相对应的键,即反引号


计算字符串的长度

方法一:使用echo:

$ str=”0123456789“

$ echo ${#str}

10

方法二:使用expr

$ expr length ”$str“

10


expr中的expr index $string substring索引命令功能在字符串$string上找出substring中字符第一次出现的位置,若不找出expr index返回0或1

$ str="0123456789sdf"

$ expr index “$str” my

0

$ expr index “$str” reg5

6

$expr index ”$str“ 340dsf

1


expr 中的expr match $string substring命令在string字符串中匹配substring字符串,然后返回匹配到的substring字符串的长度,若找不到则返回0;

$ string=asdfghjklqwertyuiop

$ expr match $string 4164

0

$ expr match $string as.*

19

$ expr match $string sjfsj

0


在shell中可以用{string:position}和{string:position:length}进行对string字符串中字符的抽取。第一种是从position位置开始抽取直到字符串结束,第二种是从position位置开始抽取长度为length的子串。而用expr中的expr substr $string $position $length同样能实现上述功能。
$ string=123456789

$ echo ${string:3}

456789

$ expr ${string:3}

456789

$ expr ${string:3:5}

45678

$ expr substr $string 3 5

34567

注意:echo ${string:10:5}和 expr substr "$string" 10 5的区别在于${string:10:5}以0开始标号而expr substr "$string" 10 5以1开始标号。



删除字符串和抽取字符串相似${string#substring}为删除string开头处与substring匹配的最短字符子串,而${string##substring}为删除string开头处与substring匹配的最长字符子串。

$ str=145411111ddfffffdd313

$ echo ${str#1*1}

1111ddfffffdd313

$ expr ${str#1*1}

1111ddfffffdd313

$ echo ${str##1*1}

3

$ expr ${str##1*1}

3

$ expr ${str#4*1}

145411111ddfffffdd313

$ expr ${str##4*1}

145411111ddfffffdd313

必须是开头处开始匹配



替换子串${string/substring/replacement}表示仅替换一次substring相配字符,而${string//substring/replacement}表示为替换所有的substring相配的子串。

$ str=145411111ddfffffdd313

$ expr ${str/11/##}

1454##111ddfffffdd313

$ expr ${str//11/##]

1454####1ddfffffdd313


(4)可用于浮点数的计算

bc:bc是一个用于数学运算的高级工具,这个精密计算器包含了大量的选项。

$ echo "4*1.25" | bc

5

$ no=45;re=`echo "$no * 2.75" | bc`;echo $re

123.75


设定小数精度(数值范围)

$ echo "scale=20;1/3" | bc

0.33333333333333333333


进制转换:用bc可以将一种进制系统转换为另一种进制系统;

$ no=100

$ echo "obase=2;$no" | bc

1100100

$ no=1100100

$ echo "obase=10;ibase=2;$no" | bc

100


计算平方根以及平方

$ echo "sqrt(100)" | bc

10

$ echo "10*10" | bc

100

$ echo "10^10" | bc

10000000000



5、文件描述符和重定向

文件描述符是与文件输入、输出相关联的整数,它们用来跟踪已打开的文件;最常见的文件描述符是stdin、stdout、stderr。

(1)>

先清空原文件,再写入内容

(2)>>

将内容追加到现有文件的尾部


注:看上一条命令是否执行成功:

$ ls +

ls:can't access +;

$ echo $?                          上一条命令ls + 执行不成功,所以返回2

2

$echo $?                           上一条命令echo $?执行成功,所以返回0

0



6、数组

bash同时支持普通数组和关联数组;普通数组只能使用整数作为数组索引,而关联数组可以使用字符串作为数组索引

$ arr=(1 2 3 4 5 6)

$ echo ${arr[0]}

1

$ echo ${arr[*]}                                     打印出每个数组元素

1 2 3 4 5 6

$ echo ${arr[@]}

1 2 3 4 5 6

$ echo ${#arr[*]}                                   打印数组元素的长度

6

$ echo ${#arr[@]}

6






8、获得终端信息


(1)























*****************************************************************************************************************************************************************************************

                                                                                                           2013年4月9日


*****************************************************************************************************************************************************************************************

你可能感兴趣的:(linux相关,脚本,读书笔记)