Linux--Shell编程

mkdir sh

cd sh

#! /bin/bash
cd /tmp
echo "hello world"

如何运行shell程序

  1. 赋予程序文件可执行权限,直接运行./shellfile:./first.sh
  2. 调用命令解释器(Shell)解释执行:bash first.sh
  3. 使用source命令执行:source first.sh

 

Shell的命令种类

  • 内部命令:是Shell解释器本身包含的命令,在文件系统没有相应的可执行文件,如cd,echo,source,pwd。执行内部命令时,不需要创建新进程,当然也就不需要销毁进程
    • source命令也称为 .命令,可以用 “.”代替source
  • shell函数:用shell语言编写的一系列程序代码,可以像其他命令一样被引用
  • 外部命令:会创建一个新进程来执行如:locate,grep,ifconfig,ls,find,
    • 执行过程:
      • 系统调用fork()创建一个Shell的复制进程(子进程)
      • 在子进程的运行环境中,查找并且载入外部命令,以外部命令的程序代码取代Shell子进程,父Shell进程休眠并等待子进程执行完毕
      • 子进程执行完毕后,父Shell进程被唤醒并继续从终端读取下一条命令

Shell执行命令的顺序

别名-->关键词-->函数-->内部命令-->外部命令

  • type:可以查看所要执行的命令是哪种类型,type ls
  • 以"#"开头的文本表示注释,会忽略#之后的所有内容
  • 每一条Shell命令在推出时都会返回一个整数值给命令行Shell,该返回值表示Shell命令的退出状态,一般约定0表示成功,非零值表示失败。通过特殊变量$?查看上一条命令的退出状态,echo $?
  • 各命令之间要以 ; 分隔开来;此外也可以用&&和||连接两条命令,这两种有短路特性
  • 符合命令:
    • 可以用 {} 或 () ,{}括起来的命令在本shell内执行,不产生新进程,()在一个子进程内执行

