shell的logo含义_shell 脚本-符号-基础语法

为了便于识别  建议 以.sh 结尾

shell脚本 可以放上所有的命令行的指令(源于bash)

shell脚本 是 解释型语言      c/c++ 是编译型语言

下面用到的 shell代码sh_1.sh#!/bin/bash

cd ../

ls

pwd

解释型脚本的执行过程:

script.sh 是文本文件,根本没有代码段和 _start  函数 , exec 怎么执行。

解释:

Shell会fork 一个子进程并调用 exec执行 ./script.sh这个程序,exec 系统调用应该把子进程的代码

段替换成./script.sh程序的代码段 ,并从它的 _start开始执行。然而 script.sh是个文本文件,根 本

没有代码段和 _start函数 ,怎么办呢 ?其实 exec还有另外一种机制 ,如果要执行的是一个文本文

件, 并且第一行用 Shebang 指定了解释器 ,则用 解释器程序的代码段替换当前进程 ,并且从解释

器 的_start开始执行 ,而这个文本文件被当作命令行参数传给解释器 。因此, 执行上述脚本相

当于执 行程序

cc544e593ac504ba66506b87986376ac.png

1. 交互 Shell(bash)fork/exec一个子 Shell(sh)用于执行脚本 ,父进程 bash等待子进程 sh终止。

2. sh读取脚本中的 cd ..命令 ,调用相应的函数 执行内建命令 ,改变当前工作目录为上一级

目 录。

3. sh读取脚本中的 ls命令 ,fork/exec这个程序 ,列出当前工作目录下的文件 ,sh等待 ls终止。

4. ls终止后 ,sh继续执行 ,读到脚本文件末尾 ,sh终止。

5. sh终止后 ,bash继续执行 ,打印提示符等待用户输入。

如果将命令行下输入的命令用 ()括号括起来 ,那么也会 fork出一个子 Shell执行小括号中的命令 ,

一 行中可以输入由分号 ;隔开的多个命令 ,比如 : $ (cd ..;ls -l)

和上面两种方法执行 Shell脚本的效果是相同的 ,cd ..命令改变的是子 Shell的 PWD,而不会影响

到 交互式Shell。

chmod + x script.sh方式

sh文件中,cd ..命令改变的是子Shell的PWD,而不会影响到 交互式Shell1(对于文件sh, 交互式shell1会先创建一个子shell2,子shell2会再创建一个shell3,shell3遇见cd命令 会直接由shell2执行,改变的是shell2的路径,shell1的路径不变)。

然而source ./script.sh  和 . ./script.sh 方式

则有不同的效果,cd ..命令是直接在交互式Shell1下执行的,改变交互式Shell的PWD

对于php 。。。脚本语言  执行也是 解释器这个流程

sh_1.sh代码:

#!/bin/bash

cd ../

ls

pwd

[bozi@localhost 1_shell]$ /bin/bash sh_1.sh //  shell脚本中 cd   直接在子bash中运行  整个过程父进程 不参与

1_shell

/home/bozi/linux_test/shell

[bozi@localhost 1_shell]$ pwd

/home/bozi/linux_test/shell/1_shell            //    所以 不影响父进程 的路径   还在子进程的路径中

[bozi@localhost 1_shell]$ cd ..                //   cd内置命令 shell 自己直接亲自执行(不创建子进程) 影响自己的路径

[bozi@localhost shell]$ pwd

/home/bozi/linux_test/shell                // 直接执行 影响了 跑到上级目录

路径

[bozi@localhost shell]$ ll

总用量 4

drwxrwxr-x. 2 bozi bozi 4096 8月  14 10:18 1_shell

[bozi@localhost shell]$ cd 1_shell/

[bozi@localhost 1_shell]$ ll

总用量 4

-rw-rw-r--. 1 bozi bozi 298 8月  14 10:18 sh_1.sh

source  与(.    命令一样)

例子:

source  不创建子bash,遇见bash中有内建命令 cd    交互式shell(父进程自己直接执行)    所以 退出时 父进程的路径 变了  影响父进程

[bozi@localhost 1_shell]$ ll

总用量 4

-rw-rw-r--. 1 bozi bozi 298 8月  14 10:18 sh_1.sh

[bozi@localhost 1_shell]$ source sh_1.sh

1_shell

/home/bozi/linux_test/shell

[bozi@localhost shell]$ pwd

/home/bozi/linux_test/shell

.命令 效果相同

[bozi@localhost 1_shell]$ . sh_1.sh

1_shell

/home/bozi/linux_test/shell

[bozi@localhost shell]$ pwd

/home/bozi/linux_test/shell

set 显示 本地变量 和  环境变量(本地变量只存在当前进程中)

env 只显示环境变量   (环境变量 可以传递给 子进程  父子进程共享)

变量

shell 中  所有变量varname都是字符串 ,且都是全局本地变量     没有int ,float等类型 显示变量 用 $varname或 ${varname}

