Shell脚本编程(一)

摘要:
Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。用printenv命令可以显示当前Shell进程的环境变量。

shell 脚本编程(一)

1 . shell 的作用

  • Shell的作用是解释执行用户的命令,用户输入一条命令,Shell就解释执行一条,这种方式称为交互式(Interactive),Shell还有一种执行命令的方式称为批处理(Batch),用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。Shell脚本和编程语言很相似,也有变量和流程控制语句,但Shell脚本是解释执行的,不需要编译,Shell程序从脚本中一行一行读取并执行这些命令,相当于一个用户把脚本中的命令一行一行敲到Shell提示符下执行。

  • 用户在命令行输入命令后, 一般情况下Shell 回fork一个子进程并exec该命令, 但是shell的内建命令例外, 执行内建命令相当与调用shell进程中的一个函数, 并不会创建新的进程, 例如:cd、alias、umask、exit 等命令都是内建命令, 凡是用which 命令查不到程序文件所在位置的命令都是内建命令, 内建命令没有单独的man手册, 要在man手册中查看内建命令, 应该用

    # 查看内建的命令
    $ man bash-builtins
    
  • 写一个简单的shell脚本, t1.sh

    #!/bin/sh
    cd ..
    ls
    
    

    说明:

    shell 脚本中用# 表示注释, 相当于C语言的//注释, 但如果#位于第一行开头, 并且是 #!(称为Shenbang)则例外, 它表示该脚本使用后面指定的解释器/bin/sh解释执行。 如果把这个脚本文件加上课执行权限然后执行

    chmod a+x t1.sh
    # 通过 ./ 执行shell脚本
    ./t1.sh
    

    说明:

    Shell 会fork一个子进程并调用exec执行 ./t1.sh这个程序, exec系统调应该把子进程的代码段替换成 ./t1.sh 程序的代码段, 并从它的 _start 开始执行, 然而 t1.sh 是个文本文件, 根本没有代码段和 _start 函数, 那怎么办??

    其实exec 还有另外以一种机制, 如果要执行的是一个文本文件, 并且第一行用Shebang指定的解释器, 则用解释器程序的代码段替换当前进程, 并且从解释器的 _start 开始执行, 而这个文本文件被当作命令参数传给解释器, 因此, 执行上述脚本相当于执行程序。

  • 执行shell 脚本的方式:

    # 通过source 命令执行.sh文件
    $ source t1.sh
    # 如果给文件添加了可执行权限, 可以通过一下方式执行shell 脚本
    $ chmod a+x t1.sh # 给该文件添加可执行权限
    # 通过./执行脚本
    $ ./t1.sh
    #直接用解释器去执行该文件
    $ /bin/sh ./t1.sh
    

  • 如果将命令行下输入的命令用()括起来, 这样也会fork 一个子Shell 执行 ()括号中的命令, 一行可以输入由分号 ;隔开多条命令。

    [czk@localhost ~]$ (cd ..;ls -l)
    total 0
    drwx------. 2 czk czk 98 May 18 22:50 czk
    
    
  • 如果没有用括号将命令括起来, 则是在当前的shell进程进行执行, 并不会fork一个子进程进行去执行该命令。

2.基本变量

变量的类型

  • 本地变量

    只存在于当前Shell进程, 用set命令可以显示当前shell进程中定义的所有变量, 包括本地变量、环境变量和函数。

    # 定义本地变量, 等号 = 两边不能由空格,变量名一般用大写+下划线组成
    [czk@localhost ~]$ VARNAME=czk
    
    
  • 环境变量

    环境变量可以从父进程传给子进程, 因此Shell进程的环境变量可以从当前shell进程传给fork出来的子进程。用printenv命令可以显示当前Shell进程的环境变量。

    # 使用export 命令可以将本地变量导出为环境变量
    [czk@localhost ~]$ export VARNAME=czk
    # 使用 unset 命令可以删除本地或环境变量
    [czk@localhost ~]$ unset VARNAME
    [czk@localhost ~]$ echo ${VARNAME}
    # 空。。。。 
    
    

    变量可以通过 $ 或者 ${varname} 进行取值

    注意,在定义变量时不用$,取变量值时要用$。和C语言不同的是,Shell变量不需要明确定义类型,事实上Shell变量的值都是字符串,比如我们定义VAR=45,其实VAR的值是字符串45而非整数。Shell变量不需要先定义后使用,如果对一个没有定义的变量取值,则值为空字符串。

3.命令代换

