shell编程基础之二

算数运算

bash中的算术运算:help let

  • +, -, *, /, %取模(取余), **(乘方),乘法符号有些场景中需要转义
  • 实现算术运算:
    • (1) let var=算术表达式
    • (2) var=$[算术表达式]
    • (3) var=$((算术表达式))
    • (4) var=$(expr arg1 arg2 arg3 ...)
    • (5) declare –i var = 数值
    • (6) echo ‘算术表达式’ | bc

bash有内建的随机数生成器变量:$RANDOM(0-32767)

  • 示例:生成 0 - 49 之间随机数

    • echo $[$RANDOM%50]

赋值

增强型赋值:

  • +=, -=, *=, /=, %=

let varOPERvalue

  • 例如:let count+=3

    • 自加3后自赋值

自增,自减:

  • let var+=1
  • let var++
  • let var-=1
  • let var--

逻辑运算

true, false

  • 1, 0

与:&

  • 1 与 1 = 1
  • 1 与 0 = 0
  • 0 与 1 = 0
  • 0 与 0 = 0

或:|

  • 1 或 1 = 1
  • 1 或 0 = 1
  • 0 或 1 = 1
  • 0 或 0 = 0

非:!

  • ! 1 = 0 ! true
  • ! 0 = 1 ! false

异或:^

  • 异或的两个值,相同为假,不同为真

短路运算

  • 短路与

    • 第一个为0,结果必定为0
    • 第一个为1,第二个必须要参与运算
  • 短路或
    • 第一个为1,结果必定为1
    • 第一个为0,第二个必须要参与运算

条件测试

判断某需求是否满足,需要由测试机制来实现专用的测试表达式需要由测试命令辅助完成测试过程

评估布尔声明,以便用在条件性执行中

  • 若真,则返回0
  • 若假,则返回1

测试命令:

  • test EXPRESSION
  • [ EXPRESSION ]
  • [[ EXPRESSION ]]
  • 注意:EXPRESSION前后必须有空白字符

bash的数值测试

-v VAR

  • 变量VAR是否设置
  • 示例:判断 NAME 变量是否定义
    • [ -v NAME ]

数值测试:

  • -gt 是否大于
  • -ge 是否大于等于
  • -eq 是否等于
  • -ne 是否不等于
  • -lt 是否小于
  • -le 是否小于等于

bash的字符串测试

字符串测试:

  • -z "STRING" 字符串是否为空,空为真,不空为假
  • -n "STRING"字符串是否不空,不空为真,空为假
  • = 是否等于
  • > ascii码是否大于ascii码 < 是否小于
  • != 是否不等于
  • == 左侧字符串是否和右侧的PATTERN相同
    • 注意:此表达式用于[[ ]]中,PATTERN为通配符
  • =~ 左侧字符串是否能够被右侧的PATTERN所匹配
    • 注意: 此表达式用于[[ ]]中;扩展的正则表达式

bash的文件测试

存在性测试

  • -a FILE:同 -e
  • -e FILE: 文件存在性测试,存在为真,否则为假

存在性及类别测试

  • -b FILE:是否存在且为块设备文件
  • -c FILE:是否存在且为字符设备文件
  • -d FILE:是否存在且为目录文件
  • -f FILE:是否存在且为普通文件
  • -h FILE 或 -L FILE:存在且为符号链接文件
  • -p FILE:是否存在且为命名管道文件
  • -S FILE:是否存在且为套接字文件

bash的权限测试

文件权限测试:

  • -r FILE:是否存在且可读
  • -w FILE: 是否存在且可写
  • -x FILE: 是否存在且可执行

文件特殊权限测试:

  • -u FILE:是否存在且拥有suid权限
  • -g FILE:是否存在且拥有sgid权限
  • -k FILE:是否存在且拥有sticky权限

bash的文件属性测试

文件大小测试:

  • -s FILE: 是否存在且非空

文件是否打开:

  • -t fd: fd 文件描述符是否在某终端已经打开
  • -N FILE:文件自从上一次被读取之后是否被修改过
  • -O FILE:当前有效用户是否为文件属主
  • -G FILE:当前有效用户是否为文件属组

双目测试:

  • FILE1 -ef FILE2: FILE1是否是FILE2的硬链接
  • FILE1 -nt FILE2: FILE1是否新于FILE2(mtime)
  • FILE1 -ot FILE2: FILE1是否旧于FILE2

bash的组合测试条件

第一种方式:

  • [ EXPRESSION1 -a EXPRESSION2 ] 并且
  • [ EXPRESSION1 -o EXPRESSION2 ] 或者
  • [ ! EXPRESSION ] 取反
  • -a 和 -o 需要使用测试命令进行,[[ ]] 不支持