如果变量不存在    shell显示空串

变量拼接 用{}花括号    如:     ${varname}aaa    $varname"aaa"

演示代码:[bozi@localhost 2_shell]$ SHELL=1

[bozi@localhost 2_shell]$ echo $SHELL

1

[bozi@localhost 2_shell]$ echo $SHELLabc

[bozi@localhost 2_shell]$ echo ${SHELL}

1

[bozi@localhost 2_shell]$ echo ${SHELL}abc

1abc

unset 取消一个变量[root@localhost 2_shell]# v=a

[root@localhost 2_shell]# echo $v

a

[root@localhost 2_shell]# unset $v

[root@localhost 2_shell]#

显示本shell的pid[root@localhost 2_shell]# echo $$

6699

read

-p 提示符  -t 等待的秒数[bozi@localhost 2_shell]$ read -p ‘>>‘ -t 10 arg

>>nihao

[bozi@localhost 2_shell]$ echo $arg

nihao

数组变量var[1]="small min"

var[2]="big min"

var[3]="nice min"

echo "${var[1]}, ${var[2]},${var[3]}"

[bozi@localhost 2_shell]$ ./1_test.sh

small min, big min,nice min

test指令

两个整数之间的判定

-eq 相等(equal)

-ne 不等(not equal)

-gt 大于 (greaater than)

-lt 小于 (less than)

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

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

例子:[bozi@localhost 2_shell]$ test 1 -lt 2; echo $?

0                ---------------》【真】

[bozi@localhost 2_shell]$ test 5 -lt 2; echo $?

1

判定字符串的数据test -z string [string 为空  返回true]

test -n string [string 为空  返回false]

test str1 = str2 [str1=str2 回传true]

test str1 != str2 [str1 与str2相等返回 false]

例子:

[bozi@localhost 2_shell]$ test -z "";echo $?

0

[bozi@localhost 2_shell]$ test -z "-";echo $?

1

[bozi@localhost 2_shell]$ test -n "";echo $?

1

[bozi@localhost 2_shell]$ test -n "-";echo $?

0

[bozi@localhost 2_shell]$ test "nihao" = "hello" ; echo $?

1

[bozi@localhost 2_shell]$ test "nihao" == "hello" ; echo $?

1

[bozi@localhost 2_shell]$ test "nihao" != "hello" ; echo $?

0

error

[bozi@localhost 2_shell]$ test "nihao"=="hello" ; echo $?

0 ----》“==两边少空格  结果 不正确”

test扩展:

当要检测系统上面某些文件或者是相关的属性时,利用test这个命令来工作真是好用得不得了,如检查/dmtsai是否存在时,使用:test –e /dmtsai

上面的执行结果并不会显示任何信息,但最后可以通过$?或&&及||来显示整个结果。

test –e /dmtsai && echo “exist” ||echo “Not exist”

最终结果可以显示exist还是not exist。-e是测试一个东西存在不存在。常用的测试命令如下:

测试的标志代表意义

关于某个文件名的“文件类型”判断,如test – e filename表示存在否

-e该文件名是否存在

-f该文件名是否存在且为文件(file)

-d该文件名是否存在且为目录(directory)

-b该文件名是否存在且为一个block device设备

-c该文件名是否存在且为一个character device设备

-S该文件名是否存在且为一个Socket文件

-p该文件名是否存在且为一个FIFO(pipe)文件

-L该文件名是否存在且为一个连接文件

关于文件的权限检测,如test –r filename表示可读否(但root权限常有例外)

-r检测该文件名是否存在且具有“可读”的权限

-w检测该文件名是否存在且具有“可写”的权限

-x检测该文件名是否存在且具有“可执行”的权限

-u检测该文件名是否存在且具有“SUID”的属性

-g检测该文件名是否存在且具有“SGID“的属性

-k检测该文件名是否存在且具有“Sticky bit”的属性

-s检测该文件名是否存在且具有“非空白文件”

两个文件之间的比较,如test file1 –nt file2

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

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

-ef判断file1与file2是否为同一文件,可用在判断hard link的判定上。主要意义在于判定两个文件是否均指向同一个inode

关于两个整数之间的判定吗,如test n1 –eq n2

-eq两数值相等(equal)

-ne两数值不等(not equal)

-gtN1大于n2(greate than)

-ltN1小于n2(less than)

-geN1大于等于n2(greater than or equal)

-leN1小于等于n2(less than or equal)

判定字符串的数据

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

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

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

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

多重条件判定,若test –r filename –a –x filename

-a两个条件同时成立!如test –r file –a –x file,则file同时具有r与x权限时,才回传true

-o任何一个条件成立!如test –r file –o –x file,则file具有r或x权限时,就可回传true

!反向状态,如test ! –x file,但file不具有x时,回传true

多重条件判定

-a [先当于 与&&]

-o 【或】

! 【非】

