13.Linux shell编程(条件语句和标准输出重定向)

(创建于2018/1/31)

条件语句

shell中的条件语句必须以fi结尾,否则会报错syntax error: unexpected end of file

if else then 这里的test命令意思就是test后的条件如果成立,则它就是0(真),否则就是非零(假)

 #!/bin/bash
  2 
  3 var=""
  4 if test var                                                                        
  5 then 
  6 echo "success"
  7 else
  8 echo "failed"
  9 fi

if then elif then fi(相当于if else if语句)

  1 #!/bin/bash                                                                        
  2 
  3 if test $var
  4 then echo "success"
  5 elif test haha
  6 then echo "haha"
  7 else echo "failed"
  8 fi

条件语句进行数字大小比较
-gt表示数学中的大于号>
其他符号的对应关系为
-eq:等于
-lt : 小于
-ne :不等于
-le :小于等于

 1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 b=5
  5 
  6 if [ $a -gt $b ]      //注意,[]中间一定有空格,否则会报错 command not found
  7 then
  8         echo "$a is greater than $b"
  9 else
 10         echo "$a is smaller than $b"
 11 fi

字符串的比较

str1 == str2
str1 != str2
str1 < str2
-n str1 长度是否非零
-z str2 长度是否为0

  1 #!/bin/bash
  2 
  3 str1="ren"
  4 str2="ming"
  5 str3=""
  6 str4="ren"
  7 
  8 if [ $str1 == $str4 ]                                                              
  9 then
 10         echo " str1 == str2"
 11 else
 12         echo " str1 != str2"
 13 fi
检查文件或者目录

-d : 检查目录是否存在
-f : 检查文件是否存在
-e : 检查文件或者目录是否存在
-r : 检查是否存在并且可读
-w : 检查是否存在并且可写
-x : 检查是否存在并且可执行
file1 -nt file2 file1比file2新(new than)
file1 -ot file2 file1比file2旧 (old than)

查看一个目录是否存在,如果存在则遍历这个目录

   1 #!/bin/bash                                                                        
  2 
  3 dir=/usr/ndk/temp
  4 
  5 if [ -d $dir ]
  6 then
  7         echo "$dir exist"
  8         cd $dir
  9         ls
 10 else
 11         echo "$dir not exist"
 12 fi

多个条件组合

如果目录存在和文件ren.sh可执行满足,则打印,遍历dir并创建一个文件b.sh并授权可执行然后再次遍历

  1 #!/bin/bash                                                                        
  2 
  3 dir=/usr/ndk/temp
  4 
  5 dir2=/usr/ndk/temp/ren.sh
  6 
  7 if [ -d $dir ] && [ -x $dir2 ]
  8 then
  9         echo "find $dir and $dir2,$dir2 can be execute"
 10         ls $dir
 11         touch b.sh
 12         chmod u+x b.sh
 13         ls -la
 14 else
 15         echo "not exist"
 16 fi


  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./a.sh 
find /usr/ndk/temp and /usr/ndk/temp/ren.sh,/usr/ndk/temp/ren.sh can be execute
a.sh  ren.sh
total 16
d--------- 2 root root 4096 Sep 13 07:57 .
drwxrwxrwx 7 root root 4096 Sep  7 07:47 ..
-rwxr--r-- 1 root root  215 Sep 13 07:57 a.sh
-rwxr--r-- 1 root root    0 Sep 13 07:57 b.sh
-rwxr--r-- 1 root root  115 Sep 13 07:34 ren.sh
shell中的case命令(类似switch)

格式如下:
case 变量 in
pattern1) 命令;;
pattern2) 命令;;
*) 默认命令;;
esac

  1 #!/bin/bash                                                                        
  2 
  3 user=zhen
  4 
  5 case $user in
  6 
  7 zhen)
  8         echo "zhen is here";;
  9 ming)
 10         echo "ming is here";;
 11 *)
 12         echo "not found";;
 13 esac

shell中的for命令

1 #!/bin/bash
  2 
  3 list="Monday,Friday,Sonday"
  4 IFS=$,          //域分隔符                                                                   
  5 for item in $list
  6 do
  7         echo $item
  8 done
  9 

打印结果去掉了括号
  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./c.sh 
Monday
Friday
Sonday
shell中的while命令
  1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 while [ $a -gt 0 ]
  5 
  6 do
  7         echo "num:$a"
  8         a=$[ $a - 1 ]
  9 done

tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./d.sh 
num:10
num:9
num:8
num:7
num:6
num:5
num:4
num:3
num:2
num:1
root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# 

循环语句和条件语句嵌套

  1 #!/bin/bash                                                                        
  2 
  3 a=10
  4 while [ $a -gt 0 ]
  5 
  6 do
  7         echo "num:$a"
  8         a=$[ $a - 1 ]
  9         if [ $a -eq 5 ]
 10         then
 11                 echo "break"
 12                 break
 13         fi
 14 done

  tabstop=8root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp# ./d.sh 
