shell script随笔记

1.shell执行方式:

Shell脚本的执行方式可以有以下几种:

方式一: ./script.sh                                     # 利用小数点来执行

方式二: sh script.sh bash script.sh      #  利用bash(sh)来执行脚本

方式三: source script.sh                            #  利用source来执行

前面两种方式其实都是一样的:都是在当前父进程下的子进程中执行,子进程完成后,子进程中的各项变量或操作将会结束而不会传回到父进程中, 而通过第三种方式执行(source test.sh)的话,在父进程中执行的,进程执行完后,各项变量传回到父进程中.

 

2. test测试功能

2.1.关于某个档名的『文件类型』判断,如 test -e filename 表示存在否

-e  该『档名』是否存在?(常用)

-f  该『档名』是否存在且为档案(file)?(常用)

-d  该『文件名』是否存在且为目录(directory)?(常用)

-b  该『档名』是否存在且为一个block device 装置?

-c  该『档名』是否存在且为一个character device 装置?

-S  该『档名』是否存在且为一个Socket 档案?

-p  该『档名』是否存在且为一个FIFO (pipe) 档案?

-L  该『档名』是否存在且为一个连结档?

2.2 关于档案的权限侦测,如 test -r filename表示可读否(但 root 权限常有例外)

-r  侦测该档名是否存在且具有『可读』的权限?

-w  侦测该档名是否存在且具有『可写』的权限?

-x  侦测该档名是否存在且具有『可执行』的权限?

-u  侦测该文件名是否存在且具有『SUID』的属性?

-g  侦测该文件名是否存在且具有『SGID』的属性?

-k  侦测该文件名是否存在且具有『Sticky bit』的属性?

-s  侦测该档名是否存在且为『非空白档案』?

2.3 两个档案之间的比较,如: test file1 -nt file2

-nt (newer than)判断 file1 是否比 file2 新

-ot (older than)判断 file1 是否比 file2 旧

-ef 判断 file1 不 file2 是否为同一档案,可用在判断hard link 的判定上。主要意义在判定,两个档案是否均指向同一个 inode 哩!

2.4 关于两个整数之间的判定,例如 test n1 -eq n2

-eq  两数值相等 (equal)

-ne  两数值不等 (notequal)

-gt n1 大于 n2 (greater than)

-lt n1 小于 n2 (less than)

-ge n1 大于等于 n2 (greater than or equal)

-le n1 小于等于 n2 (less than or equal)

2.5 判定字符串的数据

test -z string  判定字符串是否为 0 ?若 string 为空字符串,则为 true

test -n string  判定字符串是否非为 0 ?若 string 为空字符串,则为false。

         注: -n 亦可省略

test str1 = str2 判定 str1 是否等于str2 ,若相等,则回传 true

test str1 != str2 判定 str1 是否不等于str2 ,若相等,则回传false

 

2.6 多重条件判定,例如: test -r filename -a -xfilename

-a: (and)两状况同时成立!例如 test -rfile -a -x file,则 file 同时具有r 与 x 权限时,才回传 true。

-o :(or)两状况任何一个成立!例如 test -rfile -o -x file,则 file 具有 r或x 权限时,就可回传 true。

! :反相状态,如 test ! -x file,当 file 丌具有 x 时,回传 true

 

3.判断符号:[]

     在中括号 [] 内的每个组件都需要有穸格键来分隑;

  在中括号内的发数,最好都以双引号括号起来;

  在中括号内的常数,最好都以单戒双引号括号起来。

[ "$HOME" == "$MAIL" ]  相当于  test $HOME = $MAIL

 

4.Shell script 的默认变数($0, $1...)

$# :代表执行脚本后接的参数『个数』

$@ :代表『"$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);

$* :代表『"$1c$2c$3c$4" 』,其中 c 为分隔字符,默讣为空格键,所以本例中代表『 "$1

$2 $3 $4" 』之意。

例子: 脚本:sh03.sh


#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

echo "The script name is ==> $0"

echo "Total parameter number is ==>$#"

[ "$#" -lt 2 ] && echo"The number of parameter is less than 2. Stop here." && exit0

echo "Your whole parameter is ==>'$@'"

echo "The 1st parameter ==>$1"

echo "The 2nd parameter ==>$2"

 

执行: bash sh03.sh haha heihei hehe

 执行结果:

The script name is ==> sh03.sh