例子:[bozi@localhost 2_shell]$ test 1 -eq 1 -a 2 -lt 5; echo $?

0

[bozi@localhost 2_shell]$ test 1 -eq 1 -a 5 -lt 2; echo $?

1

判断符号[][bozi@localhost 2_shell]$ [ "" ==  "HOME" ];echo $?

1

[bozi@localhost 2_shell]$ [ "" !=  "HOME" ];echo $?

0

error[bozi@localhost 2_shell]$ [ ""!="HOME" ];echo $?

0

[bozi@localhost 2_shell]$ [ ""=="HOME" ];echo $?

0

注意  空格不能少  否则出错:

[bozi@localhost 2_shell]$ [ 空格"" 空格==  空格"HOME" 空格];echo $?

建议:

1 在中括号[]中的每个组件用 空格 隔开

2 在中括号内的变量, 最好用双引号括起来

3 在中括号里面的常量最好用单引号或 双引号括起来

2的一个错误例子:[bozi@localhost 2_shell]$ name="hello world"

[bozi@localhost 2_shell]$ [ $name == "hello" ]

bash: [: too many arguments   --------------------------》  太多参数 本来是两个参数比较 因为name变量的字符串中间有空格 不加“”

解析为 [ hello world == "hello" ]   肯定参数太多

[bozi@localhost 2_shell]$ [ "$name" == "hello" ]

[bozi@localhost 2_shell]$ echo $?

1

[bozi@localhost 2_shell]$ [ "$name" != "hello" ]

[bozi@localhost 2_shell]$ echo $?

0

小练习:read -p "please inoput (Y/N):" yn

[ "$yn" == "Y" -o "$yn" == "y" ] && echo "ok, continue" && exit 0

[ "$yn" == "N" -o "$yn" == "n" ] && echo "oh, interrupt" && exit 0

echo "I dont know what your chonice is " && exit 0

运行:

[bozi@localhost 2_shell]$ ./1_test.sh

please inoput (Y/N):y

ok, continue

[bozi@localhost 2_shell]$ ./1_test.sh

please inoput (Y/N):n

oh, interrupt

[bozi@localhost 2_shell]$ ./1_test.sh

please inoput (Y/N):

I dont know what your chonice is

shell中&&和||的使用方法

&&运算符:

command1  && command2

&&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;换句话说,“如果这个命令执行成功&&那么执行这个命令”。

语法格式如下:

command1 && command2 [&& command3 ...]

1 命令之间使用 && 连接,实现逻辑与的功能。

2 只有在 && 左边的命令返回真(命令返回值 $? == 0),&& 右边的命令才会被执行。

3 只要有一个命令返回假(命令返回值 $? == 1),后面的命令就不会被执行。

||运算符:

command1 || command2

||则与&&相反。如果||左边的命令(命令1)未执行成功,那么就执行||右边的命令(命令2);或者换句话说,“如果这个命令执行失败了||那么就执行这个命令。

1 命令之间使用 || 连接,实现逻辑或的功能。

2 只有在 || 左边的命令返回假(命令返回值 $? == 1),|| 右边的命令才会被执行。这和 c 语言中的逻辑或语法功能相同,即实现短路逻辑或操作。

3 只要有一个命令返回真(命令返回值 $? == 0),后面的命令就不会被执行。

&& || 与 -a -o

区别

-a -o 连接的是两个表达式 即 测试条件

而 && 与 || 连接的是两条 命令

代码:val=10

str="hello"

test $val -eq 10 -a "$str" == "hello"

echo $?

test $val -eq 10 && test "$str" == "hello"

echo $?

运行:

[bozi@localhost 2_shell]$ ./12_test.sh

0

0

默认变量  $0 $1 $2 ...

例子:$ ./1_test.sh nihao sunshine

$0        $1        $2

$# :代表后接的参数的个数, 如上例子为2

$@:代表"$1" "$2" ... 之意, 每个变量独立的用双括号括起来

$*: 代表“$1c$2c$3c$4” c为分隔符号,默认是空格键

$@ 和 $*还是有所不同的 一般用 $@

代码:#! /bin/bash

echo "\$0 is $0"

echo "\$1 is $1"

echo "\$2 is $2"

echo "\$# is $#"

echo "\$@ is $@"

echo "\$* is $*"

运行:[bozi@localhost 2_shell]$ ./1_test.sh

$0 is ./1_test.sh

$1 is

$2 is

$# is 0

$@ is

$* is[bozi@localhost 2_shell]$ ./1_test.sh 1 2 3 4

$0 is ./1_test.sh

$1 is 1

$2 is 2

$# is 4

$@ is 1 2 3 4

$* is 1 2 3 4

代码:echo "your whole parameter is ===>$0"

echo "total parameter numbers is ===>$#"

[ "$#" -lt 2 ]&&echo "the numbers of paramater is less than 2. stop here"&& exit 0;

echo "your whole parameter is ===>$@"

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

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

运行:[bozi@localhost 2_shell]$ ./1_test.sh

your whole parameter is ===>./1_test.sh

total parameter numbers is ===>0

the numbers of paramater is less than 2. stop here

[bozi@localhost 2_shell]$ ./1_test.sh nihao sunshine

your whole parameter is ===>./1_test.sh

total parameter numbers is ===>2

your whole parameter is ===>nihao sunshine

the 1st parameter ===>nihao

the 2nd parameter ===> sunshine

运行:[bozi@localhost 1_shell]$ cat sh_1.sh

#!/bin/bash

myint=10

echo ‘\$ \\ $myint \"‘

echo ‘###############‘

echo "\$ \\ $myint \""

[bozi@localhost 2_shell]$ ./1_test.sh

your whole parameter is ===>./1_test.sh

total parameter numbers is ===>0

the numbers of paramater is less than 2. stop here

[bozi@localhost 2_shell]$ ./1_test.sh nihao sunshine

your whole parameter is ===>./1_test.sh

total parameter numbers is ===>2

your whole parameter is ===>nihao sunshine

the 1st parameter ===>nihao

the 2nd parameter ===> sunshine

[bozi@localhost 2_shell]$ ./1_test.sh nihao sunshine here

your whole parameter is ===>./1_test.sh

total parameter numbers is ===>3

your whole parameter is ===>nihao sunshine here

the 1st parameter ===>nihao

the 2nd parameter ===> sunshine

shift:造成参数号码偏移,移除前num个参数

shift+num  num 及num之前的参数全部移除   num之后的参数从$1开始

如:echo $@

echo "arg count $#"

shift 1

echo "after shift 1"

echo $@

echo "arg count $#"

shift 3

echo "after shift 3"

echo $@

echo "arg count $#"

运行:[bozi@localhost 2_shell]$ ./1_test.sh one two three four five six seven

one two three four five six seven

arg count 7

after shift 1

two three four five six seven

arg count 6

after shift 3

five six seven

arg count 3

条件判断式

1 if ... then

if [条件判断式];then

条件成立执行

fi

&&代表AND

|| 代表 or

代码:#!/bin/bash

read -p "please input (Y/N):" yn

if [ "X$yn" == "XY" ] || [ "X$yn" == "Xy" ];then

echo "ok, continue"

exit 0

fi

if [ "X$yn" == "XN" ] || [ "X$yn" == "Xn" ];then

echo "oh, interupt!"

exit 0

fi

运行:please input (Y/N):y

ok, continue

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):Y

