kavo

学习 Linux Shell脚本笔记

PS:看完了,跟着测试了主要的,现在晚上时间21:00,花了近一天

因为网站要用到定时删除一定时间以前的文件,所以要用的xshell,无意间看到一位博主推荐的30分钟玩转xshell编程

于是一头扎进去开始学习。

学习链接:http://c.biancheng.net/cpp/view/6999.html

一基础:

echo $PATH #获取环境变量路径
echo $SHELL #获取默认shell默认使用环境变量

创建xx.sh并执行

#在环境路径下建立xx.sh文件内容如下

#!/bin/bash    #约定脚本使用的解释器

#范例脚本
echo "what is your name"
read person    #这里使用read命令获取stdin命令窗口输入内容获取变量
echo "hello,$person"

#写完后保存

#给予权限

chmod -x xx.sh

#提示:w:读  r:写 x:执行

#完成后执行,切记一定要./开头:
./xx.sh

 

二:变量

#切记,区别于php,变量赋值左右不能有空格,一定要注意,但是运算必须有空格
#变量声明如下,明明规范等于php,默认Bash shell都会识别为字符串,如果值包含空格等必须使用引号包围
variable=value
variable='value'
variable="value"

#使用如下,{}是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
#推荐给所有变量加上花括号{ },这是个良好的编程习惯。
author="严长生"
echo $author
echo ${author}

skill="Java"
echo "I am good at ${skill}Script"

#和php一样,变量可以被重新赋值
url="aa"
echo ${url}
url="bb"
echo ${url}

#值的引号使用等于php,单引号不解析变量,且不转义字符,双引号解析变量可以转义字符,所以如果不是原样输出,没有特殊需要最好都用双引号

#变量的赋值有两种,推荐使用第二种,如下
log=`cat test.txt`    #使用反引号,用以和单引号混淆
echo $log
log=$(cat test.txt)    #使用()号,推荐使用
echo $log

#只读变量
readonly url="aa"
url="bb"
#会报错:url: readonly variable

#删除变量使用unset,等于php
url="aa"
unset url


#变量类型
#运行shell时,会同时存在三种变量:
#1) 局部变量
#局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
#2) 环境变量
#所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
#3) shell变量
#shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
*/

特殊变量,可echo 测试:

$0当前脚本的文件名
$n传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$#传递给脚本或函数的参数个数。
$*传递给脚本或函数的所有参数。
$@传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
$?上个命令的退出状态,或函数的返回值。
$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

 

#!/bin/sh
echo "sh name:$0"
echo "fist param:$1"
echo "two param:$2"
echo "all param:$@"
echo "all param:$*"
echo "param number:$#"

#输入命令,在执行的脚本命令后边传递参数:
./dir.sh A B
#或者后面跟字符串./test.sh "a" "b" "c" "d"

#输出如下:
sh name:./dir.sh
fist param:A
two param:B
all param:A B
all param:A B
param number:2

# $* 和 $@ 的区别,他们不被双引号包含时都是以$1,$2输出所有参数
echo "\$*=" $*
echo "\"\$*\"=" "$*"  #在对双引号包含的"$*"进行for循环时,会将参数当一个整体输出(可理解为字符串)
echo "\$@=" $@
echo "\"\$@\"=" "$@"

#举例:
./test.sh "a" "b" "c" "d"    #for "$*"时 会将参数作为一个整体全部输出,而不是每个参数

#退出状态
echo $?
#在脚本里执行输出上一个命令执行后的返回结果,大部分命令执行成功会返回 0,失败返回 1

Shell替换:Shell变量替换,命令替换,转义字符:

转义字符

含义
\\反斜线
\a警报、响铃
\b退格(删除键)
\f换页(FF),将当前位置移到下页开头
\n换行
\r回车
\t水平制表符(tab键)
\v垂直制表符

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#如果输出内容里包含转义字符
a=10
echo -e "value of a is $a \n"
#这里加上-e 表示对转义字符进行替换,表示输出的结尾加上换行
value of a is 10 

#如果这里不加上-e的话,则会原样输出:
value of a is 10\n

#可以使用 echo 命令的 -E 选项禁止转义,默认也是不转义的;使用 -n 选项可以禁止插入换行符。

#命令替换

变量替换表,相当于php某些框架中模板中输出变量的用法

形式说明
${var}变量本来的值
${var:-word}如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。
${var:=word}如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。
${var:?message}如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此替换出现在Shell脚本中,那么脚本将停止运行。
${var:+word}如果变量 var 被定义,那么返回 word,但不改变 var 的值。

 shell运算符


#原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
#expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

#注意两点:
#一:表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
#二:完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。
#例如
#!/bin/bash
val=`expr 2 + 2`
echo $val

a=10
b=20

val=`expr $a \* $b`
echo "a * b : $val"

if [ $a != $b ]
then
   echo "a is not equal to b"
fi