Total parameter number is ==> 3

Your whole parameter is ==> ' haha heihei hehe '

The 1st parameter ==> haha

The 2nd parameter ==> heihei

 

5.条件判断式: if ... then

5.1单层、简单条件判断式:

         if[ 条件判断式 ]; then

                  当条件判断式成立时,可以进行的指令工作内容;

         fi<==将 if 反过来写,就成为 fi 啦!结束 if 之意!

        

如果是多条件时:

         &&代表 AND ;

      || 代表 or ;

 

 

5.2 多重、复杂条件判断式

# 多个条件判断 (if ... elif... elif ... else) 分多种不同情况执行

if [ 条件判断式一 ]; then

         当条件判断式一成立时,可以进行的指令工作内容;

elif [ 条件判断式二 ]; then

         当条件判断式二成立时,可以进行的指令工作内容;

else

         当条件判断式一与二均不成立时,可以进行的指令工作内容;

fi

 

6 条件判断式:  case...esac

语法:

case $变量名称 in  <==关键词为 case ,还有变量前有钱字号

         "第一个变量内容")   <==每个变量内容建议用双引号括起来,关键词则为小括号 )

         程序段;;  <==每个类别结尾使用两个连续的分号来处理!

         "第二个变量内容")

         程序段;;

         *)   <==最后一个变量内容都会用 * 来代表所有其他值,不包含第一个变量内容与第二个变量内容的其他程序执行段

         exit1;;

esac         <==最终的 case 结尾!『反过来写』思考一下!

7. function 功能

语法:

         functionfname() {

                   程序段

         }

         那个 fname 就是我们的自定义的执行指令名称~而程序段就是我们要他执行的内容了。要注意的是,因为 shell script 的执行方式是由上而下,由左而右,因此在 shell script 当中的 function 的设定一定要在程序的最前面,这样才能够在执行时被找到可用的程序段喔!

例子:脚本:sh12.sh

 

#!/bin/bash

# Program:

# Use function to repeat information.

# History:

# 2005/08/29  VBird First release

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

function printit(){

         echo-n "Your choice is " # 加上 -n 可以丌断行继续在同一行显示

}

echo "This program will print yourselection !"

case $1 in

"one")

printit; echo $1 | tr 'a-z' 'A-Z' # 将参数做大小写转换!

;;

"two")

printit; echo $1 | tr 'a-z' 'A-Z'

;;

"three")

printit; echo $1 | tr 'a-z' 'A-Z'

;;

*)

echo "Usage $0 {one|two|three}"

;;

esac

8.循环

while do done, until do done (不定循环)

第一种: 当 condition 条件成立时,就进行循环,直到condition 的条件不成立才停止

while [ condition ] <==中括号内的状态就是刞断式

do              <==do 是循环的开始!

         程序段落

done         <==done 是循环的结束

 

第二种: 当 condition 条件成立时,就终止循环,否则就持续进行循环的程序段。

until [ condition ]

do

         程序段落

done

 

for...do...done (固定循环)

 

语法:

for var in con1 con2 con3 ...

do

         程序段

done

 

举例: 脚本sh15.sh

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

for animal in dog cat elephant

do

         echo"There are ${animal}s.... "

done

 

for...do...done 的数值处理:

语法:

for (( 初始值; 限制值; 执行步阶 ))

do

         程序段

done

 

     初始值:某个变量在循环当中的起始值,直接以类似 i=1 设定好;

  限制值:当发量的值在这个限制值的范围内,就继续进行循环。例如 i<=100;

  执行步阶:每作一次循环时,变量的变化量。例如 i=i+1。

 

举例: sh19.sh

#!/bin/bash

PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

export PATH

read -p "Please input a number, I willcount for 1+2+...+your_input: " nu

s=0

for (( i=1; i<=$nu; i=i+1 ))

do

s=$(($s+$i))

done

echo "The result of '1+2+3+...+$nu' is==> $s"

 

9. shell script 的追踪与 debug

sh [-nvx] scripts.sh

选项与参数:

-n :不要执行 script,仅查询语法的问题;

-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;

-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!

 

10.档案权限与目录配置

使用ls -al查看

第一栏代表这个档案的类型与权限(permission):

