Shell 是一门脚本语言(又称解释型语言),Shell 其实就是一个纯文本文件,通常以【#!/bin/bash】开始。脚本自上而下,从左至右分析并执行,其中【#】后面的为注释。脚本有以下几种运行方式:(1) 【bash shell.sh】 (2)【sh shell.sh】(3)【./shell.sh】当前目录下执行,用户必须有可执行权限 (4)【. ./shell.sh】或【source shell.sh】无执行权限也能执行,【source】一般用于读取配置文件使其立即生效。

第一个 Shell 脚本:

#!/bin/bash
# show Hello World
# 2016-06-06 cyhe
echo "Hello World"
exit 0

1. 变量

  在Shell中,变量是弱类型的(存放各类数据,比如文件名,路径名等),而且无论值是否加引号,默认都是字符串。变量名只能以字母或下划线开头,并且区分大小写,长度无限制。变量分为局部变量和环境变量。当登陆 Linux取得一个交互Shell后,我们可以在这个 Shell(父Shell) 中管理系统、创建 子Shell、定义变量。子Shell 能够继承 父Shell 的环境变量,不会继承自定义变量,在Shell 可以使用【export】将自定义变量上升为环境变量,供子程序使用。

(1)局部变量

  局部变量的作用域在 Shell 内部,其他shell不能访问,随脚本结束而消亡。可以使用 local 可以显式声明局部变量,常用于函数内部。

(2)环境变量

  环境变量又称为全局变量,Shell 中变量默认就是全局的。为了有一个较好的执行环境,在编写 Shell 之前可以先设置好一些重要的环境变量,比如PATH,LANG,可以方便的下达一些命令,而不必使用绝对路径。比如,在使用 crontab 定期执行脚本自动备份Oracle数据库(或其他)时,Oracle相关的环境变量(ORACLE_HOME, NLS_LANG…)一般在oracle用户下,此时脚本不使用 export 声明Oracle相关变量,将不能执行。

(3)变量的赋值与取值

#!/bin/bash
# 变量名=值(var=value 等号两边没有空格),使用 【$var/${var}】 符号取值
# 如果有空格就必须使用引号
name=cyhe
name="cy he"
echo $name
echo ${name}

Shell 中预定义的特殊变量和特殊字符:

变量 说明
$0 脚本名称
$n 脚本或函数参数,$1 第一个参数,$2 第二个以此类推
$? 脚本或命令返回值
$*,$@ 显示所有参数
通配符 *:任意长度字符串,不包括点号和斜线
?:匹配单一字符
[]:匹配其中的任一个
‘’ 单引号:强引用,作为普通字符处理
“” 双引号:解析字符串里的【$,\,`】特殊用途
# 注释
$(命令) 可以把命令的输出赋值给变量,支持嵌套
 ; 分号,执行多个命令,# date; ls -l

2. 算术运算

Shell 只支持整数计算

命令 用法
let #!/bin/bash
a=1
b=2
let c=a+b
自增 let a++
自减 let a--
[ ] c=$[a+b] 或 c=$[ $a+2 ]
取模 $[5%2]  幂运算 $[2**3]
(()) c=$(( a+b )),c=$(( (5+2)*3 )),(( a++ )) 常用
bc 高精度计算语言,支持比较运算和逻辑运算

3. 数组

  在 shell 中,数组中元素类型可以不同,数组的长度也不限制,可以随时随地增加数组元素,但是只支持一维数组,使用整数作索引,也可以使用字符串作索引。

#!/bin/bash
# 数组相关操作
# author: cyhe 2016-11-08
nums=(1 2 3 4 5)  # 定义数组
weeks=("sun" "mon" "thu")
weeks[3]="wed"    # 随时随地增加数据
weeks[4]="thur"
echo ${#weeks[@]} # 数组长度 or ${#weeks[*]}
echo ${#weeks[4]} # 数组元素的长度
echo ${weeks[@]}  # 数组所有元素
echo ${weeks[0]}  # 取第 0 个元素
unset weeks[1]    # 取消第 1 个元素

4. 判断

  在编程时,会经常根据字符串是否为空,文件是否存在诸如此类的问题,来控制程序的流程,在 Shell 中可以使用【test expression】命令直接测试。此外可以利用判断符号【[ ](中括号)】进行数据的判断,在使用中括号有几个关键的地方:括号内的每个元素都要用空格分隔;括号内的变量,最好都用双引号括起来;括号内容的常量,最好都用单或双引号括起来。常与 if 语句搭配使用。

常用测试判断条件

标志 说明
1. 文件类型 [ –e filename ]
-e 文件是否存在
-f 文件是否存在且为文件(file)
-d 文件是否存在且为目录(directory)
2. 文件权限 [ –r filename ]
-r/w/x 文件是否存在且有相应的权限
-s 文件是否存在且为非空白文件
3. 比较文件 [ file1 -nt file2 ]
-nt/-ot 判断file1是否比file2新(new than)/旧(older than)
-ef 是否为同一文件
4. 比较整数 [ n1 -eq n2 ]
-eq/-ne 相等(equal)/不相等(not equal)
-gt/-lt 大于(greater than)/小于(less than)
-ge/-le 大于等于/小于等于
5. 判断字符串  
[ –z string ] 是否为空
[ –n string ] 是否不空
[ str1 == str2 ] 是否相等
[ str1 != str2 ] 是否不等
6. 逻辑运算  
-a and,[ –r file –a –x file ],同时有rx权限
-o or,[ –r file –o –x file ],有r或x权限
! 非,[ ! –x file ],不具有x权限
&& 与,[ –r file ] && [ –x file ]
|| 或,[ –r file ] || [ –x file ]
非,! [ –e file ]

【if/else判断】

#!/bin/bash
str="Hello World"
file=/opt/shell.log
# 单层条件判断 这里分号的作用是连续执行命令,不用换行了
if [ -z "$str" ]; then # 若字符串为空
    # TODO
fi
# 一个分支
if [ -f "$file" ]; then # 文件是否存在
    # TODO
else
    # TODO
fi

# 多个分支
if [ -z "$1" ]; then # 若第一个参数为空
    # TODO
elif [ "$1" == "" ]; then # 是否为空串
    # TODO
else
    # TODO
fi

【case … esac判断】

#!/bin/bash
case $1 in
    "start")        # 第一个变量内容,关键字右小括号
       echo "start"
       ;;           # 该程序段结束
    "stop")
       echo "start"
       ;;
    "restart")
       echo "stop"
       echo "start"
       ;;
    *)              # 默认匹配
       echo "Usage: $0 {start|stop|restart}"
       exit 1
       ;;
esac                # 结束

5. 循环

【for 循环】

#!/bin/bash
# 1. 用来遍历
nums=(1 2 3 4 5);sum=0
for n in ${nums[@]} # 遍历数组求和
do
    sum=$(($sum + $n))
done
# 遍历 1-5 的数字
for n in {1..5} # 或1 2 3 4 5 或$(seq 1 5)
do
    echo $n
done
# 2. 带条件的for循环,求1-100的和
sum=0
for (( i=0; i<=100; i++ ))
do
    sum=$(( $sum+$i )) # 或 let sum=sum+i
done
# 死循环
for ((;1;))

【while 循环】

#!/bin/bash
while [ condition ]
do
 # TODO
done
# while一个经典用法,按行读取文件
cat foo.txt | while read line # 运行时产生 3 个shell:cat,管道,while
do
    echo $line
done
# 死循环
while true
while 1

6. 函数

  函数就是自定义的一系列执行命令,一般设置返回值(0正确,非0错误),最主要还是用来代码复用。

#!/bin/bash
# 1. 函数定义与返回值
function fun_name(){ # function 关键字可省略
    # TODO
    echo $@  # 打印所有参数 无输出 0
    return 0
}
fun_name # 函数调用,只调用函数名即可
echo $?  # 取函数返回值,可赋值给变量
# 2. 参数
# fun_name arg1 arg2 ...
fun_name a b c
# 3. 变量
# shell中变量默认是全局的,可使用 local 定义局部变量
n=5
fun(){
    local n=1
    let n++
}
fun # 调用函数不影响 n 的值
echo $n
# $0 代表函数名 $1 第一个参数 $2 第二个 一次类推
# 这里的参数与脚本本身的参数 毫无关系

7. 调试脚本debug

 sh –n shell.sh  检查语法问题,不执行脚本

 sh –v shell.sh   执行前先输出脚本内容到屏幕

 sh –x shell.sh   将脚本执行过程输出到屏幕

Shell 编程的更多相关文章

  1. Linux学习笔记(17) Shell编程之基础

    1. 正则表达式 (1) 正则表达式用来在文件中匹配符合条件的字符串,正则是包含匹配.grep.awk.sed等命令可以支持正则表达式:通配符用来匹配符合条件的文件名,通配符是完全匹配.ls.find ...

  2. shell编程:定义简单标准命令集

    shell是用户操作接口的意思,操作系统运行起来后都会给用户提供一个操作界面,这个界面就叫shell,用户可以通过shell来调用操作系统内部的复杂实现,而shell编程就是在shell层次上进行编程 ...

  3. Linux Shell编程入门

    从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁.用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操 ...

  4. Shell编程菜鸟基础入门笔记

    Shell编程基础入门     1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...

  5. Linux_10------Linux之shell编程------变量

    .-9 vim num.sh #! /bin/bash num1=$1 num2=$2 sum=$(($num1+$num2)) #变量sum是num1和num2的综合 echo $sum 执行 ./ ...

  6. 需要交互的shell编程——EOF(转载)

    在shell编程中,”EOF“通常与”<<“结合使用,“<<EOF“表示后续的输入作为子命令或子shell的输入,直到遇到”EOF“, 再次返回到主调shell,可将其理解为分 ...

  7. ****CodeIgniter使用cli模式运行,把php作为shell编程

    shell简介 在计算机科学中,Shell俗称壳(用来区别于核).而我们常说的shell简单理解就是一个命令行界面,它使得用户能与操作系统的内核进行交互操作. 常见的shell环境有:MS-DOS.B ...

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

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

  9. Linux Shell编程基础

    在学习Linux BASH Shell编程的过程中,发现由于不经常用,所以很多东西很容易忘记,所以写篇文章来记录一下 ls   显示当前路径下的文件,常用的有 -l 显示长格式  -a 显示所有包括隐 ...

  10. centos 下建用户 shell编程

    useradd 用户名 passwd 用户名 cat /etc/passwd  查看用户信息 删除用户 userdel -r   加一个 -r 表示把用户及用户的主目录都删除 su  切换用户 sud ...

随机推荐

  1. 转:Android随笔之——使用Root权限实现后台模拟全局按键、触屏事件方法(类似按键精灵)

    本文转载自CSDN的jzj1993,原文连接:http://blog.csdn.net/jzj1993/article/details/39158865 有时我们需要使用安卓实现在后台模拟系统按键,比 ...

  2. Kubernetes集群搭建过程中遇到的问题

    1. 创建Nginx Pod过程中报如下错误: #kubectlcreate -f nginx-pod.yaml Error from server: error when creating &quo ...

  3. Python的安装和详细配置

    Python是一种面向对象.解释型计算机程序设计语言.被认为是比较好的胶水语言.至于其他的,你可以去百度一下.本文仅介绍python的安装和配置,供刚入门的朋友快速搭建自己的学习和开发环境.本人欢迎大 ...

  4. Node.js连接Mysql,并把连接集成进Express中间件中

    引言 在node.js连接mysql的过程,我们通常有两种连接方法,普通连接和连接池. 这两种方法较为常见,当我们使用express框架时还会选择使用中间express-myconnection,可以 ...

  5. SQL Server利用递归把所有【子部门员工】汇总到【一级根节点部门】

    前言 说起这个需求,有点反常规,左边是组织机构树,右边是组织机构对应的员工列表.点击左侧组织机构时传一个组织机构ID,然后查询该组织机构以及其所属的一级节点,如果有部门直属单击节点组织机构,则挂出来员 ...

  6. 使用FlexPaper实现office文件的预览(C#版)

    需求很简单,用户上传office文件(word.excel.ppt)后,可以预览上传的这些文件.搜索的相关的资料后.整理如下: Step1.用户上传office文件. Step2.把Office文件转 ...

  7. 大小写互换-"数字字符串"转换成数字

    今天穿着hacker浑浊马甲在百度编程课堂实训习题中发现了这个很简单的问题,就做了下. 为了考虑输入的是否是数字,结果写好后竟然超时了. 不过里面用到的将字符串装换成数字的方法,感觉是个收获,因此在此 ...

  8. 微信浏览器是移动端的IE6?微信升级内核后Html5和CSS3兼容性总结

    今年4月,自从微信浏览器X5 升级Blink内核之后,各前端社区一片高潮,仿佛看到了前端er,眼含热泪进而抱头痛头的说:终于可以不用兼容这"移动端的IE6 "了,可以早点回家了!! ...

  9. 关于本月第一天,本月最后一天的SQL代码

    DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)  --返回本月第一天 dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate() ...

  10. 移动端API架构 统一Proxy还是各自为政?

    今天首先回答上一篇的问题: 为什么APP通过运营商接入网络,连通率会那么差? 1. 域名缓存问题 运营商的localdns会缓存域名的解析结果,不向权威DNS递归查询解析 为什么要这么干呢? 1)运营 ...