#乘号(*)前边必须加反斜杠(\)才能实现乘法运算;

 

算术运算符列表
运算符说明举例
+加法`expr $a + $b` 结果为 30。
-减法`expr $a - $b` 结果为 10。
*乘法`expr $a \* $b` 结果为  200。
/除法`expr $b / $a` 结果为 2。
%取余`expr $b % $a` 结果为 0。
=赋值a=$b 将把变量 b 的值赋给 a。
==相等。用于比较两个数字,相同则返回 true。[ $a == $b ] 返回 false。
!=不相等。用于比较两个数字,不相同则返回 true。[ $a != $b ] 返回 true。

 

关系运算符列表

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

运算符 说明 举例 -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。 -ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。 -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。 -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。 -ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。 -le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

a=10
b=20
if [ $a -eq $b ] #注意啊,这里[]两边必须空格,否则报错
then
   echo "$a -eq $b : a is equal to b"
else
   echo "$a -eq $b: a is not equal to b"
fi
布尔运算符列表
运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true。[ ! false ] 返回 true。
-o或运算,有一个表达式为 true 则返回 true。[ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a与运算,两个表达式都为 true 才返回 true。[ $a -lt 20 -a $b -gt 100 ] 返回 false。
#!/bin/sh
a=10
b=20

if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a -lt 100 -a $b -gt 15 : returns true"
else
   echo "$a -lt 100 -a $b -gt 15 : returns false"
fi
#输出
10 -lt 100 -a 20 -gt 15 : returns true

 

字符串运算符列表
运算符说明举例
=检测两个字符串是否相等,相等返回 true。[ $a = $b ] 返回 false。
!=检测两个字符串是否相等,不相等返回 true。[ $a != $b ] 返回 true。
-z检测字符串长度是否为0,为0返回 true。[ -z $a ] 返回 false。
-n检测字符串长度是否为0,不为0返回 true。[ -z $a ] 返回 true。
str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。

详细请看:http://c.biancheng.net/cpp/view/2736.html

Shell字符串

#字符串拼接
a="this is a"
b="fllow,"$a"!"
c="fllow,${a} !"
echo $b $c

#输出内容如下:
fllow,this is a! fllow,this is a !

#获取字符串长度
string='abcd'
echo ${#string}
#输出
4

#提取子字符串
string="alibaba is a great company"
echo ${string:1:4} 
#输出liba,也就是第1-第四的字符


Shell数组:shell数组的定义、数组长度

#shell中数组和php有点类似,没有多维数组,定义时用(),值与值之间用空格分开,读取时用下标,下标也是0开始

array=(a b c d)

array=(
a
b
c
d
)

array[0]=a
array[1]=b
array[2]=c
array[3]=d

#读取格式为
${array[0]}

#使用*和@可以获取数组中所有元素
${array[*]}
${array[@]}

#获取数组长度
${#array[*]}
${#array[@]}
@获取数组单个元素的长度
${#array[n]}

  

Shell if else语句,三种用法

#第一种
if [ $a == $b ]
then
   echo "a is equal to b"
fi

#第二种
if [ $a == $b ]
then
   echo "a is equal to b"
else
   echo "a is not equal to b"
fi

#第三种
a=10
b=20
if [ $a == $b ]
then
   echo "a is equal to b"
elif [ $a -gt $b ]
then
   echo "a is greater than b"
elif [ $a -lt $b ]
then
   echo "a is less than b"
else
   echo "None of the condition met"
fi

Shell test命令

# test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

#数值
num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo 'The two numbers are equal!'
else
    echo 'The two numbers are not equal!'
fi

#字符串
num1=100
num2=100
if test num1=num2
then
    echo 'The two strings are equal!'
else
    echo 'The two strings are not equal!'
fi

#文件测试,比较命令请参考文档
cd /bin
if test -e ./notFile -o ./bash
then
    echo 'One file exists at least!'
else
    echo 'Both dose not exists!'
fi

#与( ! )、或( -o )、非( -a )三个逻辑操作符用于将测试条件连接起来,其优先级为:“!”最高,“-a”次之,“-o”最低。例如:

Shell case esac语句

#直接举例吧
#其间所有命令开始执行直至 ;;。 ;; 与其他语言中的 break 类似
echo 'Input a number between 1 to 4'
echo 'Your number is:\c'
read aNum
case $aNum in
    1)  echo 'You select 1'
    ;;
    2)  echo 'You select 2'
    ;;
    3)  echo 'You select 3'
    ;;
    4)  echo 'You select 4'
    ;;
    *)  echo 'You do not select a number between 1 to 4'
    ;;
esac


option="${1}"
case ${option} in
   -f) FILE="${2}"
      echo "File name is $FILE"
      ;;
   -d) DIR="${2}"
      echo "Dir name is $DIR"
      ;;
   *) 
      echo "`basename ${0}`:usage: [-f file] | [-d directory]"
      exit 1 # Command to come out of the program with status 1
      ;;
