精华内容
下载资源
问答
  • shell脚本入门

    2018-03-08 09:39:28
    shell脚本入门 shell脚本入门 shell脚本入门 shell脚本入门
  • Shell脚本入门

    2021-01-31 15:49:03
    shell脚本入门

    1.shell脚本基础知识

    shell脚本是以 .sh 结尾的

    # 新建一个脚本
    vim shell_test.sh
    

    shell脚本里面的内容要是可执行的

    #! /bin/bash
    123  # 这样的话无法执行
    echo 'python'  # 这样的话才能执行
    

    shell脚本的注释

    #! /bin/bash     第一行必然以这个开头,第一行的 # 不算注释
    # echo 'python'  从第二行开始, # 代表单行注释
    
    # 下面的内容是多行注释
    :<<!
    要被注释的内容
    !
    
    # 多行注释也可以这么写,总是要保证一一对应
    :<<a
    要被注释的内容
    a
    

    shell脚本的执行方式

    最推荐的方式

    /bin/bash 脚本文件名.sh
    

    第二种方式,这种方式必须加可执行权限才能运行

    # 先给脚本文件加上可执行权限,例如 chmod +x test.sh
    # 然后在脚本文件所在的目录执行以下命令
    ./test.sh
    

    第三种方式,不管加不加可执行方式都会执行,一般用的比较少,多用来加载脚本文件中的环境变量

    source test.sh
    

    shell脚本解释器的优先级

    1.shell脚本内容的第一行必然是 #! /bin/bash ,这个解释器的优先级最高

    2.其次是执行的时候执行的解释器 例如 /bin/bash test.sh

    3.最后才是 系统自带的默认的解释器版本,在终端中输入 echo $SHELL 可以查看默认的解释器版本

    输入 cat /etc/shells , 可以查看所有的解释器版本

    shell中的变量

    shell中的变量一共分为3种,本地 全局 内置变量

    shell中的本地变量

    本地变量分为:普通变量和命令变量

    普通变量

    变量名=变量值

    变量值必须是一个整体,不能包含特殊字符

    $age  # 先定义一个变量
    age=19  # 然后对变量进行赋值
    echo $age  # 结果是  19
    
    # 必须要是一个整体,不能有特殊字符,例如:
    $age
    age=19 abc
    echo $age  # 执行的时候就会报错,因为多了 空格
    
    

    变量名=‘变量值’, 原字符输出,原来啥样,输入的就是啥样

    $age
    age='123 456'  # ''里面的内容会原样输出
    echo $age  # 结果就是 123 456
    

    变量名=“变量值”

    先看变量值范围中有没有可以解析的变量,如果有,则先解析,然后整体赋值给新的变量名a,负责直接赋值 给变量名a

    $age
    age='123 456'
    
    $name
    name="mingwei $age"  # 变量的值里面包含着另一个变量的名称,千万不要忘记加 $ 符
    echo $name  # 结果是 mingwei 123 456 ,先把包含的变量的名称解析执行后,再把整体结果赋值给name
    

    命令变量

    变量名=``

    command=`pwd`
    echo $command  # 结果就是pwd命令被执行了
    

    变量名=$(命令)

    先执行命令,然后将执行完毕的结果交给新的变量名

    user=$(whoami)  # $(括号里面存放的是可执行命令)
    echo $user		
    

    SHELL中的全局变量

    全局变量是在什么地方都能用的变量

    查看系统中自带的全局变量

    env

    XDG_VTNR=7
    LC_PAPER=en_US.UTF-8
    LC_ADDRESS=en_US.UTF-8
    XDG_SESSION_ID=c2
    XDG_MENU_PREFIX=gnome-
    SHELL=/bin/bash
    QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1
    WINDOWID=60828225
    LC_NUMERIC=en_US.UTF-8
    UPSTART_SESSION=unix:abstract=/com/ubuntu/upstart-session/1000/2050
    GNOME_KEYRING_CONTROL=
    GTK_MODULES=gail:atk-bridge:unity-gtk-module
    NVM_DIR=/home/fengyehong/.nvm
    USER=fengyehong
    ......
    

    过滤出自己想要的变量

    env | grep SHELL

    结果是: SHELL=/bin/bash

    定义一个全局变量

    export 变量=值

    export name=jiamingwei
    env | grep name  # 过滤出定义的name
    
    # 结果是:
    name=jiamingwei
    

    查看定义的全局变量(共四种方法)

    echo $name
    echo "$name"
    
    # 下面两种用的多一些
    echo ${name}
    echo "${name}"
    

    变量的取消(对取消全局变量和本地变量都通用)

    unset 变量名

    unset name  # 取消全局变量
    unset age  # 取消本地变量
    

    SHELL中的内置变量

    $0 $n $ $# $?
    

    $0 获取当前执行的shell脚本文件名

    新建一个脚本文件,名称为 : get_shell_name.sh

    内容为:

    #! /bin/bash
    # 获取当前脚本的名称
    echo "当前脚本名称 :get_shell_name.sh"
    echo "当前脚本名称 :$0"
    

    /bin/bash get_shell_name.sh 去执行脚本

    结果为:

    echo "当前脚本名称 :get_shell_name.sh"
    echo "当前脚本名称 :get_shell_name.sh"
    

    用 mv get_shell_name.sh get_shell.sh 命令给脚本文件重命名,然后再重新执行脚本文件

    # 结果为:
    当前脚本名称 :get_shell_name.sh
    当前脚本名称 :get_shell.sh
    

    $n

    获取当前执行的shell脚本的第n个参数值, n=1…9,当n为0时表示脚本的文件名,如果n大于9就要用大 括号括起来${10}

    新建一个文件夹,名称为: get_args.sh

    内容为:

    #! /bin/bash
    # 获取参数
    echo "第1个位置的参数是:$1"
    echo "第2个位置的参数是:$2"
    echo "第3个位置的参数是:$3"
    echo "第4个位置的参数是:$4"
    

    用以下命令执行:

    /bin/bash get_args.sh a b c d   # 参数和参数之间用空格来空开
    

    结果为:

    第1个位置的参数是:a
    第2个位置的参数是:b
    第3个位置的参数是:c
    第4个位置的参数是:d
    

    $# 自动获取当前脚本参数的总的个数

    新建一个脚本,名称为:get_args_num.sh

    内容如下:

    #! /bin/bash
    # 获取当前脚本的参数的总个数
    echo "当前脚本的总个数为:$#"
    

    执行如下命令运行脚本

    /bin/bash get_args_num.sh
    

    因为没有添加参数,所以结果是: 当前脚本的总个数为:0

    执行如下命令运行脚本

    /bin/bash get_args_num.sh 1 2 3
    

    因为添加了参数,所以结果为: 当前脚本的总个数为:3

    $?

    获取上一条命令执行的结果,成功返回0,失败则返回非0
    在这里插入图片描述

    字符串精确截取

    格式: ${变量名:起始位置:截取长度}
    在这里插入图片描述

    默认值相关

    场景一:
    
    变量a如果有内容,那么就输出a的变量值 变量a如果没有内容,那么就输出默认的内容  
    
    格式: ${变量名:-默认值}  
    

    新建一个脚本文件,内容如下:
    在这里插入图片描述

    执行脚本文件
    在这里插入图片描述

    场景二:
    
    无论变量a是否有内容,都输出默认值  
    
    格式: ${变量名+默认值}  
    

    新建一个脚本文件,内容如下:
    在这里插入图片描述

    执行脚本文件
    在这里插入图片描述

    2.shell进阶

    2.1 测试语句

    在这里插入图片描述

    2.2 条件表达式

    2.2.1 逻辑表达式

    逻辑表达式一般用于判断多个条件之间的依赖关系。

    常见的逻辑表达式有: && 和 ||

    && 的格式: 命令1 && 命令2

    如果命令1执行了,命令2才执行,命令1不执行,命令2也不会执行
    在这里插入图片描述

    ||的格式: 命令1 || 命令2

    如果命令1没有执行,命令2才会执行,命令1执行了,命令2不会执行
    在这里插入图片描述

    2.2.2 文件表达式

    -f 判断输入内容是否是一个文件
    在这里插入图片描述

    -d 判断输入内容是否是一个目录
    在这里插入图片描述

    -x 判断输入内容是否可执行
    在这里插入图片描述

    2.2.3 数值操作符

    n1 -eq n2 相等
    n1 -gt n2 大于
    n1 -lt n2 小于
    n1 -ne n2 不等于
    在这里插入图片描述

    2.2.4 字符串之间的比较

    在这里插入图片描述

    2.3 计算表达式

    方式一: $ (( 计算表达式 )) 表达式范围内,空格不限制 $ 表达式种只能用±*/和()运算符,并且只能做整数运算
    在这里插入图片描述

    方式二: let 计算表达式 表达式必须是一个整体,中间不能出现空格等特殊字符
    在这里插入图片描述

    2.4 linux的常见命令符号

    & : 后台展示符号 &

    就是将一个命令从前台转到后台执行
    在这里插入图片描述

    全部信息符号 2>&1

    符号详解:

    1 表示正确输出的信息

    2 表示错误输出的信息

    2>&1 代表所有输出的信息

    新建一个文件,内容如下:

    #! /bin/bash
    # 测试2>&1的使用
    echo "这是一条测试信息"
    oaisoiwh     
    

    在终端执行以下命令:
    在这里插入图片描述

    工作中启动Django

    # 把执行效果放到file里面,同时在后台执行
    python manager runserver >> file 2>&1 &
    

    linux系统垃圾桶

    /dev/null 是linux下的一个设备文件, 这个文件类似于一个垃圾桶,特点是:容量无限大

    可以把一些无用信息放到里面,一旦放进去就收不回来了

    # 例如有一些访问成功的200和访问失败之类的404的信息不想要,可以把这些信息放到垃圾桶里面
    python manager runserver >>/dev/null 2>&1 &
    

    grep命令

    在这里插入图片描述

    小技巧

    grep -nr 关键字 路径   # 从路径下,递归的查找所有符合条件的关键字
    

    在这里插入图片描述

    sed命令讲解

    替换操作

    样式一: sed -i ‘行号s#原内容#替换后内容#列号’ [文件名] # 行号不写,表示所有行,列号不写,表示第一个
    在这里插入图片描述在这里插入图片描述

    样式二: sed -i ‘s#原内容#替换后内容#g’ [文件名] # g 表示指定行的所有匹配内容
    在这里插入图片描述

    增加操作

    在指定行号的下一行增加内容

    格式: sed -i ‘行号a\增加的内容’ 文件名
    在这里插入图片描述

    注意: 如果增加多行,可以在行号位置写个范围值,彼此间使用逗号隔开,例如 sed -i ‘1,3a\增加内容’ 文件名

    在1到3行,每一行后面都增加内容
    在这里插入图片描述

    删除操作

    指定行号删除 格式: sed -i ‘行号d’ 文件名
    在这里插入图片描述

    如果删除多行,可以在行号位置多写几个行号,彼此间使用逗号隔开,例如 sed -i ‘1,3d’ 文件名
    在这里插入图片描述

    awk命令讲解

    awk是一个功能非常强大的文档编辑工具,它不仅能以行为单位还能以列为单位处理文件。

    命令格式: awk [参数] ‘[ 动作]’ [文件名]
    在这里插入图片描述

    常见动作(适用于分隔符是空格的情况)
    在这里插入图片描述

    NR的使用(适用于分隔符是空格的情况)
    在这里插入图片描述

    BEGIN{OFS=" "} 来指定输出的分隔符号
    在这里插入图片描述

    find命令

    命令格式: find 路径 参数 关键字
    在这里插入图片描述

    代码
    在这里插入图片描述

    find过滤掉文件夹只留下文件
    在这里插入图片描述

    3.流程控制

    3.1 单分支if语句

    3.2 双分支if语句

    在这里插入图片描述

    代码演练
    在这里插入图片描述

    3.3 多分支语句

    在这里插入图片描述

    3.4 case选择语句

    在这里插入图片描述

    代码实现
    在这里插入图片描述

    case调用
    在这里插入图片描述

    3.5 for遍历的使用

    在这里插入图片描述

    代码实现:
    在这里插入图片描述

    3.6 while循环的使用

    在这里插入图片描述

    代码实现
    在这里插入图片描述

    容易出现的错误
    在这里插入图片描述

    3.7 until语句的使用

    格式和while格式基本一样

    代码实现
    在这里插入图片描述

    4.函数的使用

    格式:
    在这里插入图片描述

    代码实现:
    在这里插入图片描述

    5.代码的发布

    5.1 代码发布简介	
    	5.1.1 代码发布介绍	
    			发布:
    				代码 		功能完善
    				服务器 		公网IP,域名备案
    				效果		web+app
    					
    	5.1.2 发布方式
    		手工 
    			慢 干扰因素多 不安全
    			是脚本的基础
    		脚本
    			快,干扰因素少 安全
    			依赖手工发布代码
    			
    5.2 代码发布流程	
    	5.2.1 流程简介	
    		获取代码
    			因为发布
    		打包代码
    			代码量大,不好传输
    		传输代码
    			跨主机
    		关闭应用
    			避免对用户造成不好的干扰
    		解压代码
    			因为传输的是压缩包
    		放置代码
    			放新的代码
    		开启应用
    			刚才关闭了
    		内部检查
    			放置露脸
    		对外开放
    		
    	5.2.2 流程详解
    		获取代码
    			代码仓库 代码权限
    		打包代码
    			tar
    		传输代码
    			scp
    		关闭应用
    			先近后远
    			先关nignx,再关django
    		解压代码
    			tar
    		放置代码
    			先备份。在放置新文件
    		开启应用
    			先远后近
    			先开启django,再开启nginx
    		内部检查
    			浏览器。端口、进程,等等
    		对外开放
    

    技术的关键点

    5.1 文件的压缩和解压缩

    压缩格式: tar zcf 压缩后的文件名 要压缩的文件

    tar zcf python12.tar.gz   python12
    

    解压缩格式: tar xf 要解压的文件名(后面什么都不写,默认解压到当前目录)

    tar xf python12.tar.gz
    

    查看压缩包内容: zcat 压缩后的文件名

    zcat python12.tar.gz
    

    5.2 scp 跨主机传输文件

    格式: scp 要传输的文件 要传输到的位置

    scp python12.tar.gz root@192.168.8.14:/home/python/Desktop   # 传输到桌面文件夹,回车会要求输密码
    

    拉取:要传输的文件是远程主机的,把远程主机的文件拉到本地

    scp root@192.168.8.15:/tmp/python12.tar.gz /home/python/Desktop  # 拉取到本地桌面文件夹
    

    关键点: scp 传输文件是基于ssh协议来进行通信的 , 使用ssh登录的方式认证

    5.3 备份文件

    时间戳

    date +%F # 显示年月日  date +%T # 显示时分秒
    
    date +%Y-%m-%d       date +%H:%M:%S
    

    在这里插入图片描述

    备份文件,给一个文件加上时间戳

    cp python12.tar.gz python12.tar.gz-$(date +%Y%m%d%H%M%S)
    # 或
    mv python12.tar.gz python12.tar.gz-$(date +%Y%m%d%H%M%S)
    

    6.环境的部署

    { }的作用,创建多个文件夹
    在这里插入图片描述

    { }的作用,创建多个文件
    在这里插入图片描述

    6.1 两台主机间免密码认证

    第一步 ssh-keygen -t rsa 生成密钥(公钥和私钥)
    在这里插入图片描述

    第二步 进入保存密钥的文件夹,把公钥的内容复制出来
    在这里插入图片描述

    第三步 进入另一台主机,进入 隐藏的 .ssh文件夹,新建 authorized_keys文件,把公钥贴进去

    注意,存放公钥的文件名称可以更改,但是后期需要修改系统的文件内容,不建议修改
    在这里插入图片描述

    第四步 进入这个文件夹,修改配置文件
    在这里插入图片描述
    在这里插入图片描述

    第五步 重启服务
    在这里插入图片描述

    然后就可以在另一台主机上免密码传输文件了.

    还有一种办法

    ssh-keygen -t rsa -p "" -N ""  # 先生成密钥文件
    ssh-copy-id -i .ssh/id_rsa.pub root@192.168.8.15(表示把公钥文件直接传输到对方的主机上,之后就可以免密码使用了)
    

    6.2 另一种方式创建python虚拟环境

    第一步: 安装虚拟环境软件

    sudo apt-get install python-virtualenv -y
    

    第二步: 创建好存放虚拟环境的目录,并且进入该目录指定python版本,并创建相应的虚拟环境
    在这里插入图片描述

    第三步: 进入虚拟环境中(原先的workon就是执行了source的脚本)
    在这里插入图片描述

    6.3 传统方式安装Django框架(不是用pip 的方式)

    注意: 要先进入虚拟环境,下面的第一个图片安装实例有几个问题存在

    1.没有进入虚拟环境安装,我们的Django框架是要安装在虚拟环境下的

    2.需要在root用户下进行安装,否认会出现问题

    第一步: 先普通用户模式转换为root用户模式

    第二步: 再进入虚拟环境

    第三步: 把Django安装包解压

    第四步: 进入解压之后的目录,查看INSTALL文件中的内容,获取安装方法

    第五步: 执行安装命令, python setup.py install 根据情况可能会有前面加上sudo进行安装
    在这里插入图片描述

    安装的正确姿势
    在这里插入图片描述

    最终安装成功
    在这里插入图片描述

    展开全文
  • SHELL脚本入门

    2019-08-30 16:03:32
    SHELL脚本入门脚本格式执行脚本的方式脚本的变量 脚本格式 脚本采用以下格式开头作为标识,并指定解析器 #!/bin/bash 脚本就是一个命令行的集合,把多条命令放在一起逐个执行。 执行脚本的方式 #方式一: bash xx....

    脚本格式

    脚本采用以下格式开头作为标识,并指定解析器

    #!/bin/bash	
    

    脚本就是一个命令行的集合,把多条命令放在一起逐个执行。

    执行脚本的方式

    #方式一:
    bash xx.sh
    #方式二:
    ./xx.sh
    

    这两种方式在执行区别在于:

    • 通过bash来执行的话,不要求脚本有x执行权限,而方式二必须要求执行权限。
    • 通过bash来执行,第一行#!/bin/bash只是一个注释。而直接执行会读取第一行的解释器

    脚本的变量

    shell里面所有的变量都是字符串类型,所以不需要申明变量类型

    #定义变量
    i=0
    #输出变量
    echo $i
    #输出的内容是 0+0
    echo $i+$i
    #撤销变量
    unset i
    #只读变量,后续无法修改值
    readonly i=5
    

    系统预定义变量:$HOME $SHELL $USER等

    运算符

    基本语法

    • (())((运算式))”或“[运算式]”
    • expr + , - , *, /, %
    a=5
    b=5
    #输出10
    echo $[$a+$b]
    echo expr $a + $b
    

    特殊变量

    变量$n

    描述:获取脚本传入的参数信息。n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10}

    $ touch parameter.sh 
    $ vim parameter.sh  //在文件里输入以下两行
    #!/bin/bash
    echo "$0  $1   $2"
    
    $ chmod 777 parameter.sh
    $ ./parameter.sh cls  xz
    #输出 ./parameter.sh  cls   xz
    

    变量$#

    描述:获取输入参数的个数,一般用于循环

    $ vim parameter.sh    //在文件里输入以下三行
    #!/bin/bash      
    echo "$0  $1   $2"
    echo '$#'=$#
    
    $ chmod 777 parameter.sh
    $ ./parameter.sh cls  xz
    
    #输出如下内容
    parameter.sh cls xz 
    $#=2
    

    变量*和@

    描述:$* 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
    描述:$@ 功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)

    $ vim parameter.sh
    #!/bin/bash
    echo "$0  $1   $2"
    echo $#
    echo $*
    echo $@
    
    $ bash parameter.sh 1 2 3
    parameter.sh  1   2
    3
    1 2 3
    1 2 3
    

    变量$?

    描述: 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。

    条件判断

    基本语法:[ condition ](注意condition前后要有空格)

    常用判断条件:

    (1)两个整数之间比较
    = 字符串比较
    -lt 小于(less than) -le 小于等于(less equal)
    -eq 等于(equal) -gt 大于(greater than)
    -ge 大于等于(greater equal) -ne 不等于(Not equal)

    (2)按照文件权限进行判断
    -r 有读的权限(read) -w 有写的权限(write)
    -x 有执行的权限(execute)

    (3)按照文件类型进行判断
    -f 文件存在并且是一个常规的文件(file)
    -e 文件存在(existence) -d 文件存在并是一个目录(directory)

    a=5
    b=5
    [ $a = $b ]
    #相同输出0,不同输出1
    echo $?
    [ 1 -ge 2]
    echo $?
    # 输出1
    
    展开全文
  • shell 脚本入门

    2021-03-25 16:24:35
    将很多条命令放到一个文件里面,然后直接运行这个文件即可,这就是shell脚本。即shell脚本就是将连续执行的命令写成一个文件 二、shell 脚本写法 shell 脚本是纯文本文件,命令从上而下,一行一行的开始执行。shell...

    一、shell 脚本介绍:

    将很多条命令放到一个文件里面,然后直接运行这个文件即可,这就是shell脚本。即shell脚本就是将连续执行的命令写成一个文件

    二、shell 脚本写法

    shell 脚本是纯文本文件,命令从上而下,一行一行的开始执行。shell脚本扩展名为.sh
    shell 脚本第一行一定要为:

    #!/bin/bash
    

    表示使用 bash

    三、shell 脚本常见语法规则

    1.交互式shell 脚本

    echo 表示输出

    read可以读取键盘输入的字符 read后面可以接 -n -d -a 等等
    -p:给出提示符。例如,"-p 请输入密码:"

    #! /bin/bash
    read -p "input your age and height:" age height
    echo "your age=$age,your height=$height"
    

    若权限不够需要用 chmod 命令添加权限
    在这里插入图片描述

    2.shell 脚本的数值计算
    shell 仅支持整型

    #! /bin/bash
    echo "please input two num"
    read -p "first num:" first
    read -p "second num:" second
    // 注意total 和等号之间不能空格
    total=$(($first+$second)) // $((表达式))
    echo "$first + $second = $total"
    

    3.test 命令
    test命令用于查看文件是否存在、权限等信息,可以进行数值,字符,文件三方面的测试。
    如:&& 和 || 命令
    cmd1 && cmd2 当cmd1 执行完并且正确,那么cmd2 开始执行;若cmd1执行错误,则cmd2不执行
    cmd1||cmd2 当cmd1执行完毕并正确,那么cmd2不执行,反之cmd2执行

    #! /bin/bash
    echo "please input file name"
    read -p "file name:" filename
    // test -e 文件存在为真
    test -e $filename && echo "$filename exist" || echo "filename no exist"
    

    4.中括号[ ] 判断符

    #! /bin/bash
    echo "please input two str"
    read -p "first:" str1
    read -p "second:" str2
    // 注意中括号与字符之间的空格
    [ "$str1" == "$str2" ] && echo "str1==str2" || echo "str1 != str2"
    

    5.默认变量
    $0 ~ $n 表示 shell 脚本的参数 包括shell 脚本命令本身,shell 脚本命令本身为 $0
    $#: # 表示最后一个参数的标号
    $@: 表示$1 $2 …

    #! /bin/bash
    echo "file name" $0
    echo "total param num:" $#
    echo "whole param:" $@
    echo "first param" $1
    echo "second param" $2
    

    在这里插入图片描述

    展开全文
  • shell脚本入门 有关Shell脚本的世界上最好的概念介绍来自一个古老的AT&T培训视频 。 在视频中,Brian W. Kernighan( awk中的“ K”)和Lorinda L.Cherry( bc的合著者)演示了UNIX的一项创始原理是如何使用户能够...

    shell脚本入门

    有关Shell脚本的世界上最好的概念介绍来自一个古老的AT&T培训视频 在视频中,Brian W. Kernighan( awk中的“ K”)和Lorinda L.Cherry( bc的合著者)演示了UNIX的一项创始原理是如何使用户能够利用现有实用程序来创建复杂的和自定义的工具。

    Kernighan的话来说:“将UNIX系统程序基本上看作是可以用来创建事物的构建块。管道内衬的概念是[UNIX]系统的根本贡献。 ;您可以使用一堆程序...并将它们首尾相连,以使数据从左侧的流向右侧的流,而系统本身负责所有连接。程序本身不会我对连接一无所知;就他们而言,他们只是在与终端交谈。”

    他正在谈论让日常用户具有编程能力。

    POSIX操作系统本身就是一个API。 如果可以弄清楚如何在POSIX Shell中完成任务,则可以使该任务自动化。 那就是编程,并且这种日常POSIX编程方法的主要工具是shell脚本。

    就像它的名字一样,shell 脚本是您希望计算机执行的逐行配方,就像您手动完成一样。

    由于外壳程序脚本由日常常用命令组成,因此熟悉UNIX或Linux(通常称为POSIX )外壳程序将很有帮助。 使用shell的实践越多,编写新脚本就越容易。 这就像学习一门外语:内在的词汇量越多,形成复杂句子的难度就越大。

    打开终端窗口时,您正在打开外壳 那里有几个shell,本教程对bashtcshkshzsh以及其他可能的对象有效。 在某些部分中,我确实提供了一些特定于bash的示例,但是最终的脚本放弃了这些示例,因此您可以切换到bash上有关设置变量的课程,也可以进行一些简单的语法调整

    如果您不熟悉所有这些,只需使用bash即可 它是一个不错的外壳,具有许多友好的功能,并且在Linux,Cygwin,WSL,Mac和BSD上均是默认选项。

    你好,世界

    您可以从终端窗口生成自己的hello world脚本。 注意引号; 单人和双人有不同的效果。

    
    
    $ echo "#\!/bin/sh" > hello.sh
    $ echo "echo 'hello world' " >> hello.sh

    如您所见,编写shell脚本除了第一行外,是将命令回显或粘贴到文本文件中。

    要将脚本作为应用程序运行:

    
    
    $ chmod +x hello.sh
    $ ./hello.sh
    hello world

    或多或少,这就是全部!

    现在让我们解决一些有用的问题。

    分隔符

    如果有一件事混淆了计算机和人类的互动,那就是文件名中的空格。 您已经在互联网上看到了它:诸如http://example.com/omg%2ccutest%20cat%20photo%21%211.jpg之类的URL。 或者运行一个简单的命令时,空格可能使您绊倒了:

    
    
    $ cp llama pic.jpg ~/photos
    cp: cannot stat 'llama': No such file or directory
    cp: cannot stat 'pic.jpg': No such file or directory

    解决方案是用反斜杠或引号“转义”该空间:

    
    
    $ touch foo\ bar.txt
    $ ls "foo bar.txt"
    foo bar.txt

    这些是很重要的技巧,但是很不方便,所以为什么不编写一个脚本从文件名中删除那些烦人的空格呢?

    创建一个文件来保存脚本,以“ shebang”( #! )开头,以使您的系统知道该文件应在shell中运行:

    
    
    $ echo '#!/bin/sh' > despace

    好的代码始于文档。 定义目的可以使我们知道目标是什么。 这是一个很好的自述文件:

    
    
    despace is a shell script for removing spaces from file names.

    Usage:
    $ despace "foo bar.txt"

    现在,让我们弄清楚如何手动执行此操作,并在进行过程中构建脚本。

    假设您在否则为空的目录中有一个名为“ foo bar.txt”的文件,请尝试以下操作:

    
    
    $ ls
    hello.sh
    foo bar.txt

    计算机都是关于输入和输出的。 在这种情况下,输入是对ls特定目录的请求。 输出就是您所期望的:该目录中文件的名称。

    在UNIX中,可以通过“管道”将输出作为另一个命令的输入发送。 管道另一侧的任何东西都可以用作过滤器。 tr实用程序恰好被设计用来修改通过它的字符串。 对于此任务,请使用--delete选项删除引号中定义的字符。

    
    
    $ ls "foo bar.txt" | tr --delete ' '
    foobar.txt

    现在,您已经有了所需的输出。

    在BASH Shell中,您可以将输出存储为变量 将变量视为一个空盒,您可以在其中放置要存储的信息:

    
    
    $ NAME=foo

    当您需要返回信息时,可以通过引用以美元符号( $ )开头的变量名称来查找框。

    
    
    $ echo $NAME
    foo

    要获取您的depacing命令的输出并将其保留以备后用,请使用一个变量。 要将命令的结果放入变量中,请使用反引号:

    
    
    $ NAME=`ls "foo bar.txt" | tr -d ' '`
    $ echo $NAME
    foobar.txt

    这可以使您完成目标的一半,您可以通过一种方法从源文件名确定目标文件名。

    到目前为止,脚本看起来像这样:

    
    
    #!/bin/sh

    NAME=`ls "foo bar.txt" | tr -d ' '`
    echo $NAME

    脚本的第二部分必须执行重命名。 您现在可能已经有了该命令:

    
    
    $ mv "foo bar.txt" foobar.txt

    但是,请记住,在脚本中您正在使用变量来保存目标名称。 您知道如何引用变量:

    
    
    #!/bin/sh

    NAME=`ls "foo bar.txt" | tr -d ' '`
    echo $NAME
    mv "foo bar.txt" $NAME

    您可以通过将其标记为可执行文件并在测试目录中运行来试用您的第一份草案。 确保您有一个名为“ foo bar.txt”的测试文件(或脚本中使用的任何文件)。

    
    
    $ touch "foo bar.txt"
    $ chmod +x despace
    $ ./despace
    foobar.txt
    $ ls
    foobar.txt

    分隔符v2.0

    该脚本有效,但与您的文档描述不完全相同。 它目前非常具体,仅适用于名为foo \ bar.txt的文件,仅此而已。

    POSIX命令将自身称为$ 0,并将其后依次键入的任何内容称为$ 1$ 2$ 3 ,依此类推。 您的shell脚本算作POSIX命令,因此请尝试将foo \ bar.txt换成 $ 1

    
    
    #!/bin/sh

    NAME=`ls $1 | tr -d ' '`
    echo $NAME
    mv $1 $NAME

    创建一些名称中带有空格的新测试文件:

    
    
    $ touch "one two.txt"
    $ touch "cat dog.txt"

    然后测试您的新脚本:

    
    
    $ ./despace "one two.txt"
    ls: cannot access 'one': No such file or directory
    ls: cannot access 'two.txt': No such file or directory

    您似乎已发现错误!

    这样的错误实际上并不是错误。 一切都按设计工作,而不是您希望的工作方式。 您的脚本会将$ 1变量“扩展”为确切的含义:“一个two.txt”,随之而来的是您要消除的烦人空间。

    答案是将变量包装在引号中,就像将文件名包装在引号中一样:

    
    
    #!/bin/sh

    NAME=`ls "$1" | tr -d ' '`
    echo $NAME
    mv "$1" $NAME

    另一个测试或两个:

    
    
    $ ./despace "one two.txt"
    onetwo.txt
    $ ./despace c*g.txt
    catdog.txt

    此脚本的作用与任何其他POSIX命令相同。 您可以将其与其他命令结合使用,就像您希望能够使用任何POSIX实用程序一样。 您可以将其与命令结合使用:

    
    $ find ~/test0 -type f -exec /path/to/despace {} \;
    
    

    或者,您可以将其用作循环的一部分:

    $ for FILE in ~/test1/* ; do /path/to/despace $FILE ; done

    等等。

    分隔符v2.5

    despace脚本是功能性的,但是从技术上讲可以对其进行优化,并且可以使用一些可用性方面的改进。

    首先,实际上不需要该变量。 Shell可以一次性计算所需的信息。

    POSIX Shell具有一个操作顺序。 用数学上的方法,首先要解决方括号中的语句,在执行命令之前,shell会解析BASH中反引号( ` )或$()的语句。 因此,声明:

    
    
    $ mv foo\ bar.txt `ls foo\ bar.txt | tr -d ' '`

    变成:

    
    
    $ mv foo\ bar.txt foobar.txt

    然后执行实际的mv命令,只剩下foob​​ar.txt

    知道了这一点,您可以将Shell脚本压缩为:

    
    
    #!/bin/sh

    mv "$1" `ls "$1" | tr -d ' '`

    这看起来简直令人失望。 您可能会认为将其简化为单行代码就不必使用脚本了,但是shell脚本不必使用很多行就可以使用。 即使输入一个简单的命令就可以保存打字的脚本,仍然可以使您免于致命的打字错误,这在涉及移动文件时尤其重要。

    此外,您的脚本仍然可以使用改进。 额外的测试揭示了一些弱点。 例如, 带参数运行despace会产生无用的错误:

    
    
    $ ./despace
    ls: cannot access '': No such file or directory

    mv: missing destination file operand after ''
    Try 'mv --help' for more information.

    这些错误令人困惑,因为它们分别用于lsmv ,但是据用户所知,它们运行的​​不是lsmv ,而是despace

    如果您考虑一下,如果这个小脚本最初没有在命令中获取文件,则甚至不要尝试重命名该文件,因此请尝试使用对变量了解的知识以及测试函数。

    如果和测试

    if语句使您的小空间工具从脚本变成程序。 这是一个严肃的代码领域,但是不用担心,它也很容易理解和使用。

    if语句是一种切换。 如果某件事是正确的,那么您将做一件事;如果它是错误的,那么您将做另一件事。 这种if-then指令正是二进制决策计算机最擅长的一种。 您所要做的就是为计算机定义需要正确还是错误以及需要做什么。

    测试True或False的最简单方法是测试实用程序。 您不直接调用它,而是使用它的语法。 在终端上尝试一下:

    
    
    $ if [ 1 == 1 ]; then echo "yes, true, affirmative"; fi
    yes, true, affirmative
    $ if [ 1 == 123 ]; then echo "yes, true, affirmative"; fi
    $

    这就是测试的工作方式。 您可以选择各种速记方式,并且-z选项是您使用的一种-z选项,它检测字符串的长度是否为零(0)。 这个想法在您的despace脚本中转换为:

    
    
    #!/bin/sh

    if [ -z "$1" ]; then
       echo "Provide a \"file name\", using quotes to nullify the space."
       exit 1
    fi

    mv "$1" `ls "$1" | tr -d ' '`

    if语句分为几行以提高可读性,但概念仍然存在:如果$ 1变量内的数据为空(存在零个字符),则输出错误语句。

    试试吧:

    
    
    $ ./despace
    Provide a "file name", using quotes to nullify the space.
    $

    成功!

    好吧,实际上这是一个失败,但这是一个相当大的失败,更重要的是,一个有用的失败。

    注意语句退出1 这是POSIX应用程序向系统发送已遇到错误的警报的一种方式。 此功能对您自己以及对于可能希望在脚本中使用分隔符的其他人很重要,这些脚本必须成功取决于分隔符才能正确执行其他所有操作。

    最终的改进是添加了一些保护用户免受意外覆盖的文件。 理想情况下,您应该将此选项传递给脚本,以便它是可选的,但是为了简单起见,您将对其进行硬编码。 -i选项告诉mv在覆盖已经存在的文件之前请求许可:

    
    
    #!/bin/sh

    if [ -z "$1" ]; then
       echo "Provide a \"file name\", using quotes to nullify the space."
       exit 1
    fi

    mv -i "$1" `ls "$1" | tr -d ' '`

    现在,您的Shell脚本是有用,有用和友好的-并且您是一名程序员,所以请立即停止。 学习新命令,在终端中使用它们,记下您的操作,然后编写脚本。 最终,您将失去工作,而您的余生将在机器人小仆运行Shell脚本时度过轻松时光。

    骇客骇客!

    翻译自: https://opensource.com/article/17/1/getting-started-shell-scripting

    shell脚本入门

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,003
精华内容 2,001
关键字:

shell脚本入门