shell编程之类型和环境变量

什么是shell

shell 英文是贝壳的意思,它是一个命令解释器,它的作用是解释执行用户输入的命令及程序等,用户每输入一条命令,Shell就解释执行一条。这种从键盘一输入命令,就可以立即得到回应的对话方式,称为交互式。
Shell 存在于操作系统的最外层,负责与用户直接对话,把用户的输入解释给操作系统,并处理各种各样的操作系统输出结果,然后返回给用户。
输入系统用户名和密码并登录到 linux 后的所有操作都是由Shell解释与执行的。
在这里插入图片描述
当命令或者程序语句不在命令行下执行,而是通过一个程序文件来执行时,该程序就被称为shell脚本shell 脚本本质上是命令的堆砌,但是因为命令的执行并不具有幂等性,所以需要判断来进行控制程序流程。

查看系统支持的 shell 列表,列表中的shell又叫安全shell
现在各种linux发行版默认配置的是bash,这是由GUN项目组开发,主要目标是与POSIX标准保持一致。

## 查看系统支持的 shell 类型
cat /etc/shells
# /bin/sh             #常用shell,linux中大部分时候是指向/bin/bash
# /bin/bash           #常用shell,系统默认shell
# /sbin/nologin       #常用shell,用于禁止用户登陆
# /usr/bin/sh
# /usr/bin/bash      # 通常/bin/bash指向这里 
# /usr/sbin/nologin
## 输出 “-bash” 表示是登录式 shell
echo $0

登录shell和非登陆shell的主要区别在于启动shell时所执行的startup文件不同。

## 查看进程id
echo $$
## 查看系统的默认shell类型
echo $SHELL
# /bin/bash

shell解释器

shell 脚本文件的第一行,顶格给出解释器的路径 shebang , 用于指明解释执行当前脚本的解释器。常见的解释器:#!/bin/bash#!/usr/bin/python#!/usr/bin/perl

如果脚本的第一行不给出解释器,那么就要用对应的解释器来执行脚本,这样才能保证脚本的正常执行。例如:
如果是 shell脚本,就用 bash test.sh 执行。
如果是python脚本,就用pythontest.py`执行。

经常会有的问题是,在shell脚本中,应该选择哪种shebang呢?#!/bin/bash#!/usr/bin/env bash ?还是#!/usr/bin/bash?大部分情况下,/usr/bin/env是优先选择的,因为它提供了灵活性,特别是你想在不同的版本下运行这个脚本;而指定具体位置的方式#! /usr/bin/bash,在某些情况下更安全,因为它限制了代码注入的可能。
具体分析参见下方文章链接:
#!/usr/bin/env bash和#!/usr/bin/bash的比较
What is the difference between “#!/usr/bin/env bash” and “#!/usr/bin/bash”?

shell中的变量

shell是弱类型语言,没有任何明确的类型,所有的变量都作为字符处理。

本地变量

作用域仅为当前shell,赋值方式 name=value , 引用 $name/${name},查看变量使用 set 命令,unset 撤销变量
在这里插入图片描述
退出当前 shell: exit

环境变量

shell 通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统的全局变量,可用于所有子进程。
环境变量可以在命令中设置和创建,但用户退出命令时,这些变量的值就会丢失。
如果希望永久保存环境变量,可以配置在用户家目录下的.bash_profile或者.bashrc(非用户登录模式特有,例如远程 ssh) 文件中,或者全局配置/etc/profile/etc/bashrc(非用户登录模式特有,例如远程ssh)。

环境变量赋值方式:

  1. export name=value相当于name=value;export name;
  2. declare -x name=value 相当于name=value; declare -x name;

注意:bash 中定义了很多的内部环境变量(通常为全大写字母),用于定义 bash 的环境变量。如 PWDOLDPWDHISTSIZEHISTFILEHOME

[vagrant@nexus3 ~]$ echo $USER
vagrant
[vagrant@nexus3 ~]$ echo $UID
1000
[vagrant@nexus3 ~]$ echo $HOSTNAME
nexus3

查看所有环境变量的方法:

  1. 使用 export 不带任何参数
  2. 使用 declare -x 不带任何参数
  3. env或者 printenv 就可以直接查看环境变量列表

撤销环境变量:unset evn_name

局部变量

作用域仅为代码片段(如函数上下文)

位置参数变量

为执行脚本的进程传递参数

特殊变量

shell 内置的有特殊作用的变量,例如:

  • $?,返回0表示命令执行成功,1-255表示失败;
  • $$表示当前进程id
  • $! 获取上一个在后台工作的进程的id
  • !$ 最近一个命令或者脚本的最后一个参数。
$ bash "version"
bash: version: 没有那个文件或目录

$ echo !$
echo "version"
version

只读变量

declare -r name 或者 readonly name

只读变量无法重新赋值,也不支持 unset 撤销,存活时间为当前 shell 进程的生命周期,只有等到当前进程终止而终止。

使用readonly -p可以查看系统的只读环境变量;readonly -f key=value定义只读函数;readonly -a key=value定义只读数组变量;

shell中语句的执行顺序

  1. 分号分割命令,执行时采用并行执行方式,命令之间没有相互依赖关系。
    COMMAND1;COMMAND2;COMMAND3;...
    
  2. 使用逻辑运算符 && 串行执行方式,如果命令被 && 所分隔,那么命令也会一直执行下去,但是中间如果有命令出错的话,后续命名就不会执行,没错就一直执行到结束。
    # 一下命令之间没有相互依赖关系,顺序执行
    COMMAND1 && COMMAND2 && COMMAND3...
    
  3. 使用逻辑运算符||执行时,采用until执行方式,一旦遇到正确的命令,后续的命令就不再执行了。如果执行到错误的命令就是继续尝试执行后续命令,一直到遇到正确的命令或者结束为止。

第一个shell脚本

#!/bin/bash
echo "show some under /etc"
ls -d /etc/[pP]*
echo "translate lower to upper"
ls -d /var/* | tr 'a-z' 'A-Z'
echo "create temp file"
mktemp /tmp/test.XXXXXXXXXXXXXXX

shell脚本的执行

shell脚本是从上至下,从左至右依次执行每一行的命令及语句,如果在脚本中遇到了嵌套的子脚本时,就会先执行子脚本中的内容,完成后返回父脚本继续执行。
子shell脚本的运行是通过启动一个新的进程运行实现的
来自《跟老男孩学shell编程》

  • 脚本文件开头没有解释器: bash script-name 或者sh cript-name
  • 没有可执行权限的脚本: bash script_name或者sh cript-name
  • 拥有可执行权限的脚本: 直接通过脚本绝对路径或相对路径就可以直接执行脚本了,如 path/script_name 或者 ./script_name
  • source script-name. script-name : 这种方法通常是使用 source 或者 . (点号) 读入或加载指定的 shell 脚本到当前进程,然后执行,不会去启动新的进程。因此,使用这种方式执行脚本的时候,脚本的变量值或者函数返回值会直接留在当前进程中。这是和前面三种执行方式不同的地方。

    使用这种方式执行脚本的时候,如果脚本中有exit 1这种退出脚本的代码,当前执行脚本的shell进程就会直接退出

  • bash < script-name 或者 cat script-name
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值