esac

Shell for循环

#直接上例子,列表是一组值(数字、字符串等)组成的序列,每个值通过空格分隔
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

#结果
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

#顺序输出字符串中的字符
for str in 'This is a string'
do
    echo $str
done
#运行结果:
This is a string

#显示主目录下以 .bash 开头的文件:

for FILE in $HOME/.bash*
do
   echo $FILE
done

#结果
/root/.bash_history
/root/.bash_logout
/root/.bash_profile
/root/.bashrc

Shell while循环

#例子
count=1
while [ $count -lt 6 ]
do
  echo $count
  let count++
done
#输出
1
2
3
4
5
6

#读取磁盘信息
echo 'type <CTRL-D> to terminate'
echo -n 'enter your most liked film: '
while read FILM
do
    echo "Yeah! great film the $FILM"
done            

Shell until循环,和while相反,遇到true时才停止


#和while一样,循环里运算用法要注意
#输出 0 ~ 9 的数字
a=0
until [ ! $a -lt 10 ]
do
  echo $a 
  let ++a 
done

break命令

#像大多数编程语言一样,Shell也使用 break 和 continue 来跳出循环。

while :
do
        echo -n "input your number between 1 to 5" 
        read num
        case $num in 
                1|2|3|4|5) echo "your number is $num"
                ;;      
                *) echo 'stop'
                  break   
                ;;      
        esac    
done

#和php一样,满足条件break跳出循环    break n跳出第几层循环
for var1 in 1 2 3
do
   for var2 in 0 5
   do
      if [ $var1 -eq 2 -a $var2 -eq 0 ]
      then
         break 2
      else
         echo "$var1 $var2"
      fi
   done
done

#coutinue表示跳出本次循环  coutinue n跳出第几层循环
while :
do
    echo -n "Input a number between 1 to 5: "
    read aNum
    case $aNum in
        1|2|3|4|5) echo "Your number is $aNum!"
        ;;
        *) echo "You do not select a number between 1 to 5!"
            continue
            echo "Game is over!"
        ;;
    esac
done

Shell函数:Shell函数返回值、删除函数、在终端调用函数

#可以带function 也可以不带,调用时后面不需要()

#实例
number_one () {
   echo "Url_1 is http://see.xidian.edu.cn/cpp/shell/"
   number_two
}
number_two () {
   echo "Url_2 is http://see.xidian.edu.cn/cpp/u/xitong/"
}
number_one

#使用函数接受结果请使用$?
funWithReturn(){
    echo "The function is to get the sum of two numbers..."
    echo -n "Input first number: "
    read aNum
    echo -n "Input another number: "
    read anotherNum
    echo "The two numbers are $aNum and $anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
# Capture value returnd by last command
ret=$?
echo "The sum of two numbers is $ret !"

#删除函数
unset .f function_name

#/etc/profile    
#可以将函数定义在以上目录,这样每次登录后,在命令提示符后面输入函数名字就可以立即调用

Shell函数参数

#通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...

funWithParam(){
    echo "The value of the first parameter is $1 !"
    echo "The value of the second parameter is $2 !"
    echo "The value of the tenth parameter is $10 !"
    echo "The value of the tenth parameter is ${10} !"
    echo "The value of the eleventh parameter is ${11} !"
    echo "The amount of the parameters is $# !"  # 参数个数
    echo "The string of the parameters is $* !"  # 传递给函数的所有参数
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

#注意:注意,当n>=10时,需要使用${n}来获取参数
#前面讲过特殊变量,$*:参数个数,$*和$@获取所有参数

Shell输入输出重定向:Shell Here Document,/dev/null文件

#Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端,即显示器。

#命令的输出不仅可以是显示器,还可以很容易的转移向到文件,这被称为输出重定向。

#输出重定向  用>
echo line 1 > users    #输出重定向会覆盖文件内容
echo line 2 >> users   #使用 >> 追加到文件末尾
#查看
cat users

#输入重定向,可以从文件获取输入    用<
#计算 users 文件中的行数
wc -l users

#输入重定向到 users 文件
wc -l < users

#如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null:

#如果希望屏蔽 stdout 和 stderr,可以这样写:
command > /dev/null 2>&1



 

全部可用的重定向命令列表
命令说明
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 之间的内容作为输入。

Shell文件包含

#包含外部脚本,将外部脚本的内容合并到当前脚本。
#一种
. filename    #简单起见,一般使用点号(.),但是注意点号(.)和文件名中间有一空格
#二种
source filename

#注意:被包含脚本不需要有执行权限。

#在相同目录创建url.sh,内容为
 a='thi s inlcude strinf'

#在使用test.sh
. ./url.sh
echo $a

#即可

 

posted on 2018-07-18 20:58  下雨天唱情歌  阅读(4)  评论(0编辑  收藏  举报  来源

导航