最新消息:博主的视频课程:Django高级实战教程 开发企业级问答网站开发

鸟哥Linux基础篇-学习Shell Scripts

Linux liaogx 来源:西部世界 575浏览 0评论

12.2.2 script 的执行方式差异source sh script ./script

利用直接执行的方式来执行script

当使用直接执行的方法来处理时,系统会给予一支新的bash让我们来执行脚本里面的指令,因此变量其实是在下图中的子程序bash内执行的。当脚本执行完毕后,子程序bash内的所有数据便被移除。

利用source来执行脚本:在父程序中执行

脚本会在父程序中执行的,因此各项动作都会在原本的bash内生效!这也是为啥你不登出系统而要让某些写入 ~/.bashrc 的设置生效时,需要使用“source ~/.bashrc”而不能使用“bash ~/.bashrc”的原因。

12.3.1 利用 test 指令的测试功能

[dmtsai@study ~]$ test -e /dmtsai && echo “exist” || echo “Not exist”  Not exist <==结果显示不存在啊!

测试的标志 代表意义
1. 关于某个文件名的“文件类型”判断,如 test -e filename 表示存在否
-e 该“文件名”是否存在?(常用)
-f 该“文件名”是否存在且为文件(file) ?(常用)
-d 该“文件名”是否存在且为目录(directory) ?(常

用)

-b 该“文件名”是否存在且为一个 block device 设备?
-c 该“文件名”是否存在且为一个 character device 设

备?

-S 该“文件名”是否存在且为一个 Socket 文件?
-p 该“文件名”是否存在且为一个 FIFO (pipe) 文件?
-L 该“文件名”是否存在且为一个链接文件?
2. 关于文件的权限侦测,如 test-r filename 表示可读否 (但 root权限常有例外)
-r 侦测该文件名是否存在且具有“可读”的权限?
-w 侦测该文件名是否存在且具有“可写”的权限?
-x 侦测该文件名是否存在且具有“可执行”的权限?
-u 侦测该文件名是否存在且具有“SUID”的属性?
-g 侦测该文件名是否存在且具有“SGID”的属性?
-k 侦测该文件名是否存在且具有“Sticky bit”的属性?
-s 侦测该文件名是否存在且为“非空白文件”?
3. 两个文件之间的比较,如:test file1 -nt file2
-nt (newer than) 判断 file1 是否比 file2 新
-ot (older than) 判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一文件,可用在判断hard link 的判定上。 主要意义在判定,两个文件是

否均指向同一个 inode 哩!

4. 关于两个整数之间的判定,例如 test n1 -eq n2
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
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
6. 多重条件判定,例如: test -r filename -a -x filename (and) 两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true
-o (or) 两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true

[dmtsai@study bin]$ vim file_perm.sh

#!/bin/bash

# 1\. 让使用者输入文件名,并且判断使用者是否真的有输入字串?

echo -e “Please input a filename, I will check the filename’s type and permission. \n\n”

read -p “Input a filename : ” filename

test -z ${filename} && echo “You MUST input a filename.” && exit 0

# 2\. 判断文件是否存在?若不存在则显示讯息并结束脚本

test ! -e ${filename} && echo “The filename ‘${filename}’ DO NOT exist” && exit 0

# 3\. 开始判断文件类型与属性

test -f ${filename} && filetype=”regulare file”

test -d ${filename} && filetype=”directory”

test -r ${filename} && perm=”readable”

test -w ${filename} && perm=”${perm} writable”

test -x ${filename} && perm=”${perm} executable”

# 4\. 开始输出信息!

echo “The filename: ${filename} is a ${filetype}”

echo “And the permissions for you are : ${perm}”

12.3.2 利用判断符号[]

在中括号[]内的每个元件都需要有空白键来分隔;在中括号内的变量,最好都以双引号括号起来;在中括号内的常数,最好都以单或双引号括号起来。

[dmtsai@study bin]$ vim ans_yn.sh

#!/bin/bash