ok, continue

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):N

oh, interupt!

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):n

oh, interupt!

多重复杂条件判断式

if [条件判断式];then

条件成立

else

...

if

if [条件判断式1];then

...

elif [条件判断式2];then

...

else

...

if

代码:read -p "please input (Y/N):"  yn

if [ "x$yn" == "xY" ] || [ "x$yn" == "xy" ]; then

echo "ok, continue"

elif [ "x$yn" == "xN" ] || [ "x$yn" == "xn" ]; then

echo "oh, interupt"

else

echo "I dont know what your choice is"

fi

运行:[bozi@localhost 2_shell]$ vim 2_test.sh

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):y

ok, continue

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):n

oh, interupt

[bozi@localhost 2_shell]$ ./2_test.sh

please input (Y/N):s

I dont know what your choice is

代码:

testing=$(netstat -tuln |grep ‘:80‘ )

if [ "X$testing" != "X" ];then

echo "WWW is running in your system ."

fi

testing=$(netstat -tuln | grep ‘:22‘)

if [ "X$testing" != "X" ]; then

echo "SSH is running in your system."

fi

testing=$(netstat -tuln | grep ‘:21‘)

if [ "X$testing" != "X" ]; then

echo "FTP is running in your system."

fi

testing=$(netstat -tuln | grep ‘:25‘)

if [ "X$tesing" != "X" ]; then

echo "Mail is running in your system."

fi

运行:[bozi@localhost 2_shell]$ ./3_text.sh

Now, I will detect your linux server‘s services!

The wwww, ftp, ssh , and mail will be detect !

SSH is running in your system.

利用case ......  esac判断

case $变量名称 in

”第1个变量名称“)

程序段

;;

”第2个变量名称“)

程序段

;;                                      # ;; 相当于break

*)                                                 #*)相当于default

程序段

;;

esac

代码:#!/bin/bash

case $1 in

"one")

echo "your choice is ONE"

;;

"two")

echo "your choice is TWO"

;;

"three")

echo "your choice is THREE"

;;

*)

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

;;

esac

运行:[bozi@localhost 2_shell]$ ./4_test.sh

Usage ./4_test.sh {one|two|three}

[bozi@localhost 2_shell]$ ./4_test.sh one

your choice is ONE

[bozi@localhost 2_shell]$ ./4_test.sh two

your choice is TWO

[bozi@localhost 2_shell]$ ./4_test.sh three

your choice is THREE