**` ** 或者 **$() **

由 反引号 括起来的也是一条命令, Shell 先执行该命令, 然后将输出结果立刻代换到当前命令行中。如下:

# date 日期函数
[czk@localhost ~]$ DATE=`date`
[czk@localhost ~]$ echo $DATE
Sat May 18 23:45:47 EDT 2019
# $() 方式
[czk@localhost ~]$ DATE=$(date)
[czk@localhost ~]$ echo $DATE
Sat May 18 23:47:20 EDT 2019

4.文件名代换

主要是用通配符就将文件匹配替换

 * :匹配0个或者多个任意字符
 ?:匹配一个任意字符
 [若干字符] : 匹配方括号中任意一个字符的一次出现

5.算术代换

$(())

这个是用来进行算术运算, $(()) 中的shell 变量取值将转换成整数, 如下:

# $(())中只能用+-*/和()运算符,并且只能做整数运算。
[czk@localhost ~]$ NUM=99
[czk@localhost ~]$ echo $(($NUM+1))
100

6.转义字符

在shell中被用作转义字符用于去除紧跟其后的单个字符的特殊意义,

比如创建一个"$ $" 的文件

[czk@localhost ~]$ touch $ $
[czk@localhost ~]$ ls
$ $  test.sh

还有一个字符也比较特殊, 它没有说明特殊含义, 但是用来做文件名也是比较麻烦的, 那就是 - 号。

它会把和它连在一起的字符, 当成了命令行参数的命令选项了,如果你硬要用 它来作文件名, 可以有如下两种方式:

[czk@localhost ~]$ touch ./-hi
[czk@localhost ~]$ ls
$ $  -hi  test.sh

OR

[czk@localhost ~]$ touch -- -hello
[czk@localhost ~]$ ls
$ $  -hello  -hi  test.sh

7.单引号和双引号

Shell 脚本中的单引号和双引号一样都是字符串的界定符,而不是字符的界定符, 单引号用于保存引号内所有字符的字面值, 即使引号内的和回车也不例外,但是字符串中不能出现单引号。如果引号没有配对就输入回车,Shell会给出续行提示符,要求用户把引号配上对。

[czk@localhost ~]$ echo '$SHELL'
$SHELL

被双引号用括住的内容,将被视为单一字串。它防止通配符扩展,但允许变量扩展。这点与单引号的处理方式不同。

[czk@localhost ~]$ DATE=$(date)
# 如果是双引号, 还会继续展开里面的内容
[czk@localhost ~]$ echo "$DATE"
Sun May 19 02:31:05 EDT 2019
[czk@localhost ~]$ echo '$DATE'
$DATE

免责声明:文章转载自《Shell脚本编程(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Linux基础学习(全)高成就者的5个共同点下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Impala的安装和使用

通过本地yum源进行安装impala所有cloudera软件下载地址 http://archive.cloudera.com/cdh5/cdh/5/ http://archive.cloudera.com/cdh5/ 1、 impala的介绍imala基本介绍 impala是cloudera提供的一款高效率的sql查询工具,提供实时的查询效果,官方测试性能...

第01课 安装并配置ROS环境

1. 安装ROS   注意事项:      如果你是使用类似apt这样的软件管理器来安装ROS的,那么安装后这些软件包将不具备写入权限,当前系统用户比如你自己也无法对这些软件包进行修改编辑。     当你的开发涉及到ROS软件包源码层面的操作或者在创建一个新的ROS软件包时,你应该是在一个具备读写权限的目录下工作,就像在你当前系统用户的home目录下一样。...

BAT教程 第三节(FOR命令中的变量)

FOR命令中有一些变量,他们的用法许多新手朋友还不太了解,今天给大家讲解他们的用法!先把FOR的变量全部列出来:     ~I          -删除任何引号("),扩展%I     %~fI        -将%I扩展到一个完全合格的路径名     %~dI        -仅将%I扩展到一个驱动器号     %~pI        -仅将%I扩展到一...

Windows系统下curl的下载和配置

curl的下载和配置 简介:用URL规则在命令行下工作的文件传输工具。 下载:下载地址为 https://curl.haxx.se/download.html,在最底部找到Windows的版本,我下载的是Win64 x86_64 7zip 7.56.1,解压即可。 环境变量配置:为了更方便的在任何路径下都可以使用curl命令,可以以将地址加入环境变量...

插入格式|分章节显示参考文献|修改参考文献格式

信息检索: 与online同步需要新建library 修改参考文献格式: 分章节显示参考文献: 转自:[穿越星空](http://blog.sciencenet.cn/blog-485-448980.html) 插入Chinese Std GBT7714 (author-year)及Chinese Std GBT7714 (numeric)格式 在引...

JavaScriptDate(日期)

如何使用Date()方法获取当日的日期。 getFullYear(); 使用getFullYear()获取年份。 getTime(); getTime()返回1970年1月1日至今的毫秒数。 setFullYear(); 使用setFullYear()设置具体日期。 toUTCString(); 使用toUTCString()将当前日期(根据UTC)转换为...