第二种方式:

  • COMMAND1 && COMMAND2 并且,短路与,代表条件性的AND THEN
  • COMMAND1 || COMMAND2 或者,短路或,代表条件性的OR ELSE
  • ! COMMAND 非
  • 示例:
    • [ -f “$FILE” ] && [[ “$FILE”=~ .*.sh$ ]]

条件性的执行操作符

示例:

#grep -q no_such_user /etc/passwd || echo 'No such user'

  • No such user

#ping -c1 -W1 172.16.0.1 &> /dev/null \

> && echo '172.16.0.1 is up' \

> || (echo '172.16.0.1 is unreachable'; exit 1)

  • 172.16.0.1 is up

示例:

test "$A" = "$B" && echo "Strings are equal"

test "$A"-eq "$B" && echo "Integers are equal"

[ "$A" = "$B" ] && echo "Strings are equal"

[ "$A" -eq "$B" ] && echo "Integers are equal"

[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab

[ -z "$HOSTNAME" -o $HOSTNAME = "localhost.localdomain" ] \

>&& hostname www.magedu.com

用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量

-p 指定要显示的提示

-s 静默输入,一般用于密码

-n N 指定输入的字符长度N -d ‘字符’ 输入结束符

-t N TIMEOUT为N秒

read 从标准输入中读取值,给每个单词分配一个变量

所有剩余单词都被分配给最后一个变量

read -p “Enter a filename: “ FILE

条件选择if语句

选择执行:

  • 注意:if 语句可嵌套
#单分支
if 判断条件;then
条件为真的分支代码
fi #双分支
if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi #多分支
if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
else
以上条件都为假的分支代码
fi #逐条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

条件判断case语句

case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
*)
默认分支
;;
esac

case支持glob风格的通配符:

  • *: 任意长度任意字符
  • ?: 任意单个字符
  • []:指定范围内的任意单个字符
  • a|b:

bash如何展开命令行

  • 把命令行分成单个命令词
  • 展开别名
  • 展开大括号的声明({}
  • 展开波浪符声明(~)
  • 命令替换$() 和 ``)
  • 再次把命令行分成命令词
  • 展开文件通配(*、?、[abc]等等)
  • 准备I/0重导向(<、>)
  • 运行命令

防止扩展

反斜线(\)会使随后的字符按原意解释

  • echo Your cost: $5.00

    • Your cost: $5.00

加引号来防止扩展

  • 单引号(’’)防止所有扩展
  • 双引号(”“)也可防止扩展,但是以下情况例外:
    • $(美元符号) 变量扩展
    • ` ` (反引号) 命令替换
    • \(反斜线) 禁止单个字符扩展
    • !(叹号) 历史命令替换

bash的配置文件