函数 function

函数的参数 也是$1$2$....    但是函数体里面的$1$2...与函数外面的 是相对独立的

函数返回值: return后    用  $? 来接收  【返回值】(缺陷  返回257   是 1        范围0-255)

代码:#!/bin/bash

function printit()             # 也可以不加关键字function  即  printit(){...}   也是可以的

{

echo -n "Your choice is "  #加上-n表示不断行继续在一行显示

}

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

运行:[bozi@localhost 2_shell]$ ./5_test.sh one

Your choice is ONE

[bozi@localhost 2_shell]$ ./5_test.sh

Usage ./5_test.sh {one|two|three}

[bozi@localhost 2_shell]$ ./5_test.sh one

Your choice is ONE

[bozi@localhost 2_shell]$ ./5_test.sh two

Your choice is TWO

[bozi@localhost 2_shell]$ ./5_test.sh three

Your choice is THREE

经典的fork炸弹   【!!!立马宕机】.() { .|.& }; .             #递归调用  后台执行

类似的  function a() { a|a }; a

防范措施 ulimit -Hu num  限定用户最多num个进程

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

以下程序段就是由Jaromil所作的在类UNIX系统的shell环境下触发fork炸弹的shell脚本代码,总共只用了13个字符(包括空格):

:(){ :|:& };:

注解如下:

:()# 定义函数,函数名为":",即每当输入":"时就会自动调用{}内代码

{# ":"函数开始标识

:# 用递归方式调用":"函数本身

|# 并用管道(pipe)将其输出引至...

:# 另一次递归调用的":"函数

# 综上,":|:"表示的即是每次调用函数":"的时候就会生成两份拷贝【二倍指数增长】

调用间脱钩,以使最初的":"函数被杀死后为其所调用的两个":"函数还能继续执行

}# ":"函数结束标识

;# ":"函数定义结束后将要进行的操作...

:# 调用":"函数,"引爆"fork炸弹

其中函数名“:”只是简化的一例,实际实现时可以随意设定,一个较易理解(将函数名替换为“forkbomb”)的版本如下:

forkbomb(){ forkbomb|forkbomb &} ; forkbomb

Windows下则可以批处理命令如下实现:

%0|%0

POSIX标准下的C与C++的实现:

#include int main(){while(1) fork();return0;}

Perl语言的实现:

fork while fork

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

循环

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

代码:#!/bin/bash

while [ "X$yn" != "Xyes" -a "X$yn" != "XYES" ]

do

read -p "please input yes/YES to stop this program:" yn

done

echo "ok, you input the correct answer."

运行:[bozi@localhost 2_shell]$ chmod u+x 6_test.sh

[bozi@localhost 2_shell]$ ./6_test.sh

please input yes/YES to stop this program:e

please input yes/YES to stop this program:e

please input yes/YES to stop this program:yes

ok, you input the correct answer.

until代码:sum=0

i=0

until [ $i -gt 100 ]

do

if (( i%2==0 ));then

let sum+=i

fi:

let i++

done

echo $sum

运行:[bozi@localhost 2_shell]$ ./6_test.sh

2550

代码:

s=0

i=0

while [ "$i" != "100" ]

do

i=$(($i+1))

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

done

echo "sum of 1+2+3+...+100 is : $s"

运行:[bozi@localhost 2_shell]$ ./7_test.sh

sum of 1+2+3+...+100 is : 5050

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

for var in con1 con2 con3 ...

do

程序段

done

代码:for animal in dog cat elephant

do

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

done

运行:

[bozi@localhost 2_shell]$ ./8_test.sh

there are dogs...

there are cats...

there are elephants...

代码:users=$(cut -d‘:‘ -f1 /etc/passwd)

for username in $users

do

id $username

done

运行:[bozi@localhost 2_shell]$ ./9_test.sh

uid=0(root) gid=0(root) 组=0(root)

uid=1(bin) gid=1(bin) 组=1(bin),2(daemon),3(sys)

uid=2(daemon) gid=2(daemon) 组=2(daemon),1(bin),4(adm),7(lp)

uid=3(adm) gid=4(adm) 组=4(adm),3(sys)

uid=4(lp) gid=7(lp) 组=7(lp)

uid=5(sync) gid=0(root) 组=0(root)

测ip代码:read -p "enter like 192.168.1->" network

for sitenu in $(seq 1 100)

do

ping -c 1 -w 1 ${network}.${sitenu} &>/dev/null && result=0 || result=1

if [ "$result" == 0 ];then

echo "server ${network}.${sitenu} is up."

else

echo "server ${network}.${sitenu} is down"

fi

done

运行:[bozi@localhost 2_shell]$ ./9_test.sh

enter like 192.168.1->192.168.174

server 192.168.174.1 is up.

server 192.168.174.2 is up.

server 192.168.174.3 is down

server 192.168.174.4 is down

server 192.168.174.5 is down

server 192.168.174.6 is down

