Shell学习笔记

█开始行
shell程序必须以下面的行开始(必须方在文件的第一行)

#!/bin/sh

符号#!用来告诉系统它后面的参数是用来执行该文件的程序
█可执行
当编辑好脚本时,如果要执行该脚本,还必须使其可执行。
要使脚本可执行:chmod +x filename
█管道 (|):
 将一个命令的输出作为另外一个命令的输入。
█重定向:
将命令的结果输出到文件,而不是标准输出(屏幕)。
> 写入文件并覆盖旧文件
>> 加到文件的尾部,保留旧文件内容
█双引号与单引号
双引号的特殊字符可以保有变量的特性,但是单引号内的特殊字符则仅为一般字符。
#name="$LOGNAME is hh" //root is hh
#name='$LOGNAME is hh' //$LOGNAME is hh
通常大写字符为系统预设变量,自行设定的变量可以使用小写字符 
█取消变量:
用unset 变量名
█Shell特殊变量
$0 :执行的脚本的文件名
$1 :脚本文件的第一个参数名
$# :传递到脚本的参数个数
$* :以一个单字符串显示所有向脚本传递的参数
$$ :脚本运行的当前进程ID号
$? :显示最后命令的退出状态,0表示没有错误,其它值表示有错误
█常用shell内嵌命令:
(1)echo:显示变量内容
(2)env:显示目前系统中主要的预设变量内容
(3)set:显示目前系统中全部的变量内容
(4)read:从键盘读入变量内容
(5)declare:声明变量内容
-a:定义为数组 array
-f:定义为函数 function
-i:定义为整数 integer
-r:定义为“只读”
-x:定义为透过环境输出变量、
█算术运算符:
\*:对两个变量做乘法。
/:对两个变量做除法。
**:对两个变量做幂运算。
%:取模运算,第一个变量除以第二个变量求余数。
*=:乘等于,在第一个变量的基础上乘以第二个变量。
/=:除等于,在第一个变量的基础上除以第二个变量。
%=:取模赋值,第一个变量对第二个变量取模运算,再赋值给第一个变量
在使用这些运算符时,需要注意到运算顺序的问题。例如输入下面的命令,输出1+2的结果。
echo 1+2  Shell并没有输出结果3,而是输出了1+2。
█更改运算顺序。
a、用expr改变运算顺序。
如:echo `expr 1 + 2`来输出1+2的结果,用expr表 示后面的表达式为一个数学运算。
需要注意的是,`并不是一个单引号,而是Tab键上面的那个符号。
b、用let指示数学运算。
可以先将运算的结果赋值给变量b,运算命令是b=let 1 + 2。然后用echo $b来输出b的值。
c、用$[]表示数学运算。
将一个数学运算写到$[]符号的中括号中,中括号中的内容将先进行数学运算(中括号中可以包含空格)。
例如命令echo $[1+2],将输出结果3
█关系运算符:
-eq:数值相等
-ne:数值不相等
-ge:数1大于等于数2
-lt:数1小于数2
-gt:数1大于数2
-le:数1小于等于数2
例:输入test 1 -lt 2 && echo "yes"则打印yes
█布尔运算:
-a:(and)两状况同时成立。例:test -r file -a -x file,则file同时具有r和x权限时,才为true。
-o:(or)两状况任何一个成立。例:test -r file -o -x file,则file具有r或x权限时,就为true。
!:相反状态。例:test ! -r file,当file不具有r权限时,就为true。
█字符串运算符:
=:两个字符串相等
!=:两个字符串不相等
-z:空串
-n:非空串
█测试文件状态的条件表达式:
-e:是否存在
-d:是目录
-f:是文件
-L:符号连接
-s:文件非空
-r:可读
-w:可写
-x:可执行
█反短斜线:
使用反短斜线可以将一个命令的输出作为另外一个命令的一个命令行参数。
命令:find . -mtime -1 -type f -print
用来查找过去24小时(-mtime -2则表示过去48小时)内修改过的文件。
如果您想将所有查找到的文件打一个包,则可以使用以下脚本:
#!/bin/sh
# The ticks are backticks (`) not normal quotes ('):
tar -zcvf lastmod.tar.gz `find . -mtime -1 -type f -print`
█"if" 表达式:
如果条件为真则执行then后面的部分:
if ....; then .... elif ....; then .... else ....    fi
大多数情况下,可以使用测试命令来对条件进行测试。
比如可以比较字符串、判断文件是否存在及是否可读等等。
通常用" [ ] "来表示条件测试。注意这里的空格很重要。要确保方括号的空格。
[ -f "somefile" ] :判断是否是一个文件
[ -x "/bin/ls" ] :判断/bin/ls是否存在并有可执行权限
[ -n "$var" ] :判断$var变量是否有值
[ "$a" = "$b" ] :判断$a和$b是否相等 
█case表达式:
例:
#!/bin/sh
ftype=`file "$1"`
case "$ftype" in
"$1: Zip archive"*)
    unzip "$1"
