Shell学习笔记

1.Shell脚本

1.1 格式

首行 #!/bin/bash 指定解释器

1.2 注释

'#'开头的行,'#!'是例外
此外,# 是特殊字符,可以出现在一些参数代换结构和在数值常量表达式中,具有特殊含义,而不会开启一个注释。‘#’也不会开启一个注释。

1.3 函数

function funname(){…}

或者

funname()
{
    statements;
}

只需要使用函数名就可以调用某个函数:funname

参数可以传递给函数,使用方法就好像函数是个新脚本一样:

funname arg1 arg2...; #传递参数

在函数中使用传入的参数:$1 第一个参数;$@ 所有参数。

其中:"$@"被扩展成"$1""$2""$3";

"$*"被扩展成"$1c$2c$3",即一个字符串。c为IFS的第一个字符。

有时我们需要知道命令或者函数的执行状态,用$?可以查看前一个命令的返回值,如果命令成功退出,那么退出状态为0,否则非0。

1.4 正文部分

流程控制+命令

1.5 执行:修改权限

转为可执行程序
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本

1.6 流程控制

条件语句
if :

if condition
then
    command1 
    command2
    ...
    commandN
fi
if `ps -ef | grep ssh`;  
then 
    echo hello; 
fi

if else-if else :

if condition1
then
    command1
elif condition2
    command2
else
    commandN
fi

循环语句
for :

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done
for var in item1 item2 ... itemN; do command1; command2… done;

while :

i=1;total=0;
while [ $i -le 10 ]
do
    let total+=i
    let i++
    echo $total,$i
done
i=1; total=0;
while((i<=10))
do
    ((total+=i, i++))
    echo $total,$i
done

case语句: case语句可以用户处理自定义参数。

case $num in
1) echo "January";;                 #双分号结束
2) echo "Feburary";;
5) echo "may"                       #每个case可以有多条命令       
   echo "sdfd"
   echo "sdf";;                     #但最后一条命令一定是双分号结束
*) echo "not correct input";;       #*)是其他值、default的意思
esac

1.7 while read line

while read line; do something ; done

1.8 参数处理

a) "$*"将所有的参数解释成一个字符串,而"$@"是一个参数数组。
b) Shell内建函数getopts “:a:bc” opt

主要变量:
$OPTIND :   存储所处理的选项在参数列表中的位置
$OPTARG :   存储相应选项所带的参数

例子:

while getopts ":a:b:cef" opt
do
    case $opt in
        a)echo "the $OPTIND has arg:$OPTARG";;#$OPTIND=3
        b)echo "the b has arg:$OPTARG";;
        c | e | f)echo "the $opt has no arg";;
        \?)echo "the $opt is invalid param";;
    esac
done

c) shift n 将位置命令左移n个

1.9 条件判断

条件判断应该放进方括号里,且方括号两边都应该留有空格。 [ ]
a) 字符串判断
字符串比较时,最好用双中括号,因为有时候采用单中括号会产生错误,所以最好避开它们。[[ $str1 = $str2 ]]

=           当两个串有相同内容、长度时为真
!=        当串str1和str2不等时为真
-n          当串的长度大于0时为真(串非空)
-z          当串的长度为0时为真(空串)

b) 数值判断

-eq     两数相等为真 
-ne     两数不等为真 
-gt     int1大于int2为真 
-ge     int1大于等于int2为真 
-lt     int1小于int2为真 
-le     int1小于等于int2为真

c) 文件判断

-e file         若文件存在,则为真 
-d file         若文件存在且是一个目录,则为真
-b file         若文件存在且是一个块特殊文件,则为真
-c file         若文件存在且是一个字符特殊文件,则为真
-f file         若文件存在且是一个规则文件,则为真
-g file         若文件存在且设置了SGID位的值,则为真
-h file         若文件存在且为一个符合链接,则为真
-k file         若文件存在且设置了"sticky"位的值
-p file         若文件存在且为一已命名管道,则为真
-r file         若文件存在且可读,则为真
-s file         若文件存在且其大小大于零,则为真
-u file         若文件存在且设置了SUID位,则为真
-w file         若文件存在且可写,则为真
-x file         若文件存在且可执行,则为真
-o file         若文件存在且被有效用户ID所拥有,则为真

d) 逻辑判断

!      非
-a     与        &&
-o     或        ||

if [ $v –ne 0 –a $v –lt 2 ] 等价 if [ $v –ne 0 ] && [ $v –lt 2 ]
if [ $v –ne 0 –o $v –lt 2 ] 等价 if [ $v –ne 0 ] || [ $v –lt 2 ]
条件判断部分可能会变得很长,一个优化的小技巧是利用&&和||运算符。

if condition
then
    command1
else
    command2
fi
[ condition ] && command1 || command2

这样就用一行代替了上面的5行而实现的功能完全相同。
如果命令有多个,可以用{}括起来,当做一个命令块。
这样可以使判断语句变得非常简洁。

1.10 &&、||

cmd1 && cmd2
表示,当cmd1执行成功后,就执行cmd2,否则不执行。
cmd1 || cmd2
表示,当cmd1执行失败后,就执行cmd2,否则不执行。

2.变量

2.1 系统变量

$n 该变量与脚本被激活时所带的参数相对应。n是正整数,与参数位置相对应($1,$2...)
$? 前一个命令执行后的退出状
$# 提供脚本的参数号
$* 所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2
$0 正在被执行命令的名字。对于shell脚本而言,这是被激活命令的路径
$@ 所有这些参数都分别被双引号引住。若一个脚本接收到两个参数,$@等价于$1$2
$$ 当前shell的进程号。对于shell脚本,这是其正在执行时的进程ID
$! 前一个后台命令的进程号