server 192.168.174.7 is down

代码:#!/bin/bash

read -p "please input a diretory:" dir

if [ "$dir" == "" -o ! -d "$dir" ];then

echo "then $dir is not exist in your system."

exit 1

fi

filelist=$(ls $dir)

for filename in $filelist

do

perm=""

test -r "$dir/$filename" && perm="$perm readable"

test -w "$dir/$filename" && perm="$perm writable"

test -x "$dir/$filename" && perm="$perm executable"

echo "the file $dir/$filename‘s permission is $perm"

done

运行:[bozi@localhost 2_shell]$ ./10_test.sh

please input a diretory:../1_shell

the file ../1_shell/2‘s permission is  readable writable

the file ../1_shell/3‘s permission is  readable writable

the file ../1_shell/sh_1.sh‘s permission is  readable writable

the file ../1_shell/sh_2.sh‘s permission is  readable writable executable

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

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

do

程序段

done

这种写法 适合在数值运算中

代码:read -p "please input a number . I will count for 1+2+3+...+your_input" num

s=0

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

do

((s += i))

done

echo "the result of ‘1+2+3+...+$num ‘is $s"

运行:[bozi@localhost 2_shell]$ ./11_test.sh

please input a number . I will count for 1+2+3+...+your_input10

the result of ‘1+2+3+...+10 ‘is 55

代码:

#!/bin/bash

for i in {A..b}

do

echo "val is: $i"

done

运行:[bozi@localhost 2_shell]$ sh 14_test.sh

val is: A

val is: B

val is: C

val is: D

val is: E

val is: F

val is: G

val is: H

val is: I

val is: J

val is: K

val is: L

val is: M

val is: N

val is: O

val is: P

val is: Q

val is: R

val is: S

val is: T

val is: U

val is: V

val is: W

val is: X

val is: Y

val is: Z

val is: [

val is:

val is: ]

val is: ^

val is: _