第一栏有十个字符:

         第一个字符代表这个档案是『目录、档案或链接文件等等』

                   当为[ d ]则是目录,例如上表档名为『.gconf』的那一行;

                  当为[ - ]则是档案,例如上表档名为『install.log』那一行;

                 若是[ l ]则表示为连结档(link file);

                    若是[ b ]则表示为装置文件里面的可供储存的接口设备(可随机存取装置);

                    若是[ c ]则表示为装置文件里面的串行端口设备,例如键盘、鼠标

         接下来的字符中,以三个为一组,且均为『rwx』的三个参数的组合。其中,[ r ]代表可读,(read)、[ w ]代表可写(write)、[ x ]代表可执行(execute)。要注意的是,这三个权限的位置不会改变,如果没有权限,就会出现减号[ - ]而已。

                   第一组为『档案拥有者的权限』

                   第二组为『同群组的权限』;

                   第三组为『其他非本群组的权限』。

 

第二栏表示有多少档名连结到此节点(i-node);

 

第三栏表示这个档案(或目录)的『拥有者账号』;

 

第四栏表示这个档案的所属群组;

 

第五栏为这个档案的容量大小,默认单位为 bytes;

 

第六栏为这个档案的建档日期或者是最近的修改日期;

 

第七栏为这个档案的档名


11.变量的设定

11.1变量的设定规则

1. 变量与变量内容以一个等号『=』来连结,如下所示:

『myname=VBird』

2. 等号两边不能直接接空格符,如下所示为错误:

         『myname =VBird』或『myname=VBird Tsai』

3. 变量名称只能是英文字母与数字,但是开头字符不能是数字,如下为错误:

『2myname=VBird』

4.变量内容若有空格符可使用双引号『"』或单引号『'』将变量内容结合起来,但

         o 双引号内的特殊字符如 $ 等,可以保有原本的特性,如下所示:

『var="lang is $LANG"』则『echo $var』可得『lang is en_US』

         o 单引号内的特殊字符则仅为一般字符 (纯文本),如下所示:

『var='lang is $LANG'』则『echo $var』可得『lang is $LANG』

