shell 编程

变量

变量定义:name=Tom
变量使用:echo $name
自定义环境变量:export name
常见环境变量:$HOME $PATH
查看环境变量:env
声明只读变量:readonly name
特殊变量:

$0  shell执行程序名
$n  位置参数,n = 1...9
$*  所有位置参数组成的字符串
$#  位置参数的个数
$$  程序执行后的pid,常用来生产临时文件
$!  最后一个后台程序执行后的pid
$?  命令执行后的返回值,0表示成功,其他失败

位置参数只能有9个,可以用shift命令将位置参数后移一格
set命令可以改变位置参数,执行set "p1 p2 p3"后,0=p11=p2 $2=p3

数值运算

整数运算

# 4种方式实现自增
i=0
((i++))
let i++
expr $i + 1
echo $i 1 | awk '{printf($1+$2);}'

浮点运算

(()),let和expr都无法进行浮点运算,bc和awk可以

echo "10 3" | awk '{printf("%0.3f", $1/$2)}'

随机数

环境变量RANDOM产生0到32767的随机数,而awk的rand函数可以产生0到1之间的随机数

echo $RANDOM
echo "" | awk '{srand(); printf("%f", rand());}'

序列数

可以用循环实现,建议用seq工具

seq 5           # 1 2 3 4 5
seq 1 2 5       # 1 3 5
seq -s: 1 2 5   # 1:3:5
seq -w 1 3 10   # 01 04 07 10
{1..5}          # 1 2 3 4 5

函数

可以有return语句,但是只能返回整数

# 定义hello函数
hello () {
    echo "hello $1"
}
hello hatlonely     # 调用hello,hatlonely为参数

控制语句

#!/bin/bash

# 遍历目录
for file in `ls`; do
    if [ -f $file ]; then
        echo "$file is a file"
    else
        echo "$file is not a file"
    fi
done

# for循环
for ((i = 0; i < 10; i++)) do
    echo $i
done

# while循环
i=0
while [ $i -lt 10 ]; do
    echo $i
    ((i++))
done

# 处理命令行参数
usage()
{
    echo "usage: $0 [-a] [-e <admin>] [-f <serverfile>] [-h] [-d <domain>] [-s <whois_server>] [-q] [-x <warndays>]"
}

while getopts ae:f:hd:s:qx: option; do
    case "${option}" in
        a) ALARM="TRUE";;
        e) ADMIN=${OPTARG};;
        d) DOMAIN=${OPTARG};;
        f) SERVERFILE=$OPTARG;;
        s) WHOIS_SERVER=$OPTARG;;
        q) QUIET="TRUE";;
        x) WARNDAYS=$OPTARG;;
        \?) usage; exit 1;;
    esac
done

echo "ALARM=$ALARM"
echo "ADMIN=$ADMIN"

# 读取输入
while read line; do
    echo $line
done

字符串

判断字符串的值

${var}  变量var的值, 与$var相同

${var-DEFAULT}  如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:-DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *

${var=DEFAULT}  如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:=DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *

${var+OTHER}    如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
${var:+OTHER}   如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串

${var?ERR_MSG}  如果var没被声明, 那么就打印$ERR_MSG *
${var:?ERR_MSG} 如果var没被设置, 那么就打印$ERR_MSG *

${!varprefix*}  匹配之前所有以varprefix开头进行声明的变量
${!varprefix@}  匹配之前所有以varprefix开头进行声明的变量

字符串操作

${#string}                  $string的长度

${string:position}          在$string中, 从位置$position开始提取子串
${string:position:length}   在$string中, 从位置$position开始提取长度为$length的子串

${string#substring}     从变量$string的开头, 删除最短匹配$substring的子串
${string##substring}    从变量$string的开头, 删除最长匹配$substring的子串
${string%substring}     从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring}    从变量$string的结尾, 删除最长匹配$substring的子串

${string/substring/replacement}     使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement}    使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement}    如果$string的前缀匹配$substring,
                                    那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement}    如果$string的后缀匹配$substring,
                                    那么就用$replacement来代替匹配到的$substring

条件测试

使用[]测试时,前后都要空格

文件测试

-a file exists.
-b file exists and is a block special file.
-c file exists and is a character special file.
-d file exists and is a directory.
-e file exists (just the same as -a).
-f file exists and is a regular file.
-g file exists and has its setgid(2) bit set.
-G file exists and has the same group ID as this process.
-k file exists and has its sticky bit set.
-L file exists and is a symbolic link.
-n string length is not zero.
-o Named option is set on.
-O file exists and is owned by the user ID of this process.
-p file exists and is a first in, first out (FIFO) special file or named pipe.
-r file exists and is readable by the current process.
-s file exists and has a size greater than zero.
-S file exists and is a socket.
-t file descriptor number fildes is open and associated with a terminal device.
-u file exists and has its setuid(2) bit set.
-w file exists and is writable by the current process.
-x file exists and is executable by the current process.
-z string length is zero.

整数比较

-eq     ==
-ne     !=
-ge     >=
-gt     >
-le     <=
-lt     <

字符串测试

string      测试字符串不为空
-n string   测试字符串不为空
-z string   测试字符串为空
str1=str2   字符串相同
str1!=str2  字符串不同

逻辑运算

!expression     not
expr1 -a expr2  and
expr1 -o expr2  or

路径处理

$ temp=/home/hatlonely/hatlonely/librayrs.txt
$ echo `basename ${temp}`
$ echo `dirname ${temp}`
$ echo ${temp##*/}
$ echo ${temp%/*}

颜色

格式: echo "/033[字背景颜色;字体颜色m字符串/033[控制码"
如果单纯显示字体颜色可以固定控制码位0m
例如: echo "/033[字背景颜色;字体颜色m字符串/033[0m"

字背景颜色范围:40 - 49

40:黑
41:深红
42:绿
43:黄色
44:蓝色
45:紫色
46:深绿
47:白色

字颜色:30 - 39

30:黑
31:红
32:绿
33:黄
34:蓝色
35:紫色
36:深绿
37:白色

ANSI控制码

\33[0m 关闭所有属性
\33[01m 设置高亮度
\33[04m 下划线
\33[05m 闪烁
\33[07m 反显
\33[08m 消隐
\33[30m -- \33[37m 设置前景色
\33[40m -- \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标

例子

echo -e "\033[31m \033[05m 请确认您的操作,输入 [Y/N] \033[0m"

转载请注明出处
本文链接:http://www.hatlonely.com/2018/11/04/shell-%E7%BC%96%E7%A8%8B/

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容

  • Bash内置基本变量 PWD : 显示当前的工作目录 OLDPWD : 显示上一次的工作目录 ~:用户家目录 - ...
    魏镇坪阅读 1,494评论 0 6
  • 流程控制 if 单条件 双分支 多分支 case case支持glob风格的通配符: *: 任意长度任意字符?: ...
    毛利卷卷发阅读 704评论 0 1
  • Shell脚本编程基础 shell概念: shell是一个用C语言编写的程序,他是用户使用Linux的桥梁,它是一...
    JM68阅读 481评论 1 7
  • 数字比较 ``` -eq 等于,如:if [ "$a" -eq "$b" ] -ne 不等于,如:if...
    飞翔你我阅读 266评论 0 0
  • 1. shell脚本: 包含一些命令或声明,并符合一定格式的文本文件  格式要求:首行shebang(#!)机制...
    尛尛大尹阅读 1,845评论 0 1