2.2 普通变量

  1. 赋值:var=value

获取字符串的长度。len=${#var}

  1. 数值运算:let
    let命令后面的变量不用带$,如:
    nu=10;
    let nu+=10; #nu=20
    但这个命令不能进行浮点数的运算。
  2. 浮点数运算:bc
    echo "4 * 0.6" | bc
    bc是一个强大的计算器,还可以进项如下操作:
    设定小数精度,scale=2,eg:echo "scale=2;3 / 8" | bc
    #.37 这是bc的特性,小于0的数,是不显示小数点前的0的。
    进制转换。用ibase设定输入数字的进制,obase设定输出数字的进制。
no=10
echo "obase=2;ibase=10;$no" | bc   #1010

计算平方以及平方根。

echo "10^4" | bc        #1000   平方
echo "sqrt(100)" | bc   #10     平方根

2.3 IFS

全称是Internal Field Separtor,内部分隔符。
Shell 的环境变量分为 set, env 两种,其中 set 变量可以通过 export 工具导入到 env 变量中。其中,set 是显示设置shell变量,仅在本 shell 中有效;env 是显示设置用户环境变量 ,仅在当前会话中有效。换句话说,set 变量里包含了 env 变量,但 set 变量不一定都是 env 变量。这两种变量不同之处在于变量的作用域不同。显然,env 变量的作用域要大些,它可以在 subshell 中使用。
而 IFS 是一种 set 变量,当 shell 处理"命令替换"和"参数替换"时,shell 根据 IFS 的值,默认是 space, tab, newline 来拆解读入的变量,然后对特殊字符进行处理,最后重新组合赋值给该变量。

eg:
$ cat test.txt
1
2
3
$ out=$(cat test.txt)
$ echo $out
1 2 3           #shell将(cat test.txt)的结果拆解,并用默认的分隔符(空格)重新组合,赋值给out,因此echo $out的结果不包含换行。

如果要保留cat test.txt中的换行符,一般情况下要做两步:
1是,设定IFS为换行:IFS='\n'
2是,将$(cat test.txt)用双引号引起来,表示不用
若指定IFS为换行符。

2.4 UID

特殊的环境变量,如果UID=0,表示当前以root用户运行脚本。否则不是root

3.自增

Linux Shell中写循环时,常常要用到变量的自增,现在总结一下整型变量自增的方法。

1)  i=`expr $i + 1`;
2)  let i+=1;
3)  ((i++));    #双括号结构
http://www.cnblogs.com/chengmo/archive/2010/10/19/1855577.html
4)  i=$[$i+1];
5)  i=$(( $i + 1 ))

4.双括号结构(())

双括号结构是对shell中算数及赋值运算的扩展。
语法:
((表达式1,表达式2…))
特点:

  1. 在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。
  2. 在双括号结构中,所有变量可以不加入:“$”符号前缀。
  3. 双括号可以进行逻辑运算,四则运算.eg. echo $((a>1?2:3));注意四则运算中仍然不支持浮点数运算
  4. 支持多个表达式运算,各个表达式之间用“,”分开. eg:((a+1,b++,c++))
  5. 双括号结构 扩展了for,while,if条件测试运算

5.数组

  1. 取数组长度 – '#'
arr=(1 2 3 4 5)
len=${#arr[@]}
  1. 打印特定索引的数组元素
echo ${arr[2]}      #2
  1. 打印出数组中的所有值-'*'、'@'
echo ${arr[*]}
echo ${arr[@]}

6.关联数组

在关联数组中,可以用任意的文本作为数组索引。先声明才能使用

  1. 声明一个关联数组。
declare –A ass_array
  1. 赋值:
a)  ass_array=([index1]=val1 [index2]=val2)
b)  ass_array[index1]=val1
ass_array[index2]=val2
  1. echo ${ass_array[index1]}
  2. 列出数组索引:
    echo ${!ass_array[@]}

7.临时文件或目录

在shell脚本中经常要保存临时的数据,如果使用认为创建临时文件用户保存临时数据,则有可能出现重名的情况,导致覆盖原来的数据。
mktemp prefile.xxx 创建以prefile开头的随机文件文件,并返回文件名,指定前缀时必须包含至少3个xxx。
主要参数:
-d : 创建一个目录,dirname=mktemp -d
-u : 仅生成随机文件名,但不创建实际的文件或目录,tmpfile=mktemp -u

原文链接:http://blog.keepmovingxin.com/2016/05/02/Learn-shell/

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

推荐阅读更多精彩内容

  • Shell Study Notes 指导思想: 10分钟语法+实操 变量 变量赋值 Here文档 输入到一个命令的...
    PennLi阅读 247评论 0 0
  • 1.特殊文件:/dev/null与/dev/tty /dev/null:bit bucket(位桶),传送到此文件...
    喜欢萝莉的逗逼青年阅读 526评论 0 48
  • 1.awk 对付文字处理工作,做一些文本/数据处理,最基本功能是在文件或字符串中基于指定规则浏览和抽取信息. 1....
    喜欢萝莉的逗逼青年阅读 722评论 0 50
  • 很久没写过字句了, 然后就一直追忆…… 发现离家后的我 就像失了忆 仿佛不记得自己都做了什么 不是想不起 而是每一...
    汐芜阅读 71评论 0 0
  • 如果你我在梦中相遇 请千万不要叫醒我 就让我永远的沉浸在这迷梦里 细听你均匀的呼吸 感受你每一寸肌肤的细腻 在无尽...
    慕容锦瑟阅读 491评论 2 2