num:10
num:9
num:8
num:7
num:6
break
root@iZuf67sz57humoriy3o6oiZ:/usr/ndk/temp#

重定向深入理解undefined

一般情况下,每一个Linux 命令运行时都会打开三个文件:
标准输入文件(stdin): stdin的文件描述符为0,linux程序默认从stdin读取数据。
标准输出文件(stdout): stdout 的文件描述为1,linux程序默认向stdout输出数据。
标准错误文件(stderr): stderr 的文件描述符为2,linux程序会向stderr流中写入错误信息。

以后打开文件后。新增文件绑定描述符 可以依次增加。 一条shell命令执行,都会继承父进程的文件描述符。因此,所有运行的shell命令,都会有默认3个文件描述符。
正常情况下,command > file 将stdout重定向file,command < file 将stdin 重定向到 file。
一个命令执行了:
先有一个输入:输入可以从键盘,也可以从文件得到
命令执行完成:成功了,会把成功结果输出到屏幕:standard output默认是屏幕
命令执行有错误:会把错误也输出到屏幕上面:standard error默认也是指的屏幕
如果希望stderr 重定向 到file 可以这样写:

command 2> file
1

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

command 2>> file

1.输出内容到文件中,(如果文件不存在则自动创建)

#!/bin/bash                                                                              

file=test111
echo "input into test111" > $file
echo "input into test111" >> $file  (追加到文件末尾)

打开文件test111会发现结果,输入了两行
input into test111
input into test111

2.输出到屏幕上(控制台)

 #!/bin/bash                                                                              

file=test111

//0 STDIN
//1 STDOUT  标准输出
//2 STDERR

echo "input into test111" >&2    //注意,>与&2之间没有空格
echo "input into test111" >&2    //>>无法输出到屏幕

3.在命令行中控制标准输出重定向到文件中

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)。

command1 < infile > outfile   //执行command1,从文件infile读取内容,然后将输出写入到outfile中
#!/bin/bash                                                                              

file=test111
echo "input into test111"
echo "input into test111"
    
//./14.sh &> test222  也可以输出到文件中,搞不懂
执行脚本

tabstop=8root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ./14.sh 1> test222   //(将文件描述符为 n 的文件重定向到 file。)会将标准输出符为1的文件14.sh中的标准输出内容重定向到test222文件中,注意任何test222内的已经存在的内容将被新内容替代。如果要将新的内容添加到文件的末尾,则使用>>操作符。
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  3.sh  5.sh  7.sh  9.sh  ren.txt  test222
11.sh  13.sh  2.sh   4.sh  6.sh  8.sh  copy  test111
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat test222
input into test111
input into test111

4.在脚本中设置标准输出重定向写入文件中,exec 1>文件名

#!/bin/bash                                                                              

exec 1>test333
echo "input into test333"
echo "input into test333"
      
      
输出结果:

./14.sh
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  3.sh  5.sh  7.sh  9.sh  ren.txt  test222
11.sh  13.sh  2.sh   4.sh  6.sh  8.sh  copy  test111  test333
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat test333 


  1 #!/bin/bash                                                                        
  2 
  //将标准输出重定向到output.txt文件中,这样一来这个脚本中的所有输出内容会
  //被打印到output.txt文件
  3 exec 1>output.txt
  //将标准错误输出重定向到error.txt文件,所以这个文件中发生的错误信息会被打印
  //到这里
  4 exec 2>error.txt
  5 
  6 echo "this is output"
  7 ls -la ffmpeg

5.自定义输出

#!/bin/bash   

//#0 STDIN    标准输入
//#1 STDOUT   标准输出
//#STDERR     标准错误

exec 1>file1      //将脚本执行过程中的标准输出写入到文件file1
exec 2>file2      //将脚本执行中的标准错误输出到文件file2

exec 3>file3      //自定义输出将标准输出输入到文件file3
echo "hello" >&3
echo "byebye"
ls -a ./hehe      //没有这个文件,发生错误,会将错误信息打印到file2中
    
    
结果:

tabstop=8root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ./15.sh 
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# ls
10.sh  12.sh  14.sh  2.sh  4.sh  6.sh  8.sh  copy         ren.txt  STDOUT
11.sh  13.sh  15.sh  3.sh  5.sh  7.sh  9.sh  CUSTOME_STD  STDERR
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat STDOUT 
byebye
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat STDERR 
ls: cannot access './hehe': No such file or directory
root@iZbp11v3y27wpf6mglp2glZ:/user/renzhenming/shell# cat CUSTOME_STD 
hello
上一篇:Android怎么找到最优适配资源


下一篇:C#处理JSON数据