荣耀之链论坛

 找回密码
 立即注册
搜索
查看: 3127|回复: 1

shell编程相关

[复制链接]

1325

主题

2372

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
10262
发表于 2015-10-21 23:16 | 显示全部楼层 |阅读模式
shell中if做比较
比较两个字符串是否相等的办法是:
    if [ "$test"x = "test"x ]; then
    这里的关键有几点:
    1 使用单个等号
    2 注意到等号两边各有一个空格:这是unix shell的要求
    3 注意到"$test"x最后的x,这是特意安排的,因为当$test为空的时候,上面的表达式就变成了x = testx,显然是不相等的。而如果没有这个x,表达式就会报错:[: =: unary operator expected
   
    二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别.
    整数比较
    -eq 等于,如:if [ "$a" -eq "$b" ]
    -ne 不等于,如:if [ "$a" -ne "$b" ]
    -gt 大于,如:if [ "$a" -gt "$b" ]
    -ge 大于等于,如:if [ "$a" -ge "$b" ]
    -lt 小于,如:if [ "$a" -lt "$b" ]
    -le 小于等于,如:if [ "$a" -le "$b" ]
     大于(需要双括号),如:(("$a" > "$b"))
    >= 大于等于(需要双括号),如:(("$a" >= "$b"))
    小数据比较可使用AWK
    字符串比较
    = 等于,如:if [ "$a" = "$b" ]
    == 等于,如:if [ "$a" == "$b" ],与=等价
     注意:==的功能在[[]]和[]中的行为是不同的,如下:
     1 [[ $a == z* ]] # 如果$a以"z"开头(模式匹配)那么将为true
     2 [[ $a == "z*" ]] # 如果$a等于z*(字符匹配),那么结果为true
     3
     4 [ $a == z* ] # File globbing 和word splitting将会发生
     5 [ "$a" == "z*" ] # 如果$a等于z*(字符匹配),那么结果为true
     一点解释,关于File globbing是一种关于文件的速记法,比如"*.c"就是,再如~也是.
     但是file globbing并不是严格的正则表达式,虽然绝大多数情况下结构比较像.
    != 不等于,如:if [ "$a" != "$b" ]
     这个操作符将在[[]]结构中使用模式匹配.
     大于,在ASCII字母顺序下.如:
     if [[ "$a" > "$b" ]]
     if [ "$a" \> "$b" ]
     注意:在[]结构中">"需要被转义.
     具体参考Example 26-11来查看这个操作符应用的例子.
    -z 字符串为"null".就是长度为0.
    -n 字符串不为"null"
     注意:
     使用-n在[]结构中测试必须要用""把变量引起来.使用一个未被""的字符串来使用! -z
     或者就是未用""引用的字符串本身,放到[]结构中。虽然一般情况下可
     以工作,但这是不安全的.习惯于使用""来测试字符串是一种好习惯.
if判断式
if [ 条件判断一 ] && (||) [ 条件判断二 ]; then
elif [ 条件判断三 ] && (||) [ 条件判断四 ]; then
else
   执行第三段內容程式
fi
例如:

root@Bizbox:~# a=0
root@Bizbox:~# b=0
root@Bizbox:~# c=5        
root@Bizbox:~# if [ $a = 0 -a $b = 0 ]&&[ $c != 0 ]; then
> echo success
> fi
successif 使用的表达式
Primary 意义
[ -a 文件 ] 如果文件存在为真。
[ -b 文件 ] 如果 文件 存在 而且 是一个 块-特殊 文件为真。
[ -c 文件 ] 为真 如果 文件 存在 而且 是一个 字-特殊 文件。

[ -d 文件 ] 为真 如果 文件 存在 而且 是一个 目录。
[ -e 文件 ] 为真 如果 文件 存在。
[ -f 文件 ] 为真 如果 文件 存在 而且 是一个 普通 文件。
[ -g 文件 ] 为真 如果 文件 存在 而且 已经设置了他的 SGID 位。
[ -h 文件 ] 为真 如果 文件 存在 而且 是一个 符号连接。
[ -k 文件 ] 为真 如果 文件 存在 而且 他的粘住位已经设置。
[ -p 文件 ] 为真 如果 文件 存在 而且 是一个 已经命名的管道 (F 如果O)。
[ -r 文件 ] 为真 如果 文件 存在 而且 是可读的。
[ -s 文件 ] 为真 如果 文件 存在 而且 比零字节大。
[ -t FD ] 为真 如果 文件 文件描述符已经打开 而且 指向一个终端。
[ -u 文件 ] 为真 如果 文件 存在 而且 已经设置了他的 SUID (set user ID)位。
[ -w 文件 ] 为真 如果 文件 为真 如果 文件 存在 而且 是可写的。
[ -x 文件 ] 为真 如果 文件 存在 而且 是可执行的。
[ -O 文件 ] 为真 如果 文件 存在 而且 属于有效用户ID。
[ -G 文件 ] 为真 如果 文件 存在 而且 属于有效组ID。
[ -L 文件 ] 为真 如果 文件 存在 而且 是一个 符号连接。
[ -N 文件 ] 为真 如果 文件 存在 而且 has been mod 如果ied since it was last read。
[ -S 文件 ] 为真 如果 文件 存在 而且 是一个 socket。
[ 文件1 -nt 文件2 ] 为真 如果 文件1 has been changed more recently than 文件2, or 如果
文件1 存在 而且
文件2 does not。
[ 文件1 -ot 文件2 ] 为真 如果 文件1 比 文件2 旧, 或者 文件2 存在而且 文件1 不存在。
[ 文件1 -ef 文件2 ] 为真 如果 文件1 而且 文件2 refer to the same device 而且 inode
numbers。
[ -o 选项名 ] 为真 如果 shell 选项 "选项名" 开启。
[ -z STRING ] 为真 如果 "STRING"的长度是零。
[ -n STRING ] 或者 [ STRING ] 为真 "STRING"的长度是非零值。
[ STRING1 == STRING2 ] 如果两个字符串相等为真。 "=" may be used instead of "==" for
strict POSIX compliance。
[ STRING1 != STRING2 ] 为真 如果 两两个字符串不相等。
[ STRING1 < STRING2 ] 为真 如果 "STRING1" sorts before "STRING2" lexicographically in the
current locale。
[ STRING1 > STRING2 ] 为真 如果 "STRING1" sorts after "STRING2" lexicographically in the
current locale。
[ ARG1 OP ARG2 ]
"OP" 是 -eq, -ne, -lt, -le, -gt or -ge 其中一个。 These arithmetic binary operators
return 为真 如果 "ARG1" is equal to, not equal to, less than, less than or equal to, greater
than, or greater than or equal to "ARG2", respectively。 "ARG1" 而且 "ARG2" are
integers。
表达式可以借以下操作符组合起来, listed in decreasing order of precedence:
操作符效果
[ ! EXPR ] 如果EXPR 为假则为真。
[ ( EXPR ) ] 返回EXPR 的值。 这样可以用来忽略正常的操作符优先级。

[ 表达式1 -a 表达式2 ] 如果表达式1 而且表达式2 同时为真则为真 。
[ 表达式1 -o 表达式2 ] 如果表达式1 或者表达式2 其中之一为真则为真

1) bash
   a=3 ; b=2 ; c=4
   if (( a > b )) && (( a < c ))

   或者
   if [[ $a > $b ]] && [[ $a < $c ]]
    或者
   
     if [ $a -gt $b -a $a -lt $c ]