5. 可用跳脱字符『 \ 』将特殊符号(如 [Enter], $,\, 空格符, '等)变成一般字符;

6.在一串指令中,还需要藉由其他的指令提供的信息,可以使用反单引号『`指令`』或 『$(

)』。特别注意,那个 ` 是键盘上方的数字键 1 左边那个按键,而不是单引号! 例如想要取得核心版本的设定:

『version=$(uname -r)』再『echo $version』可得『2.6.18-128.el5』

7. 若该变量为扩增变量内容时,则可用"$变量名称" 或 ${变量} 累加内容,如下所示:

『PATH="$PATH":/home/bin』

8. 若该变量需要在其他子程序执行,则需要以export 来使变量变成环境变量:

『export PATH』

9. 通常大写字符为系统默认变量,自行设定变量可以使用小写字符,方便判断 (纯粹依照使用者兴趣与嗜好) ;

10. 取消变量的方法为使用 unset :『unset 变量名称』例如取消myname 的设定:

『unset myname』

 

11.2变量内容的删除与取代

12.3变量的测试与内容替换

12.重定向

大多数UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端。一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

重定向命令列表如下:

命令

说明

command > file

将输出重定向到 file

command < file

将输入重定向到 file

command >> file

将输出以追加的方式重定向到 file

n > file

将文件描述符为 n 的文件重定向到 file

n >> file

将文件描述符为 n 的文件以追加的方式重定向到 file

n >& m

将输出文件 m n 合并。

n <& m

将输入文件 m n 合并。

<< tag

将开始标记 tag 和结束标记 tag 之间的内容作为输入。

 

 

需要注意的是文件描述符 0 通常是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

 

12.1输出重定向

重定向一般通过在命令间插入特定的符号来实现。特别的,这些符号的语法如下所示:

command1 > file1

上面这个命令执行command1然后将输出的内容存入file1

注意任何file1内的已经存在的内容将被新内容替代。如果要将新内容添加在文件末尾,请使用>>操作符。

 

实例:

执行下面的 who 命令,它将命令的完整的输出重定向在用户文件中(users):

$ who > users

 

执行后,并没有在终端输出信息,这是因为输出已被从默认的标准输出设备(终端)重定向到指定的文件。

可以使用 cat 命令查看文件内容:

$ cat users
_mbsetupuser console  Oct 31 17:35 
tianqixin    console  Oct 31 17:35 
tianqixin    ttys000  Dec  1 11:33 

 

输出重定向会覆盖文件内容,请看下面的例子:

$ echo "菜鸟教程:www.runoob.com" > users
$ cat users
菜鸟教程:www.runoob.com
$

如果不希望文件内容被覆盖,可以使用>>追加到文件末尾,例如:

$ echo "菜鸟教程:www.runoob.com" >> users
$ cat users
菜鸟教程:www.runoob.com
菜鸟教程:www.runoob.com
$

 

1> :以覆盖的方法将『正确的数据』输出到指定的档案或装置上;

1>>:以累加的方法将『正确的数据』输出到指定的档案或装置上;

2> :以覆盖的方法将『错误的数据』输出到指定的档案戒装置上;

2>>:以累加的方法将『错误的数据』输出到指定的档案戒装置上;

12.2输入重定向

和输出重定向一样,Unix 命令也可以从文件获取输入,语法为:

command1 < file1

这样,本来需要从键盘获取输入的命令会转移到文件读取内容。

注意:输出重定向是大于号(>),输入重定向是小于号(<)

实例:

接着以上实例,我们需要统计 users 文件的行数,执行以下命令:

$ wc -l users
       2 users

也可以将输入重定向到 users 文件:

$  wc -l < users
       2 

注意:上面两个例子的结果不同:第一个例子,会输出文件名;第二个不会,因为它仅仅知道从标准输入读取内容。

command1 < infile > outfile

同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中。

 

12.3重定向深入讲解

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

·        标准输入文件(stdin)stdin的文件描述符为0Unix程序默认从stdin读取数据。

·        标准输出文件(stdout)stdout 的文件描述符为1Unix程序默认向stdout输出数据。

·        标准错误文件(stderr)stderr的文件描述符为2Unix程序会向stderr流中写入错误信息。

默认情况下,command > file stdout 重定向到 filecommand < file stdin 重定向到 file

如果希望 stderr 重定向到 file,可以这样写:

$ command 2 > file

如果希望 stderr 追加到 file 文件末尾,可以这样写:

$ command 2 >> file

2 表示标准错误文件(stderr)

如果希望将 stdout stderr 合并后重定向到 file,可以这样写:

$ command > file 2>&1
或者
$ command >> file 2>&1

 

如果希望对 stdin stdout 都重定向,可以这样写:

$ command < file1 >file2

command 命令将 stdin 重定向到 file1,将 stdout 重定向到 file2

 

12.4HereDocument

HereDocument Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。

它的基本的形式如下:

command << delimiter

   document

delimiter

它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command

注意:

·        结尾的delimiter一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。

·        开始的delimiter前后的空格会被忽略掉。

实例

在命令行中通过 wc -l 命令计算 Here Document 的行数:

$ wc -l << EOF
    欢迎来到
    菜鸟教程
    www.runoob.com
EOF
3          # 输出结果为 3 
$

我们也可以将 Here Document 用在脚本中,例如:

#!/bin/bash
# author:菜鸟教程
# url:www.runoob.com
 
cat << EOF
欢迎来到
菜鸟教程
www.runoob.com
EOF

 

执行以上脚本,输出结果:

欢迎来到
菜鸟教程
www.runoob.com

 

/dev/null文件

如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null

$ command > /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。

如果希望屏蔽 stdout stderr,可以这样写:

$ command > /dev/null 2>&1

注意:0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

 

 

 

13.管道

管道符号,是unix一个很强大的功能,符号为一条竖线:"|"
用法: command 1 | command 2 他的功能是把第一个命令command 1执行的结果作为command 2的输入传给command 2,例如:

 

$ls -s|sort -nr (请注意不要复制$符号进去哦)

-s file size-nnumeric-sort-rreverse,反转

该命令列出当前目录中的文档(size),并把输出送给sort命令作为输入,sort命令按数字递减的顺序把ls的输出排序。

$ls -s|sort -n

按从小到大的顺序输出。
当然还可进行多次操作,如下面的功能为先去除纯数字,再由sed将竖线(这里不是管道符号)替换为空格,再将结果取出来排序,再进行结果的选择显示,不明白可查看 排序和分页

cat filename |grep -v '^[0-9]*$' | sed 's/|/ /g' |sort -nrk 8 -nrk 9 |tail -n+1 |head -n 10

 


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值