val is: `

val is: a

val is: b

shell script 的  追踪 与  debug

-n : 不执行script,仅查询语法错误

-v: 在执行script之前,现将script的内容输出到屏幕上

-x: 将使用到的script内容显示到屏幕上

代码:

检查是否有语法问题    没有问题就什么也不输出

运行:

[bozi@localhost 2_shell]$ sh -n 12_test.sh

[bozi@localhost 2_shell]$

代码:

将使用到的代码显示出来

运行:[bozi@localhost 2_shell]$ sh -x 12_test.sh

+ val=10

+ str=hello

+ test 10 -eq 10 -a hello == hello

+ echo 0

0

+ test 10 -eq 10

+ test hello == hello

+ echo 0

0

一是在命令行提供参数

$ sh -x ./script.sh

二是在脚本开头提供参数

#! /bin/sh -x

第三种方法是在脚本中用 set命令启用或禁用参数

set -x和set +x 分别表示启用和禁用 -x参数 ,这样可以只对脚本中的某一段进行跟踪调试。

代码:val=10

str="hello"

set -x

test $val -eq 10 -a "$str" == "hello"

echo $?

set +x

test $val -eq 10 && test "$str" == "hello"

echo $?

运行:[bozi@localhost 2_shell]$ sh -x 12_test.sh

+ val=10

+ str=hello

+ set -x

+ test 10 -eq 10 -a hello == hello

+ echo 0

0

+ set +x

0

:是一个特殊的命令,称为空命令 ,该命令不做任何事,但 Exit Status总是真。此外 ,也可以执 行

/bin/true或 /bin/false得到真或假的 Exit Status。

文件名替换

这些用于匹配的字符称为通配符 (Wildcard),具体如下 :

通配符 * : 匹配 0个或多个 任意字符

? : 匹配 一个任意 字符

[若干字符 ] : 匹配 方括号中任意一个字符的一次出现运行:

[bozi@localhost 1_shell]$ ls *

2  3  sh_1.sh  sh_2.sh

[bozi@localhost 1_shell]$ ls sh_?.sh

sh_1.sh  sh_2.sh

[bozi@localhost 1_shell]$ ls [s]h*

sh_1.sh  sh_2.sh

注意, Globbing 所匹配的文件名是由 Shell展开的 ,也就是说在参数还没传给程序之前已经展开

了 ,不是ls展开的

命令代换:

由反引号``括起来的也是一条命令 ,Shell先执行该命令 ,然后将输出结果立刻代换到当前命令行

中。[bozi@localhost 1_shell]$ DATE=‘date‘

[bozi@localhost 1_shell]$ echo $DATE

date

[bozi@localhost 1_shell]$ DATE=`date`

[bozi@localhost 1_shell]$ echo $DATE

2016年 08月 21日 星期日 11:05:13 CST

例如定义一个变量存放 date命令的输出 :

命令代换也可以用 $()表示 : $ DATE=$(date)[bozi@localhost 1_shell]$ DATE=$(date)

[bozi@localhost 1_shell]$ echo $DATE

2016年 08月 21日 星期日 11:05:56 CST

算术代换 :$(())

用于算术计算 ,$(())中的 Shell变量取值将转换成整数 ,例如 :[bozi@localhost 1_shell]$ v=3

[bozi@localhost 1_shell]$ echo $((v+3))

6

$(())中只能用+-*/ 和()运算符 ,并且只能做整数运算。

(( )) 中间支持c语言的写法[bozi@localhost 1_shell]$ i=1;(( i++));echo $i

2

[bozi@localhost 1_shell]$ i=1;(( i+=5));echo $i

6

[bozi@localhost 1_shell]$ i=1;(( i>0));echo $?

0

[bozi@localhost 1_shell]$ i=1;(( i<0));echo $?

1

shell进度条小程序

代码:#!/bin/bash

function proc()

{

i=0;

str=‘‘

arr=(‘|‘ ‘/‘ ‘-‘ ‘\\‘)

index=0

while [ $i -le 100 ]

#while ((i <= 100))

do

printf "[%-100s][%d%%][%c]\r" "$str" "$i" "${arr[$index]}"

#这里不用像c语言一样fflush刷新输出缓冲区 因为 printf是子进程执行

# 子进程退出自动刷新

str=${str}‘#‘

sleep 0.1

let i++

let index++

let index%=4

#((index%=4))

done

printf "\n"

}

function main()

{

proc

}

main

运行:[bozi@localhost 4_shell]$ sh proc.sh

#########################################################################                          ][74%][-]

读取文件数据  计算最大和最小值、平均值

代码:

#找 文件中的最大值和 最小值max=0

min=0

count=0

sum=0

while read line

do

if [ "$count" -eq "0" ];then

max=$line

min=$line

let count++

let sum+=$line

continue

fi

[ "$max" -lt "$line" ] && max=$line

[ "$min" -gt "$line" ] && min=$line

let sum+=$line

let count++

done 

echo $max

echo $min

echo "ibase=10 ;scale=2; $sum/$count" | bc

数据:[bozi@localhost 4_shell]$ cat file

1

2

3

4

5

6

7

8

9

运行:[bozi@localhost 4_shell]$ sh ./5_shell.sh

9

1

5.00

建议数字计算 用(())  不用[  ]    []对于空数据报错

如数据第四行空file

[bozi@localhost 4_shell]$ cat file

1

2

3

5

6

7

8

9

(())结果

if (( line 

[bozi@localhost 4_shell]$ vim test.sh

[bozi@localhost 4_shell]$ sh  ./test.sh

1

2

3

5

6

7

8

error

[]结果 if [ "$line" -lt  "9" ];then[bozi@localhost 4_shell]$ sh  ./test.sh

1

2

3

./test.sh: line 11: ((: 

error

5

6

7

8

error

数组

1 数组的定义

一对()表示数组 数组元素用 空格 符号作为分隔符[bozi@localhost 4_shell]$ a=(1 2 3 4 5)

[bozi@localhost 4_shell]$ echo $a

1

[bozi@localhost 4_shell]$ echo ${a[*]}

1 2 3 4 5

[bozi@localhost 4_shell]$ str=(‘q‘ "nihao" ‘hello‘)

[bozi@localhost 4_shell]$ echo $str

q

[bozi@localhost 4_shell]$ echo ${str[@]}

q nihao hello

2 数组的读取与赋值(下标从0开始)

赋值:[bozi@localhost 4_shell]$ a[10]=10

读取:[bozi@localhost 4_shell]$ echo ${a[*]}

1 2 3 4 5 10[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 10

得到长度:

得到整个数组长度[bozi@localhost 4_shell]$ echo ${#a[*]}

6

[bozi@localhost 4_shell]$ echo ${#a[@]}

6

得到数组某个元素的长度[bozi@localhost 4_shell]$ a=(1 2 3 4 5 10)

[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 10

[bozi@localhost 4_shell]$ echo ${#a[5]}

2

[bozi@localhost 4_shell]$ echo ${#a[0]}

1

删除:[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 10

#删除某个元素[bozi@localhost 4_shell]$ unset a[2]

[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 4 5 10

#删除整个数组[bozi@localhost 4_shell]$ unset a

[bozi@localhost 4_shell]$ echo ${a[@]}

[bozi@localhost 4_shell]$

3.特殊使用:

分片:

$[数组名{@或*]起始位置:长度} 从起始位置开始 切长度个元素

返回的是字符串  中间用空格隔开

所以如果加上"()" , 将的到切片的数组。[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 6

[bozi@localhost 4_shell]$ echo ${a[@]:0:3}

1 2 3

[bozi@localhost 4_shell]$ echo ${a[@]:2:3}

3 4 5

[bozi@localhost 4_shell]$ echo ${a[@]:2:5}

3 4 5 6

[bozi@localhost 4_shell]$ echo ${a[@]:1:5}

2 3 4 5 6

加上"()" , 将的到切片的数组。[bozi@localhost 4_shell]$ echo ${a[@]:1:5}

2 3 4 5 6

[bozi@localhost 4_shell]$ newa=(${a[@]:1:5})

[bozi@localhost 4_shell]$ echo ${newa[@]}

2 3 4 5 6

替换:

调用方法是: ${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先的内容, 如果需要修改, 可以像上面一样  加() 生成一个新的数组[bozi@localhost 4_shell]$ a=(1 2 3 4 5 6)

[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 6

[bozi@localhost 4_shell]$ echo ${a[@]/3/100}

1 2 100 4 5 6

[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 3 4 5 6

原内容 未改变

要改变原内容 加()[bozi@localhost 4_shell]$ a=(${a[@]/3/100})

[bozi@localhost 4_shell]$ echo ${a[@]}

1 2 100 4 5 6

[bozi@localhost 4_shell]$ str=("nihao" hello)

[bozi@localhost 4_shell]$ echo ${str[@]}

nihao hello

[bozi@localhost 4_shell]$ echo ${str[@]/ni/wo}

wohao hello

[bozi@localhost 4_shell]$ str=("nihao" "hello" "here")

[bozi@localhost 4_shell]$ echo ${str[@]}

nihao hello here

[bozi@localhost 4_shell]$ echo ${str[@]/he/the}

nihao thello there

遍历数组:arr=(aaa bbb ccc ddd)

num=${#arr[@]}

for ((i = 0; i 

{

echo ${arr[i]}

}

[bozi@localhost 4_shell]$ sh arr.sh

aaa

bbb

ccc

ddd

特殊arr=(aaa bbb ccc ddd)

arr[50]="ffff"

num=${#arr[*]}

for ((i = 0; i 

{

echo ${arr[i]}

}

结果  多了一个元素arr[50]  读也是读五个 只不过是从前向后读 没有读到arr[50] 读到空

这里${#arr[*]}和 ${#arr[@]}都是5[bozi@localhost 4_shell]$ sh arr.sh

aaa

bbb

ccc

ddd

[bozi@localhost 4_shell]$ cat arr.sh

下面这种方式解决读到空的问题 没有读到后面的有效数字

代码:arr=(aaa bbb ccc ddd)

arr[50]="ffff"

num=${#arr[*]}

for var in ${arr[*]}

#for var in ${arr[@]}       这两个效果一样 都能访问到定义了的数据

{

echo $var

}

运行:[bozi@localhost 4_shell]$ sh arr.sh

aaa

bbb

ccc

ddd

ffff[bozi@localhost 4_shell]$ for var in ${arr[*]}; do echo $var;let i++;done

a

b

c

hello

[bozi@localhost 4_shell]$ arr[100]="iam100"

[bozi@localhost 4_shell]$ for var in ${arr[*]}; do echo $var;let i++;done

a

b

c

hello

iam100

[bozi@localhost 4_shell]$ [bozi@localhost 4_shell]$ for var in ${arr[*]}; do echo $var;let i++;done

a

b

c

hello

[bozi@localhost 4_shell]$ arr[100]="iam100"

[bozi@localhost 4_shell]$ for var in ${arr[*]}; do echo $var;let i++;done

a

b

c

hello

iam100

[bozi@localhost 4_shell]$ for var in ${arr[@]}; do echo $var;let i++;done

a

b

c

hello

iam100

[bozi@localhost 4_shell]$ i=0;while ((i 

a

b

c

hello

[bozi@localhost 4_shell]$ i=0;while ((i 

a

b

c

hello

[bozi@localhost 4_shell]$

${arr[@]}; do echo $var;let i++;done

a

b

c

hello

iam100

[bozi@localhost 4_shell]$ i=0;while ((i 

a

b

c

hello

[bozi@localhost 4_shell]$ i=0;while ((i 

a

b

c

hello

[bozi@localhost 4_shell]$

从这个 例子可以看出

for var in种方式访问的是 有效元素的个数

for ((i = 0; i < len;i++)) 是从前向后找 ,找len个就停止,后面隔着的有些有效的数据就没有输出

count=0; while [ $count -le 100] touch test${count};

数学运算((  ))中变量直接取得是 变量的值

v1=1

v2=2

((v3 = v1 + v2))    //    (($v3 = $v1 + $v2)) 也可以

echo $(v3)

echo $(arr[*])   显示所有的元素 (空的丢弃)

echo $(arr[@])   显示所有的元素

echo $(#arr[@]) 显示 已经定义的元素的个数    如   arr

遍历数组

for i in $(arr[@])

do

echo $(arr[i])

done

单引号 双引号

单引号 对转义、特殊的变量 都不会 进行处理  原样输出

双引号                                      会处理

[bozi@localhost 1_shell]$ /bin/bash sh_1.sh

10

\$ \\ $myint \"

###############

$ \ 10 "

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值