2)   a=3 ; b=2 ; c=4
      if (( a > b )) || (( a < c ))
     
       或者
      if [[ $a > $b ]] || [[ $a < $c ]]
       或者
       if [ $a -gt $b -o $a -lt $c ]
3) -o = or , -a = and , 但我一向只用 || 或者 &&
4) 可用, 但是要两个独立的 [ ] , [[ ]] 或 (( ))
   看 1)
5) -ne 比较数字 (numberic) ; != 比较字符 (string), 但后者拿来
   比较数字也可,只是不是标准用法
   -lt 是等同 < , 但 < 只能在 shell 的数值操作符 (( )) 或
   者 逻缉操作符 [[ ]] 才可使用, -lt , -eq , -gt , -ge
   -le , 这些是 test , 就是 [ ] 这个内建命令使用的条件操
   作符, 数字用, = , != 字符用, == 这个该是 [[ ]] 用的,
   可用来比对正规表示式, 但用在 [ ] 也可,只是不太正统用法



if [ $a = "aa" -a $b = "bb" ] || [$c = "cc" -a $d = "dd" ];
then
  echo "success"
fi



回复

使用道具 举报

1325

主题

2372

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
10262
 楼主| 发表于 2015-10-21 23:16 | 显示全部楼层
一、变量分类
局部变量和环境变量,局部变量只适用于当前shell,而环境变量是全局的,它适用于所有当前shell以及其派生出来的任意子进程,有些变量是用户创建的,其他的则是专用的shell变量。
二、局部变量
局部变量的作用域被限定在创建它们的shell中。local函数可以用来创建局部变量,但仅限于函数内使用。局部变量可以通过简单的赋予它一个值或一个变量名来设置,用declare内置函数来设置,或者省略也可。
格式:
变量名=值
declare 变量名=值
以下来示范一个局部变量的例子:
[root@centos ~]# echo
8836
[root@centos ~]# round=world
[root@centos ~]# echo $round
world
[root@centos ~]# bash
[root@centos ~]# echo