read -p “Please input (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 don’t know what your choice is” && exit 0

12.3.3 Shell script 的默认变量($0, $1…

/path/to/scriptname opt1 opt2  opt3 opt4
$0  $1  $2  $3  $4

[dmtsai@study bin]$ vim how_paras.sh

#!/bin/bash

echo “The script name is ==> ${0}”

echo “Total parameter number is ==> $#”

[ “$#” -lt 2 ] && echo “The number of parameter is less than 2\. Stop here.” && exit 0

echo “Your whole parameter is ==> ‘$@'”

echo “The 1st parameter ==> ${1}”

echo “The 2nd parameter ==> ${2}

 

[dmtsai@study bin]$ sh how_paras.sh theone haha quot

The script name is ==> how_paras.sh <==文件名

Total parameter number is ==> 3 <==果然有三个参数

Your whole parameter is ==> ‘theone haha quot’ <==参数的内容全部

The 1st parameter ==> theone <==第一个参数

The 2nd parameter ==> haha <==第二个参数

12.4 条件判断式

[dmtsai@study bin]$ vim netstat.sh

#!/bin/bash

# 1\. 先作一些告知的动作而已~

echo “Now, I will detect your Linux server’s services!”

echo -e “The www, ftp, ssh, and mail(smtp) will be detect! \n”

# 2\. 开始进行一些测试的工作,并且也输出一些信息啰!

testfile=/dev/shm/netstat_checking.txt

netstat -tuln > ${testfile} # 先转存数据到内存当中!不用一直执行 netstat

testing=$(grep “:80 ” ${testfile}) # 侦测看 port 80 在否?

if [ “${testing}” != “” ]; then

echo “WWW is running in your system.”

fi

testing=$(grep “:22 ” ${testfile}) # 侦测看 port 22 在否?

if [ “${testing}” != “” ]; then

echo “SSH is running in your system.”

fi

testing=$(grep “:21 ” ${testfile}) # 侦测看 port 21 在否?

if [ “${testing}” != “” ]; then

echo “FTP is running in your system.”

fi

testing=$(grep “:25 ” ${testfile}) # 侦测看 port 25 在否?

if [ “${testing}” != “” ]; then

echo “Mail is running in your system.”

fi

 

[dmtsai@study bin]$ vim cal_retired.sh

#!/bin/bash

# 1\. 告知使用者这支程序的用途,并且告知应该如何输入日期格式?

echo “This program will try to calculate :”

echo “How many days before your demobilization date…”

read -p “Please input your demobilization date (YYYYMMDD ex>20150716) : ” date2

# 2\. 测试一下,这个输入的内容是否正确?利用正则表达式啰~

date_d=$(echo ${date2} |grep ‘[0-9]\{8\}’) # 看看是否有八个数字

if [ “${date_d}” == “” ]; then

echo “You input the wrong date format….”

exit 1

fi

# 3\. 开始计算日期啰~

declare -i date_dem=$(date –date=”${date2}” +%s) # 退伍日期秒数

declare -i date_now=$(date +%s) # 现在日期秒数

declare -i date_total_s=$((${date_dem}-${date_now}) ) # 剩余秒数统计

declare -i date_d=$((${date_total_s}/60/60/24) ) # 转为日数

if [ “${date_total_s}” -lt “0” ]; then # 判断是否已退伍

echo “You had been demobilization before: ” $((-1*${date_d}) ) ” ago”

else

declare -i date_h=$(($((${date_total_s}-${date_d}*60*60*24) ) /60/60) )

echo “You will demobilize after ${date_d} days and ${date_h} hours.”

fi

12.6 shell script 的追踪与 debug

[dmtsai@study ~]$ sh [-nvx] scripts.sh

选项与参数:

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

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

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

范例一:测试 dir_perm.sh 有无语法的问题?

[dmtsai@study ~]$ sh -n dir_perm.sh

# 若语法没有问题,则不会显示任何信息!

 

范例二:将 show_animal.sh 的执行过程全部列出来~

[dmtsai@study ~]$ sh -x show_animal.sh

+ PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/root/bin

+ export PATH

+ for animal in dog cat elephant

+ echo ‘There are dogs…. ‘

There are dogs….

+ for animal in dog cat elephant

+ echo ‘There are cats…. ‘

There are cats….

+ for animal in dog cat elephant

+ echo ‘There are elephants…. ‘

There are elephants….

本章练习

一、请创建一支script ,当你执行该script的时候,该script可以显示: 1. 你目前的身份(用 whoami ) 2. 你目前所在的目录 (用 pwd)

#!/bin/bash

echo -e “Your name is ==> $(whoami) ”

echo -e “The current directory is ==> $(pwd) ”

二、请自行创建一支程序,该程序可以用来计算“你还有几天可以过生日”啊?

#!/bin/bash

read -p “Pleas input your birthday (MMDD, ex> 0709) : ” bir

now=`date +%m%d`

if [ “$bir” == “$now” ]; then

echo “Happy Birthday to you!!!”

elif [ “$bir” -gt “$now” ]; then

year=`date +%Y`

total_d=$(($((`date –date=”$year$bir” +%s`-`date +%s`) ) /60/60/24) )

echo “Your birthday will be $total_d later”

else

year=$((`date +%Y`+1) )

total_d=$(($((`date –date=”$year$bir” +%s`-`date +%s`) ) /60/60/24) )

echo “Your birthday will be $total_d later”

fi

三、让使用者输入一个数字,程序可以由1+2+3… 一直累加到使用者输入的数字为止。

#!/bin/bash

read -p “Please input an integer number: ” number

i=0

s=0

while [ “$i” != “$number” ]

do

i=$(($i+1) )

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

done

echo “the result of ‘1+2+3+…$number’ is ==> $s”

四、撰写一支程序,他的作用是: 1.) 先查看一下 /root/test/logical 这个名称是否存在; 2.)若不存在,则创建一个文件,使用touch来创建,创建完成后离开; 3.) 如果存在的话,判断该名称是否为文件,若为文件则将之删除后创建一个目录,文件名为logical ,之后离开; 4.) 如果存在的话,而且该名称为目录,则移除此目录!

#!/bin/bash

if [ ! -e logical ]; then

touch logical

echo “Just make a file logical”

exit 1

elif [ -e logical ] && [ -f logical ]; then

rm logical

mkdir logical

echo “remove file ==> logical”

echo “and make directory logical”

exit 1

elif [ -e logical ] && [ -d logical ]; then

rm -rf logical

echo “remove directory ==> logical”

exit 1

else

echo “Does here have anything?”

fi

五、我们知道/etc/passwd里面以 : 来分隔,第一栏为帐号名称。请写一只程序,可以将/etc/passwd的第一栏取出,而且每一栏都以一行字串“The 1 account is “root” ”来显示,那个1表示行数。

#!/bin/bash

accounts=`cat /etc/passwd | cut -d’:’ -f1`

for account in $accounts

do

declare -i i=$i+1

echo “The $i account is \”$account\” ”

done

转载请注明:西部世界 » 鸟哥Linux基础篇-学习Shell Scripts

发表我的评论
取消评论

表情