linux随笔-3

条件执行

  • if/then
if [ condition ] 
then
statement(s)
fiif [ condition ]; then statement(s);fi

例:

[root@localhost tmp]#cat Test_failure
#!/bin/bash
#测试,通过脚本返回值判断 脚本执行是否成功。 0为成功,其他为失败。
#查看 文本$1

cat "$1"
if [ "$?" -ne "0" ]; then 
echo "Error: Read $1 failed."
fi

[root@localhost tmp]# cat Test_failure_better 
#!/bin/bash
#测试,通过脚本返回值判断 脚本执行是否成功。 0为成功,其他为失败。
#查看 文本$1
if [ ! -r "$1" ]; then 
echo "Error: Read $1 is not readable file."
echo "Quitting"
exit 1
fi
cat "$1"
[root@localhost tmp]# 
  • else
  • elif
  • test([)
    上面例子中,使用了-r 测试来检查文件是否存在且可读。
    test手册中有更多的附有详细文档的测试。
    test本身是一个程序,通常作为shell的内置命令
[root@localhost tmp]# type test
test is a shell builtin
[root@localhost tmp]# type [
[ is a shell builtin
[root@localhost tmp]# which test
/usr/bin/test
[root@localhost tmp]# which [
/usr/bin/[
[root@localhost tmp]# ls -il /usr/bin/test /usr/bin/[
1063532 -rwxr-xr-x. 1 root root 37000 417 2012 /usr/bin/[
1053571 -rwxr-xr-x. 1 root root 33808 417 2012 /usr/bin/test
[root@localhost tmp]# 

通过多种方法测试 /etc/hosts是否为常规文件:

[root@localhost tmp]# test -f /etc/hosts
[root@localhost tmp]# echo $?
0
[root@localhost tmp]# /usr/bin/test /etc/hosts
[root@localhost tmp]# echo $?
0
[root@localhost tmp]# [ -f /etc/host
host.conf    hosts        hosts.allow  hosts.deny   
[root@localhost tmp]# [ -f /etc/hosts ]
[root@localhost tmp]# echo $?
0
[root@localhost tmp]# 

测试/etc/stsoh不是常规文件:

[root@localhost tmp]# test -f /etc/stsoh
[root@localhost tmp]# echo $?
1
[root@localhost tmp]# /usr/bin/test /etc/stsoh
[root@localhost tmp]# echo $?
0
[root@localhost tmp]# [ -f /etc/stsoh ]
[root@localhost tmp]# echo $?
1
[root@localhost tmp]#
  • 测试标志
    测试文件是否存在,使用-e 标志(e表示 exists)。-a 标志与-e含义相同。
if [ -e /etc/resolv.conf ]; then
    echo "DNS Configuration: "
    cat /etc/resolv.conf
else
    echo "No DNS resolv.conf file exists."
fi

-f 测试文件是否存在且为常规文件。
-b 测试文件是否为快设备。
-c 测试文件是否为字符设备
-L测试或者-h 测试是否为符号链接
-S测试是否为套接字
-p测试是否为命名管道(FIFO)

测试文件的类型:

[root@localhost tmp]# cat ./blockcharacterfile.sh 
#!/bin/bash
while read -p "what file do you want to test? " filename
do
if [ ! -e "$filename" ]; then
    echo "The file does not exist."
    continue
fi

#Okay,the file exists.
ls -ld "$filename"

if [ -L "$filename" ]; then
    echo "$filename is a symbolic link"
elif [ -f "$filename" ]; then
    echo "$filename is a regular file."
elif [ -b "$filename" ]; then
    echo "$filename is a block device "
elif [ -c "$filename" ]; then
    echo "$filename is a character device "
elif [ -d "$filename" ]; then
    echo "$filename is a directory "
elif [ -p "$filename" ]; then
    echo "$filename is a named pipe"
elif [ -S "$filename" ]; then
    echo "$filename is a socket"
else
    echo "I don't know what kind of file that is .Is this a Linux system?"
fi
done
[root@localhost tmp]# 

常使用-d标志的脚本之一 是/etc/profile脚本。该脚本能在当前系统状态下对用户环境进行自定义。下面的代码将~/bin添加到PATH环境变量中,但只有当该目录存在的时候才添加:

if[ -d ~/bin ]; then
    PATH=$PATH:~/bin
fi

测试文件属性的标志:
-r 读(R)
-w 写(W)
-x 执行(X)
测试测试会话对测试文件是否具有读、写、执行权限。

[root@localhost tmp]# cat rwx.sh 
#!/bin/bash
while read -p "What file do you want to test? " filename
do 
if [ ! -e "$filename" ]; then
    echo "The file does not exists."
    continue
fi

#Okay,the file exists.
ls -ld "$filename"

if [ -r "$filename" ]; then
    echo "$filename is readable."
fi
if [ -w "$filenanme" ]; then
    echo "$filename is writeable."
fi
if [ -x "$filename" ]; then
    echo "$filename is executeable."
fi
done
[root@localhost tmp]# 

-O和-G 测试文件是否属于当前用户和/或组ID

[root@localhost tmp]# cat owner.sh 
#!/bin/bash
while read -p "What file do you want to test? " filename
do 
if [ ! -e "$filename" ]; then
    echo "The file does not exists."
    continue
fi
#Okay,the file exists.
ls -ld $filename
if [ -O $filename ];then
    echo "You own $filename"
else
    echo "Your don't own $filename"
fi
if [ -G $filename ]; then
    echo "You group owns $filename"
else 
    echo "Your group doesn't own $filename"
fi
done
[root@localhost tmp]# 

unix风格的文件权限另一个特性是suid、sgid。它们允许程序以文件所属用户(或组)的身份运行,这在rwx模式中使用s而不是x来表示文件权限,我们可以分别使用-g、-u来测试这两个权限。

[root@localhost tmp]# cat suid.sh 
#!/bin/sh
while read -p "What file do you want to test? " filename
do 
if [ ! -e "$filename" ]; then
    echo "The file does not exists."
    continue
fi

#Okay,the file exists.
ls -ld $filename
if [ -u $filename ];then
    echo "$filename will run as user \" `stat --printf=%U $filename` \" "
fi
if [ -g $filename ];then
    echo "$filename will run as group \" `stat --printf=%G $filename`\" "
fi 
done

[root@localhost tmp]# 

查看日志是否写入,检查文件是否含有任何内容:
使用 -s标志能测试文件是否存在且不为空,可以与-e组合来进行检查文件是否存在并不为空。

[root@localhost tmp]# cat mce.sh 
#!/bin/sh
if [ -s /var/log/mcelog ]; then
    echo "Machine Check Exceptions found :"
    wc -l /var/log/mcelog
fi

[root@localhost tmp]# ./mce.sh 
Machine Check Exceptions found :
274 /var/log/mcelog
[root@localhost tmp]# 

有时需要在文件包含新内容时读取它。命名管道是个较好的方案,但是有时却无法选择数据的生成方式。此时,使用-N标志检测文件自从上次读取之后是否被修改。可以使用脚本对-N测试的功能进行演示–图形环境下可以在两个不同的窗口运行脚本,或者使用连接到服务器的两个独立会话。

echo hello > /tmp/myfile.log
echo hello world >> /tmp/myfile.log

[root@localhost tmp]# cat watchfile.sh 
#!/bin/bash
GAP=10 #how long to wait
LOGFILE=$1 #file to log to

#Get the current length of the file.
len=`wc -l $LOGFILE | awk '{print $1}'`
echo "Current size is $len lines"
while :
do
    if [ -N $LOGFILE ];then
        echo "`date`: new entries in $LOGFILE:"
        newlen=`wc -l $LOGFILE | awk '{print $1}'`
        newlines=`expr $newlen - $len`
        tail -$newlines $LOGFILE
        len=$newlen
    fi
    sleep $GAP
done
[root@localhost tmp]# 
./watchfile.sh /tmp/myfile.log 
Current size is 3 lines
现在从一个独立的窗口运行下面的命令:
 echo this is a test >> /tmp/myfile.log
在第一个窗口中,我们将在$GAP秒(本例中是10秒)内看到下面的输出:
20150811日 星期二 10:20:02 CST: new entries in /tmp/myfile.log:
this is a test
只有当文件发生变化时,watchfile.sh才显示数据,还可以增加$GAP的值,来获取更多的输入时间。

这是一个查看文件的增量变化的有效方法,甚至更适合于cron任务。

  • 文件比较测试
    test命令还能对文件进行一些基本的比较操作,-ef 比较两个文件是否为同一文件系统中相同的inode节点的硬链接。这省去很多麻烦,因为尽管stat –format=%i或者ls -i能提供文件的inode号,我们还是必须检查两个文件是否处于同一个文件系统中。
[root@localhost tmp]# cat equalfile.sh 
#!/bin/bash
file1=$1
file2=$2

ls -il $file1 $file2
if [ $file1 -ef $file2 ]; then
    echo "$file1 is the same file as $file2"
else
    echo "$file1 is not the same file as $file2"
    diff -q $file1 $file2
    if [ "$?" -eq 0 ]; then
        echo "However,their contents are identical."
    fi
fi
[root@localhost tmp]# 

[root@localhost tmp]# echo testing > file1
[root@localhost tmp]# ln file1 file2
[root@localhost tmp]# echo testing > file3
[root@localhost tmp]# ls -il file?
1845475 -rw-r--r--. 2 root root 8 811 10:44 file1
1845475 -rw-r--r--. 2 root root 8 811 10:44 file2
1848669 -rw-r--r--. 1 root root 8 811 10:45 file3
[root@localhost tmp]# chmod +x equalfile.sh 
[root@localhost tmp]# ./equalfile.sh file1 file2 
1845475 -rw-r--r--. 2 root root 8 811 10:44 file1
1845475 -rw-r--r--. 2 root root 8 811 10:44 file2
file1 is the same file as file2
[root@localhost tmp]# ./equalfile.sh file1 file3
1845475 -rw-r--r--. 2 root root 8 811 10:44 file1
1848669 -rw-r--r--. 1 root root 8 811 10:45 file3
file1 is not the same file as file3
However,their contents are identical.
[root@localhost tmp]# echo something different >file4
[root@localhost tmp]# ./equalfile.sh file1 file4 
1845475 -rw-r--r--. 2 root root  8 811 10:44 file1
1848671 -rw-r--r--. 1 root root 20 811 10:46 file4
file1 is not the same file as file4
Files file1 and file4 differ
[root@localhost tmp]# 

test能对两个文件执行的其他比较操作包括查看一个文件的内容的修改日期是否比另一个文件更晚。

[root@localhost tmp]# echo old file > old
[root@localhost tmp]# sleep 60
[root@localhost tmp]# echo newer file > new
[root@localhost tmp]# ls -l new old
-rw-r--r--. 1 root root 11 811 10:51 new
-rw-r--r--. 1 root root  9 811 10:50 old
[root@localhost tmp]# if [ new -nt old ] ;then echo "new is newer"; else  echo "old is newer"; fi
new is newer
[root@localhost tmp]# if [ new -ot old ] ;then echo "new is newer"; else  echo "old is newer"; fi
old is newer
[root@localhost tmp]# 
  • 字符串比较测试
    有四种用于字符串测试的字符串,”<”,”>”只能在复合命令[[……]]中起作用,”==”和”=!”测试即可以在单方括号测试中也能在爽方括号测试中使用,但是单个等于符号”=”只能用在单方括号测试中。导致这种复杂性的原因是为了在添加更加强大的[[命令的同事,保持与Bourne shell的兼容性。
[root@localhost tmp]# cat alnum.sh 
#!/bin/bash
if [ "$1" = "$2" ]; then 
    echo " $1 is the same as $2"
else
    echo "$1 is not the same as $2"

if [[ "$1" < "$2" ]]; then
    echo "$1 comes before $2"
else 
    echo "$1 comes after $1"
fi
fi
[root@localhost tmp]# 
[root@localhost tmp]# ./alnum.sh apples bananas
apples is not the same as bananas
apples comes before bananas
[root@localhost tmp]# ./alnum.sh bananas apples
bananas is not the same as apples
bananas comes after bananas
[root@localhost tmp]# ./alnum.sh oranges oranges
 oranges is the same as oranges
[root@localhost tmp]# 

脚本中没有使用不相等的测试,应使用!=来实现:

[root@localhost tmp]# if [ "one" != "two" ]; then echo "These are not the same"; fi
These are not the same
[root@localhost tmp]# 

最后介绍的两个字符串测试与文件的-s 测试相似。-z测试在字符串长度为0时返回真,而-n在字符串长度非零时返回真。因为测试的字符串可能谁是空字符串,所以需要用引号将变量名引用起来;否则[-z $input]就会成为[-z ],这从语法上而言是非法的。只有[-z “” ]在语法意义上才是合法的。

[root@localhost tmp]# cat nz.sh 
#!/bin/bash
input=""
while [ -z "$input"  ];do
    read -p "Please give your input: " input
done
echo "Thank you for saying $input"
[root@localhost tmp]# 
[root@localhost tmp]# ./nz.sh 
Please give your input: 
Please give your input: 
Please give your input: songme
Thank you for saying songme
[root@localhost tmp]# 

正则表达式测试
使用=~

[[ $变量名 =~ .*\.deb]]

注意要是用双方括号[[]]

例:
[root@localhost tmp]# cat isdeb.sh 
#!/bin/bash
for deb in pkgs/*
do
    pkgname=`basename $deb`
    if [[ $pkgname =~ .*\.deb ]];then
        echo "$pkgname is a .deb package"
    else
        echo "File \"$pkgname\" is not a .deb package"
    fi
done
[root@localhost tmp]# 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值