8920
[root@centos ~]# echo $round
[root@centos ~]# exit
exit
[root@centos ~]# echo $$
8836
[root@centos ~]# echo $round
world
在上面的岩石中可以看出,当启动一个bash程序,相当于创建一个子shell后,round变在这个子shell中没有被赋值,exit退出子shell后,可以看到父shell中变量round仍有值。
三、环境变量
环境变量通常又称全局变量,以区别于局部变量,通常,环境变量应该大写,环境变量是已经用export内置命令导出的变量。子shell继承当前父shell的环境变量,并能一直传承下去,但是不可逆向传递。
格式:
export 变量=值
declare -x 变量=值
我们做个示范:
[root@centos ~]# export NAME=”yuan faxiang”
[root@centos ~]# echo $NAME
yuan faxiang
[root@centos ~]# echo
8836
[root@centos ~]# bash
[root@centos ~]# echo

8958
[root@centos ~]# echo $NAME
yuan faxiang
[root@centos ~]# declare -x NAME=”Arvin”
[root@centos ~]# echo $NAME
Arvin
[root@centos ~]# exit
exit
[root@centos ~]# echo $$
8836
[root@centos ~]# echo $NAME
yuan faxiang
上述例子中,父shell中定义的NAME环境变量传递到了子shell中,在子shell中定义的NAME环境变量没有被带到父shell中。
环境变量按生存周期可分为:
1. 永久的:需要修改配置文件,export变量永久生效。
2. 临时的:使用export命令行声明即可,变量在关闭shell时失效。
2.设置变量的三种方法
1) 在/etc/profile文件中添加变量【对所有用户生效(永久的)】
用VI在文件/etc/profile文件中增加变量,该变量将会对Linux下所有用户有效,并且是“永久的”。
例如:编辑/etc/profile文件,添加CLASSPATH变量
# vi /etc/profile
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注:修改文件后要想马上生效还要运行# source /etc/profile不然只能在下次重进此用户时生效。
2) 在用户目录下的.bash_profile文件中增加变量【对单一用户生效(永久的)】
用VI在用户目录下的.bash_profile文件中增加变量,改变量仅会对当前用户有效,并且是“永久的”。
例如:编辑guok用户目录(/home/guok)下的.bash_profile
$ vi /home/guok/.bash.profile
添加如下内容:
export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib
注:修改文件后要想马上生效还要运行$ source /home/guok/.bash_profile不然只能在下次重进此用户时生效。
3) 直接运行export命令定义变量【只对当前shell(BASH)有效(临时的)】
在shell的命令行下直接使用[export变量名=变量值]定义变量,该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

荣耀之链

GMT+8, 2025-6-18 03:02 , Processed in 0.016429 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表