Linux - shell 脚本学习

  shell 脚本是一种解释型语言。所以需要配套解释器来解释你的脚本。

一、解释器选择

  在脚本的第一行,就要注明你的脚本需要使用什么解释器来运行,比如#!/bin/bash,这个意思就是用/bin/bash来解析脚本。以下是常用的。

#!/bin/bash     <- 推荐
#!/bin/sh
#!/bin/ksh
#!/usr/bin/env bash    <- 推荐

  最后一种#!/usr/bin/env bash,通过/usr/bin/env运行程序,用户不需要去寻找程序在系统中的位置(因为在不同的系统,命令或程序存放的位置可能不同),只要程序在你的$PATH中。通过/usr/bin/env运行程序另一个好处是,它会根据你的环境寻找并运行默认的版本,提供灵活性。
  当然也可以自己定义一个脚本语言,用自己定义的解释器去解释他,比如你的解释器叫做xshell,放在/usr/local/bin下面。所以使用的时候就是#!/usr/local/bin/xshell

二、运行和调试

  一个脚本文件如何去运行呢,可以使用如下的方式运行脚本。

1、当前路径下运行
./test.sh
2、绝对路径运行
/tmp/test.sh
3、使用 . 运行
. test.sh
4、使用sh
sh test.sh
5、使用source
source test.sh 

  source、./ 、sh、. 这几种方式都可以运行脚本,但是这几种方式有一些区别。source和.和sh是在当前bash环境下读取并执行FileName中的命令。该filename文件可以无”执行权限”,sh更灵活带有很多参数,source常用来更新系统配置文件。./是打开一个子shell来读取并执行脚本中命令。
  脚本写完后需要调试,调试方式如下。

1、在脚本中, 不推荐
#! /bin/bash -x
2、在运行的时候
sh -x test.sh

  脚本调试中不推荐使用第一种方式,因为生产和测试的代码肯定是一样的,第一种方式还要去修改脚本代码,这种很容易忘了去修改回来,导致运行的时候都是调试信息。调试信息中前面带+或者++的表示执行的命令,不带的表示输出结果。

三、脚本基本语法

3.1、变量

  定义变量,key=value,主要分成两种动态变量和静态变量,静态变量就是数值是暂时不会变化的,习惯上字符串使用“”,数值的就不用引号;动态变量,值得是执行后才知道结果的值(常用于包含命令),使用反引号。

#静态变量
me="woshihaha"
#动态变量
date=`date`
echo ${me}
echo ${date}
3.2、传递参数

  传递的参数以$为开头。

字符含义讲解
$n参数n,n从1开始$1就是参数一,$2就是参数2
$0当前脚本的文件名
$#参数的个数
$*所有的参数
$@所有的参数
$?上个命令的退出状态,或函数的返回值。
$$当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

  $* 和 $@ 都表示所有参数,但是两者之间是有区别的。

脚本名称叫test.sh 入参三个: 1 2 3
运行test.sh 1 2 3$*"1 2 3"(一起被引号包住)
$@"1" "2" "3"(分别被包住)
3.3、数组

  数组都是一维的。 定义方式key=(value1 value2 value3 value4)

1、访问数组内元素,从0开始
echo ${arr[0]}
2、输出所有元素
echo ${arr[*]}
3、取数组的个数
echo ${#arr[*]}
3.4、判断

  用if判断,基本方法:

if [ "$a" == "$b" ]; then
elif[ "$a" == "CCC" ]; then
else
fi

当然如下这样子也是可以的

if [ "$a" == "$b" ]
then

else
fi

  需要注意的是[]的内部两边是要有空格。等于号两边也要有空格
  if判断有一堆的参数,如下

参数含义样式
-z是否为空串[ -z $myvar ]
-f filename如果 filename为常规文件,则为真[ -f “${A}”/start-dfs.sh ]
-gt大于if [ $# -gt 1 ]=>参数大于1
-e当pathname指定的文件或目录存在时返回真[ -e $myvar ]
-ge大于等于[ $# -ge 1 ]
-n非空串
-eq等于[ $# -eq 1 ]
3.5、循环

  循环主要用到两种,for循环和while循环。

for x in 1 2 3 4 5
do
    echo $x
done 

  for循环除了用in,还可以这样for ((i=1;i<10;i++)),这种方式很像Java代码。while循环:

i=1
while(($i<10))
do
    echo $i
    let "i++"   
done
3.6 case

  像其他语言switch一样,有条件的选择。

case "$promer" in
    "A")
      echo "A"
    ;;
    "B"|"C")
      echo "A"
    ;;
    *)
      echo "A"
    ;;
  esac

四、常用方法

4.1 获取当前脚本所在路径

  获取当前脚本的所在的路径有两个问题需要注意下。
  第一,pwd确实是用于获取绝对路径,但是如果你的shell脚本是test.sh,运行的时候不是本地运行,而是在上层目录运行的(如:shell/test.sh),这个时候的pwd就是上层父目录的地址。
  第二,$0,这个在不同的调用时候有不同的含义。

建议的写法:
BASEPATH=$(cd `dirname $0`; pwd)
解析:
dirname $0   <- 去除文件名中的非目录部分,仅显示与目录有关的内容,即文件所在当前目录
cd           <- 进入这个目录          
pwd          <- 获取该目录的路径
4.2 变量配置

  可以进行变量的条件替换,既只有某种条件发生时才进行替换。

变量配置方式str 没有配置str 为空字符串str 已配置非为空字符串
var=${str-expr}var=exprvar=var=$str
var=${str:-expr}var=exprvar=exprvar=$str
var=${str+expr}var=var=exprvar=expr
var=${str:+expr}var=var=var=expr
var=${str=expr}str=expr
var=expr
str 不变
var=
str 不变
var=$str
var=${str:=expr}str=expr
var=expr
str=expr
var=expr
str 不变
var=$str
var=${str?expr}expr 输出至 stderrvar=var=$str
var=${str:?expr}expr 输出至 stderrexpr 输出至 stderrvar=$str
4.3、分割字符串

  字符串要按照某种特殊字符进行分割,如下:

s="1,2,3,4,5"
OLD_IFS="$IFS"
IFS=","
arr=($s)
IFS="$OLD_IFS"
for x in ${arr[*]}
do
    echo $x
done

  讲解:IFS这个是hash内部的域分隔符,需要保留之前的值,在字符串再转数组的时候,自动使用IFS将字符串切分。
  或者,如下使用的替换“,”为“ ”方式,然后转化成数组。

arr2=(${s//,/ })
for x in ${arr2[*]}
do
    ehco $x
done
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值