Shell变量

  • 变量的名称应该由字母,数字或者下划线组成,并且只能以字母或下划线开头,区分大小写,名称长度没有限制
  • 变量名=变量值,中间不能有空格,如果变量值中包含空格,需要加上单引号或者双引号。引用变量时,在变量名前面加上"$"符号
  • shell变量本质上是一个键值对(也就是说有hash),这和python的字符串很像,也有hash
  • 在变量名后面紧跟一个由非空白字符开始的字符串时,为了使变量名和气候的字符串区分开来,应该用花括号"{}"将变量名括起来
  • unset命令可以将一个变量的值清除(变成空串)
  • {$#变量名}:得到变量的长度,也就是字符数
  • 命令替换:
    • 反引号
    • $(...)
  • 变量属性声明:declare或者typeset
    • -r:只读
    • -i:整数,因为变量默认是字符串类型,所以有的时候需要这个
    • -a:数组
    • -f:函数
    • -x:导出变量
  • 数组变量:和普通变量一样,不需要先定义或者先赋值再使用,没有赋值的情况下,数组元素的值就是空串
    • 赋值:数组名[下标]=值
    • 引用数组元素:${数组名[下标]}
    • 组合赋值:数组名=(值1,值2,值3...),各个值之间要以空格分开,比如arr=(how are you ?)
    • ${arr}其实就等于${arr[0]},
    • 两个特殊的变量引用:${数组名[*]}和${数组名[@]}
      • ${数组名[*]}:引用数组的所有非空元素,且拼接成一个字符串
      • ${数组名[@]}:引用数组的所有非空元素,仍然是单个元素,可迭代
      • ${#数组名[*]}和${#数组名[@]}:数组中所有非空元素的个数
  • 变量引用操作符:${...}除了简单的引用变量之外,还有字符串替换,模式匹配替换
    • 字符串匹配:
      • ${varname:-word}:如果varname存在且非空串,返回varname的值,否则返回word
      • ${varname:=word}:如果varname存在且非空串,返回varname的值,否则将varname的值设置为word
      • ${varname:+word}:如果varname存在且非空串,返回word的值,否则返回空串
      • ${varname:?message}:如果varname存在且非空串,返回varname的值,否则输出message,并且退出当前脚本程序--->类似于捕获错误
      • 冒号都可以省略,省略的话则只判断varname是否存在
    • 模式匹配:filepath=/home/alice/major.minor.ext
      • ${varname#pattern}:如果pattern匹配varname的头部,则删除最短匹配部分,返回剩余部分,varname本身不变
        • echo ${filepath#/*/}---->alice/major.minor.ext
      • ${varname##pattern}:如果pattern匹配varname的头部,则删除最长匹配部分,返回剩余部分,varname本身不变
        • echo ${filepath##/*/}---->major.minor.ext
      • ${varname%pattern}:如果pattern匹配varname的尾部,则删除最短匹配部分,返回剩余部分,varname本身不变
        • echo ${filepath%.*}---->/home/alice/major.minor
      • ${varname%%pattern}:如果pattern匹配varname的尾部,则删除最长匹配部分,返回剩余部分,varname本身不变
        • echo ${filepath%%.*}---->/home/alice/major
      • ${varname/pattern/string}或${varname//pattern/string}:如果pattern匹配varname的某个子串,则将varname的最长匹配部分替换成string,并返回替换后的串,varname本身不变。如果模式以'#'开头,则表示匹配varname的首部,如果模式以'%'开头,则表示匹配varname的尾部。如果string为空串,匹配部分将被删除。如果varname为@或者*,操作将被依次用于每个位置参数,并且扩展为结果列表。第一种格式仅替换第一次匹配的子串,第二种格式会替换所有匹配的子串
  • 位置参数和特殊变量
    • 位置参数:也称为位置变量,运行Shell脚本程序时,命令行Shell传递给脚本的参数,以及在Shell脚本程序中调用函数时传递给函数的参数。变量的名称是以0,1,2,3......这些整数命名的。使用$0,$1,$2引用这些变量。注意:${10}这样的不能用$10表示。$0表示脚本名
    • 特殊变量:
      • $#:命令行上参数的个数,不包含脚本名本身,就是说$0
      • $*:以一个单字符串显式向脚本程序传递所有参数,不包括$0
      • $@:从参数1开始,显式向脚本程序传递的所有参数,如果放在双引号中扩展,则"$@"与"$1" "$2" "$3"...等效
      • $?:上一条命令执行后的返回值,也就是退出状态,0为成功
      • $$:运行脚本的当前进程进程号
      • $!:上一个后台命令对应的进程号
      • $.:由当前Shell设置的执行标志名组成的字符串
    • 不加双引号的$@和$*的作用是一样的,加上双引号的"$@","$*"在特殊场合作用会有所不同,"$@"是引用所有参数,可以进行迭代,"$*"表示引用所有参数连接在一起,中间用空格分开,是一个字符串。"${数组名[@]}"表示引用数组整体的各个元素
    • 位置变量不能由用户直接设置,但是可以用set命令间接的设置除$0之外的位置变量的值
    • #! /bin/bash
      # setposvar.sh
      set learn linux program
      echo $0 $1 $2 $3

       

    • shell内置了shift,用于左移位置参数,也就是原来的$2的值赋给$1(原$1的值永远丢失),$3的值赋给$2。。。
    • #! /bin/bash
      # shiftposvar.sh
      set learn linux program
      echo "parameter number: $#,they are:"
      echo $1 $2 $3
      shift
      echo "after shifted, parameter number: $#, they are:"
      echo $1 $2 $3
      
      # execute
      bash shiftposvar.sh one two three
      
      # result
      parameter number: 3,they are:
      one two three
      after shifted, parameter number: 2, they are:
      two three

       

    • read命令:用于从键盘上读取数据并且赋值给指定的变量,read命令可编写交互式脚本程序,格式:read 变量1 [2]
  • export语句:
    • 在同一Shell中,变量的值是可见的,但是在子shell中,父shell的变量是不可见的
    • 子进程只能继承父进程的公有区和转出区中的数据,私有区是进程私有的不能继承
    • 为父进程定义的变量对其子进程的运行环境不产生任何影响,为了使其各个子进程能继承父进程中定义的变量,就必须用export命令将这些变量送入进程转出区。
    • 子进程可以读取但无法改变父进程中export出来的变量的值 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值