按生效范围划分,存在两类:

  • 全局配置:

    • /etc/profile
    • /etc/profile.d/*.sh
    • /etc/bashrc
  • 个人配置:
    • ~/.bash_profile
    • ~/.bashrc

shell登陆的两种方式

交互式登录:

  • (1)直接通过终端输入账号密码登录
  • (2)使用“su - UserName” 切换的用户
  • 执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc

非交互式登录:

  • (1)su UserName
  • (2)图形界面下打开的终端
  • (3)执行脚本
  • (4)任何其它的bash实例
  • 执行顺序: /etc/profile.d/*.sh --> /etc/bashrc -->~/.bashrc

profile类和bashrc类

按功能划分,存在两类:

  • profile类和bashrc类

profile类:为交互式登录的shell提供配置

  • 全局:/etc/profile, /etc/profile.d/*.sh
  • 个人:~/.bash_profile
  • 功用:
    • (1) 用于定义环境变量
    • (2) 运行命令或脚本

bashrc类:为非交互式和交互式登录的shell提供配置

  • 全局:/etc/bashrc
  • 个人:~/.bashrc
  • 功用:
    • (1) 定义命令别名和函数
    • (2) 定义本地变量

编辑配置文件生效

修改profile和bashrc文件后需生效

  • 两种方法:

    1. 重新启动shell进程
    2. . 或source Conf_File_Name
    • 例: . ~/.bashrc

bash退出任务

保存在~/.bash_logout文件中(用户)

在退出登录shell时运行

用于

  • 创建自动备份
  • 清除临时文件

set命令

$- 变量

  • h:hashall,打开这个选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭
  • i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的shell。所谓的交互式shell,在脚本中,i选项是关闭的
  • m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等
  • B:braceexpand,大括号扩展
  • H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

脚本安全

  • -u 在扩展一个没有设置的变量时,显示错误信息等同set -o nounset
  • -e 如果一个命令返回一个非0退出状态值(失败)就退出等同set -o errexit

7-1 shell编程基础之二的更多相关文章

  1. Linux学习之二十一-shell编程基础

    Shell编程基础 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言.Shell 是指一种应用程序,这个应用程序提供了一个 ...

  2. 【转】Shell编程基础篇-下

    [转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...

  3. 【转】Shell编程基础篇-上

    [转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...

  4. shell编程基础(转载)

    Shell编程基础 原作者 Leal:请参阅页面底部的编者列表. 授权许可: 创作共享署名协议 GNU 自由文档许可证 注意:本文仍然在持续的修订之中,且错漏之处可能较多.如果能够阅读英语的话,可以考 ...

  5. 【Shell 编程基础第二部分】Shell里的流程控制、Shell里的函数及脚本调试方法!

    http://blog.csdn.net/xiaominghimi/article/details/7603003 本站文章均为李华明Himi原创,转载务必在明显处注明:转载自[黑米GameDev街区 ...

  6. 6-2 shell编程基础

    shell编程基础 编程基础 Linus:Talk is cheap, show me the code 程序和编程风格 程序: 程序:算法+数据结构 数据:是程序的核心 算法:处理数据的方式 数据结 ...

  7. shell编程基础(二): shell脚本语法之分支语句和循环语句

    一.分支语句 1.条件测试:test [ 命令test或[可以测试一个条件是否成立,如果测试结果为真,则该命令的Exit Status为0,如果测试结果为假,则命令的Exit Status为1(注意与 ...

  8. 基于Linux系统的Shell编程-基础篇

    1. Shell基础介绍 1.1 Shell编程的意义 为什么使用shell编程 节约时间 1.2 显示脚本执行过程 前面有+表示执行过的命令的 前面没有东西,表示输出到屏幕上的内容. [root@C ...

  9. Shell 编程基础之变量和环境变量

    一.变量赋值和引用 Shell 编程中,使用变量无需事先声明,同时变量的命名不惜遵循如下规则: 首个字符必须为字母(a-z,A-Z)或者_ 变量名中间不能有空格,可以使用_连接 不能使用其他表达符号 ...

随机推荐

  1. openssl数据加密

    一.openssl简介 openssl是最著名的开源SSL,其用 C 实现,被广泛应用在基于TCP/Socket的网络程序中. OpenSSL:开源项目 三个组件:openssl: 多用途的命令行工具 ...

  2. 原生 JS实现一个简单分页插件

    最近做的一个 PC端的需求,这个需求中有一个小点,页面底部有一块列表区域,这个列表的数据量比较大,需要进行分页控制,切换页码的时候,发送一个 ajax请求,在页面无刷新的情况下,实现列表数据的刷新,所 ...

  3. 返回vector指针

    #include<iostream> #include <vector> using namespace std; vector<int> *MyFind() { ...

  4. Springboot项目报错【java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to java.base/java.net.URLClassLoader】

    1.发生问题: 升级了JDK9,发现原先的springboot项目起不来了,以为是maven中jdk配置有问题. 于是在pom中添加了 <plugin> <groupId>or ...

  5. 题解 【ZJOI2009】 假期的宿舍

    题面 解析 这其实就是个二分图匹配的水题(虽然我还是爆零了) 这题的意思就是说,有x个人,y张床(x,y不确定), 每个人只能睡在指定的几张床上, 问能否使每人都有床睡. 所以,直接二分图匹配,看最大 ...

  6. The 2018 ACM-ICPC Asia Qingdao Regional Contest, Online(2018 青岛网络预选赛)

    A题 A Live Love 原题链接:https://pintia.cn/problem-sets/1036903825309761536/problems/1041155943483625472 ...

  7. Codevs 1200 同余方程 2012年NOIP全国联赛提高组

    1200 同余方程 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 求关于 x 同余方程 a ...

  8. docker打包flask简单程序

    简单代码: from flask import Flask app=Flask(__name__) @app.route('/') def hello(): return 'hello world' ...

  9. 深度学习笔记(十一)网络 Inception, Xception, MobileNet, ShuffeNet, ResNeXt, SqueezeNet, EfficientNet, MixConv

    1. Abstract 本文旨在简单介绍下各种轻量级网络,纳尼?!好吧,不限于轻量级 2. Introduction 2.1 Inception 在最初的版本 Inception/GoogleNet, ...

  10. Fantasy of a Summation (LightOJ - 1213)(快速幂+简单思维)

    题解:根据题目给的程序,就是计算给的这个序列,进行k次到n的循环,每个数需要加的次数是k*n^(k-1),所以快速幂取模,算计一下就可以了. #include <bits/stdc++.h> ...