Do not go gentle into that good night.|

stepForward-

园龄:3年9个月粉丝:5关注:3

shell编程

shell

什么是shell?

​ shell就是基于用户和操作系统内核之间的一个应用程序,可以让用户更简单高效安全地使用和操作linux内核。

​ shell是像javaScript,python一样,都是解释性语言(脚本语言),一边解释一边执行,不会生成任何可执行文件。

shell命令

​ shell命令分为内置命令和外部命令,一个 Shell 内置命令就是一个shell内部的函数,一个外部命令就是一个应用程序。内置命令是常驻与内存中的,而外部命令由于是一个应用程序,使用外部命令需要启动一个进程,所以相对于内置命令来说,执行外部命令相对内置命令耗时上较久。

​ 其中$PATH 变量包含的目录中几乎聚集了系统中绝大多数的可执行命令,它们都是外部命令。

​ 可以使用 type 来确定一个命令是否是内建命令:

[atguigu@hadoop01 bin]$ type ifconfig
ifconfig 是 /usr/sbin/ifconfig
[atguigu@hadoop01 bin]$ type cd
cd 是 shell 内嵌

​ shell命令基本格式:commend [选项] [参数]

​ 其中[选项]中也可以携带参数。

​ 例如:read -n 1 sex 命令用来读取一个字符并赋值给 sex 变量,其中-n 是 read 命令的选项,1 是-n 选项的参数,sex 是 read 命令的参数。

​ Shell 命令的选项和参数在本质:不管是内置命令还是外部命令,它后面附带的数据最终都以参数的形式传递给了函数。实现一个命令的一项重要工作就是解析传递给函数的参数。

执行shell脚本(多种方式)

在新进程中执行

方式1:将 Shell 脚本作为程序运行

​ Shell 脚本也是一种解释执行的程序,可以在终端直接调用(需要使用 chmod 命令给 Shell 脚本加上执行权限),如下所示:

[atguigu@hadoop01 bin]$ ls
check.sh  getsum  getsum.c  test.sh
[atguigu@hadoop01 bin]$ chmod +x ./check.sh   #给脚本添加执行权限
[atguigu@hadoop01 bin]$ ./check.sh   #执行脚本文件
4600   #当前pid

方式2:将 Shell 脚本作为参数传递给 Bash 解释器

[atguigu@hadoop01 bin]$ /bin/bash ./check.sh
4606
[atguigu@hadoop01 bin]$ bash ./check.sh #bash是一个外部命令,本质与/bin/bash一样
4607

​ 无论是方式1还是方式2,都是需要在执行脚本文件前面添加./来保证是执行当前目录下的,否则linux会去$PATH变量中去寻找,如果你配了可执行程序所在文件的环境变量则可以省./

在当前进程中执行

​ 使用source命令,source 是 Shell 内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。 你也可以理解为,source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。

# source命令格式
source filename  #方式1
. filename  #方式2
[atguigu@hadoop01 bin]$ echo $$  #输入当前进程
4574
[atguigu@hadoop01 bin]$ source check.sh #执行脚本文件
4574
[atguigu@hadoop01 bin]$ . check.sh #执行脚本文件
4574
[atguigu@hadoop01 bin]$ echo $$ #输入当前进程
4574

shell配置文件的加载

​ 无论是否是交互式,是否是登录式,Bash Shell 在启动时总要配置其运行环境,例如初始化环境变量、设置命令提示符、指定系统命令 路径等。这个过程是通过加载一系列配置文件完成的,这些配置文件其实就是 Shell 脚本文件。