"$1: gzip compressed"*)
    gunzip "$1"
"$1: bzip2 compressed"*)
    bunzip2 "$1"
*) error "File $1 can not be uncompressed with smartzip";
esac
█for循环
语法一:
-----
for (( 初始值; 限制值; 执行步阶 ))
do 程序
done
-----
初始值:变量在循环中的起始值
限制值:当变量值在这个限制范围内时,就继续进行循环
执行步阶:每作一次循环时,变量的变化量
 
语法二:
-----
for var in con1 con2 con3 ...//var是一个变量
do 程序
done
-----
第一次循环时,$var的内容为con1
第二次循环时,$var的内容为con2
第三次循环时,$var的内容为con3
█while循环
while循环,使您能够重复执行一组命令,直到某些条件发生。它通常用于当你需要反复操纵的变量值。
-----
while [ 条件 ] 
do 程序
done
-----
当条件成立的时候进入while循环,直到条件不成立时才退出循环
█until循环
有时候,你需要执行一组命令,直到某个条件为真。 语法如下:
-----
until 命令
do 程序
done
-----
这种方式与while循环恰恰相反,当命令成立的时候退出循环,否则继续循环
█select循环
语法如下:
-----
select var in word1 word2 ...
do 程序
done
-----
█shell数组
$a=(123 34 3 5)
$echo $a          // 默认获取第一个元素 123
$echo ${a[1]}     // 通过下标访问 34
$echo ${a[@]}     // 访问整个数组,@或者* 获取整个数组 123 34 3 5
$echo ${#a[@]}    // 获取数组的长度 4
$echo ${#a[3]}    // 获取字符串长度 1
$echo ${a[@]:1:2} // 切片方式获取一部分数组内容 34 3
$echo ${a[@]:2}   // 从第二个元素开始 3 5
$echo ${a[@]::2}  // 到第二个元素 123 34
█创建函数
声明一个函数语法:
function_name()
{
    list of commands
}
 
█for循环事例
bash version 3.0+版本
#!/bin/bash
 for i in {1..5}
do
   echo "Welcome $i times"
done


bash version 4版本 

#!/bin/bash
echo "Bash version ${BASH_VERSION}..."
for i in {0..10..2}
  do
     echo "Welcome $i times"
 done


含有“seq”命令的语法示例

#!/bin/bash
for i in $(seq 1 2 20)
do
   echo "Welcome $i times"
done


for循环的三个表达式

语法如下:

for (( EXP1; EXP2; EXP3 ))
do
         command1
         command2
         command3
done


示例如下:

#!/bin/bash
for (( c=1; c<=5; c++ ))
do
         echo "Welcome $c times..."
done

效果:

Welcome 1 times
Welcome 2 times
Welcome 3 times
Welcome 4 times
Welcome 5 times

for的无限循环

#!/bin/bash
for (( ; ; ))
do
   echo "infinite loops [ hit CTRL+C to stop]"
done


break条件语句

for I in 1 2 3 4 5
do
  statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
  statements2
  if (disaster-condition)
  then
         break                #Abandon the loop.
  fi
  statements3          #While good and, no disaster-condition.
done


下面的shell脚本将通过在/ etc目录中存储的所有文件。 for循环将放弃当/ etc / resolv.conf的文件中找到。

#!/bin/bash
for file in /etc/*
do
         if [ "${file}" == "/etc/resolv.conf" ]
         then
                 countNameservers=$(grep -c nameserver /etc/resolv.conf)
                 echo "Total  ${countNameservers} nameservers defined in ${file}"
                 break
         fi
done


continue条件语句

for I in 1 2 3 4 5
do
  statements1      #Executed for all values of ''I'', up to a disaster-condition if any.
  statements2
  if (condition)
  then
         continue   #Go to next iteration of I in the loop and skip statements3
  fi
  statements3
done


利用这个脚本在命令行中指定的所有文件名的备份。如果。bak文件存在,它会跳过cp命令。

#!/bin/bash
FILES="$@"
for f in $FILES
do
        # if .bak backup file exists, read next file
         if [ -f ${f}.bak ]
         then
                 echo "Skiping $f file..."
                 continue  # read next file and skip cp command
         fi
        # we are hear means no backup file exists, just use cp command to copy file
         /bin/cp $f $f.bak
done
 
posted @ 2016-03-17 12:31  大墨垂杨  阅读(328)  评论(0编辑  收藏  举报