​ 与 Bash Shell 有关的配置文件主要有 /etc/profile、~/.bash_profile、 ~/.bash_login、 ~/.profile、 ~/.bashrc、/etc/bashrc、 /etc/profile.d/*.sh,不同的启动方式会加载不同的配置文件。

登陆式

​ 首先会先读取和执行/etc/profile,这是所有用户的全局配置文件,其中/etc/profile还会嵌套加载 /etc/profile.d/*.sh,然后再会到用户主目录中寻找~/.bash_profile ,~/.bash_login, ~/.profile,它们都是用户个人的配置文件。其中执行的优先级从高到低排列 ~/.bash_profile >~/.bash_login>~/.profile ,只会执行其中的一个。其中用户个人的配置文件也会嵌套加载~/.bashrc配置文件。

​ 所以加载顺序是先全局配置后再用户个人配置。

非登陆式

​ 如果以非登录的方式启动 Shell,那么就不会读取以上所说的配置文件,而是直接读取 ~/.bashrc。 ~/.bashrc 文件还会嵌套加载 /etc/bashrc

总结:

profile 类配置文件只在用户登录 Shell 时会被加载执行;而 bashrc 类配置文件除在用户登录 Shell 时会被加载执行之外,每当用户打开新的 Shell 或者子 Shell 时,都会被加载执行。通过修改这些配置文件,就可以指定用户在登录 Shell 时自动执行某些操作。相关链接参考:https://blog.csdn.net/xiaobinhxb/article/details/126318016

shell编程

变量

​ 1. 变量中单引号和双引号的区别:

​ 以单引号' '包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。这 种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。

​ 以双引号" "包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。这种方式比较适合字符 串中附带有变量和命令并且想将其解析后再输出的变量定义。

​ 如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景。

  1. 将命令的结果赋值给变量

    variable=$(command)   
    variable=`{command}`  # 注意这是反引号,与单引号容易混淆,建议使用上面的赋值方式
    

    实例:

    [atguigu@hadoop01 bin]$ log=$(cat log.txt)
    [atguigu@hadoop01 bin]$ echo $log
    将命令的结果赋值给变量
    [atguigu@hadoop01 bin]$ cat log.txt
    将命令的结果赋值给变量
    
  2. 只读变量(readonly)

  3. 删除变量(unset) ,无法删除只读变量

变量的作用域

  1. 局部变量,只在函数内部生效,要加上关键字local,否则默认为全局变量,在函数外部也生效,在整个shell进程中也生效。

  2. 全局变量,在整个当前shell进程中都生效,打开一个命令行窗口就是一个shell进程,只在当前shell进程定义的变量都生效,并且是不同的shell脚本文件也是能读和取的。

  3. 环境变量,只存在于父子进程之间,使用关键字export将variable传递给子进程,并且只能父传给子,不能子传给父。如果父进程被关闭,则子进程获取的值也无法生效。

    以上变量最大作用范围也就只能在父进程和子进程之间了,如果我们想要所用的shell进程都共享同一个变量,那么只有一个办法就是在shell初始化配置文件中进行变量的初始化赋值等操作,这样所有shell进程都能使用到一个变量了。

位置参数

​ 格式:${1/2/3....n}来表示第几个参数

  1. 给函数传位置参数

    #!/bin/bash
    #定义函数
    function func(){
            echo "language: ${1}"
            echo "name: ${2}"
    }
    #调用函数  chinese赋值到${1} lixuwei赋值到${2}
    func chinese lixuwei
    

    ​ 然后执行该脚本文件:

    [atguigu@hadoop01 bin]$ bash ./test.sh 
    language: chinese
    name: lixuwei
    
  2. 给脚本文件传递位置参数

    #!/bin/bash
    
    echo "language: ${1}"
    echo "name: ${2}"
    

    执行脚本文件时传递参数:

    [atguigu@hadoop01 bin]$ bash ./test.sh chinese lixuwei
    language: chinese
    name: lixuwei
    

shell中的特殊变量

​ 例如上面提到的位置参数,就是shell编程中的其中一个特殊变量,还有其他的如下:

特殊变量 含义
${n}(n>=1) 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 $2。
$ 当前脚本的文件名
$# 传递给脚本或函数的参数个数
$@ 传递给脚本或函数的所有参数。
$* 传递给脚本或函数的所有参数。
$? 上个命令的退出状态,或函数的返回值
$$ 当前进程的pid

$@$*的区别:

​ 当 $* 和 $@ 不被双引号" "包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。 但是当它们被双引号" "包含时,就会有区别了:

"$*"会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
"$@"仍然将每个参数都看作一份数据,彼此之间是独立的。

$?获取函数返回值或者上个命令的退出状态

  1. 获取函数返回值

    #!/bin/bash
    function add(){
            return $(expr $1 + $2)
    }
    add 50 100
    result=$?
    echo $result
    

    获取函数返回值赋值到一个变量然后进行输出

    1. 获取上一个命令的退出状态

      ​ 所谓退出状态,就是上一个命令执行后的返回结果。退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1, 这和 C 语言的 main() 函数是类似的。

      #!/bin/bash
      if [ "$1" == 100 ]
      then
      	exit 0 #参数正确,退出状态为 0
      else
       	exit 1 #参数错误,退出状态 1
      fi
      

      输入不同数字查看退出状态:

      [atguigu@hadoop01 bin]$ bash ./test.sh 100  
      [atguigu@hadoop01 bin]$ echo $?
      0
      [atguigu@hadoop01 bin]$ bash ./test.sh -100
      [atguigu@hadoop01 bin]$ echo $?
      1
      
      

shell中的内置命令

​ $PATH 变量包含的目录中几乎聚集了系统中绝大多数的可执行命令,它们都是外部命令。

​ 通常来说,内建命令会比外部命令执行得更快,执行外部命令时不但会触发磁盘 I/O,还需要 fork 出一个单独的进程来执行,执行完成后再退出。而执行内建命令相当于调用当前 Shell 进程的一个函数。

​ 常用的几个内置命令有echo,read,exit,declare等,不会就去百度或者文档查找使用说明即可。这里我就不总结了,详细的可以去看c语言中文网哈。

本文作者:sunshineTv

本文链接:https://www.cnblogs.com/sunshineTv/p/17460116.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   stepForward-  阅读(13)  评论(0编辑  收藏  举报
@format
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.