2019-05-08 shell第一天

一. Shell介绍:命令的集合

  1. 用户,shell,内核关系:


    1.png
  2. 基本简介
    (1)#!指明解释器 与 赋予可执行权限
    在脚本内指明解释器: #!/bin/bash
    给脚本可执行权限: chmod +x xx.sh
    (2)执行脚本:./xx.sh 或者 /bin/bash xx.sh 或 (命令;命令;命令)
    [oracle@localhost ~]$ (cd go;ls -al)

    2.png

    3.png

(3)查看当前系统所使用的shell方式:echo $SHELL


4.png

(4)shell操作的本质:fork一个子进程并调用exec执行xx.sh这个程序
(5)行注解: #
多行注解:(注:下面的!可换成其他的符号)

      :<<!
       !

(6)echo 用于字符串的输出(自动换行)

  • 显示转移字符:echo ""It is a test"" #输出的带双引号

  • 显示变量的值:echo “$变量”

        read name  # read 命令从标准输入中读取一行,并赋值其后的而变量
        echo "$name It is a test"  #输出的是变量name的值。
    
  • 显示换行:echo -e "OK! \n" # -e 开启转义

  • 显示不换行 echo -e "OK! \c" # -e 开启转义 \c 不换行
    即下面的输出会在本行继续输出。

  • 单引号,原样输出字符串,不转移,不输出变量:

    echo '$name\"'
    
  • 显示结果重定向到文件:

    echo "It is a test" > myfile
    
  • 使用的是反引号 输出命令的执行结果: echo命令`
    (7)printf输出命令(手动换行\n)
    格式: printf 格式 参数 #格式可选

    • printf "Hello, Shell\n" # hello, shell
    • printf "%-10s %-8s %d\n" 路飞 男 66 #
      %-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐)
      %d 整形; %-4.2f 指格式化为小数,其中.2指保留2位小数
      注: 上面的格式,可双引号,可单引号, 可无引号。
  1. 变量—》shell中的变量的值都是字符串, 不需要声明。

(1)分类: 环境变量与 本地变量

环境变量是任何进程都有的概念,而本地变量是Shell特有的概念**

  • 定义变量:变量名不加美元符号等号两边都不能有空格: varname=value
    只读变量:(值不可修改,先赋值)readonly 命令修饰—》readonly myUrl

  • 使用定义过变量:变量名前面加美元符号—》$varname 或者 ${变量名}

  • 删除变量:unset命令删除环境/本地变量。 unset varname

(2) 字符串: 可单引号,可双引号

  • 单引号: 内部的任何字符都会原样输出,即内部的变量是无效的。

    注:当单引号内部出现成对的单引号时—》起到拼接字符串作用。

  • 双引号: 里可以有变量, 可以出现转义字符。

  • 拼接字符串: 使用单引号 或 双引号

 var_name="12"
 var1="hello,”$var_nam”"     #双引号拼接
 var_2='hello, '$var_name'’  #单引号拼接
echo $var1 $var2
  • 获取字符串长度:${#string}
  • 字符串截取:echo ${string:0:4} #从第0个开始,一共获取4个
 方式1: 路径分割: dirname命令(目录), basename命令(名称)
例子:  Var1=“/etc/xiawucha.txt”
            dirname $var1          #得:/etc
            basename $var1 #得:xiawucha.txt

方式2: 使用expr命令:expr substr $变量名 起始位置 截取长度

   注:起始位置从1开始

方式3: 使用 ${} 表达式: ${变量名 :起始位置 : 截取长度}
注: 编号从0开始

var1= xiawucha

 expr substr $var1 4 4 #得: wuch

 echo ${var1:4:4} #得: ucha
  • 字符串替换

同样使用${}

      格式1: ${var1 /old/new}     #将变量中的 第一个old 变成 new

       格式2: ${var1 //old/new}       #将变量中的 所有old 变成 new

注: old,new代表字符。

(3) 数组: 只支持一维数组,但没有限制数组大小,下标从0开始

  • 定义数组: 使用()代表数组,内部值使用空格或换行分割。

     array_name=(v0 v1 v2 v3)
    
  • 获取数组的值:${数组名[下标]}

    获取数组的所有值,使用@:${数组名[@]}

  • 取得数组元素的个数 length=${#array_name[@]} 或将@换成 * 好

  • 取得数组单个元素的长度lengthn=${#array_name[n]}

(4)使用变量

1)三种定界符号: 双引号,单引号, 反撇号或$()

双引号: 允许引用,允许转义\

单引号: 进制 引用 与 转义; 代表其: 本事的符号。

反撇号 或者 $() :以命令输出进行替换。

        echo “变量名”  : 输出的变量的值, 一般都省略 “”。

       echo ‘变量名’  : 输出还是变量的名。

         A= ‘命令’ :将命令输出的值赋值给变量。 或者使用$()

2)创建的环境变量。 目的:用来记录、设置运行参数

系统赋值:USER, LOGNAME, HOME, SHELL...

用户操作:PATH, LANG, CLASSPATH ....

列出所有的环境变量: env

同时输出多个环境变量的值: echo $USER $HOME $SHELL

3)特殊的变量: 由系统 或 脚本控制, 不可直接赋值。

  • $? 记录前一条命令执行后的状态值,为0:代表前一个命令执行成功,否则失败

  • $0 脚本自身的程序名

  • $1-$9 第一到第9个位置的参数。

  • $* 命令行的所有位置参数的内容

  • $# 命令行的位置参数个数

2. 运算符

原生bash不支持简单的数学运算,但可以通:awk 和 expr,expr 等实现:

(1) 算数运算符:

 加(+), 减(1),乘(*),除(/), 取余(%),赋值(=)

特别: 相等(==), 不相等(!=)-》放在方括号[]之间,并且前后要有空格

例子:`expr 2 + 2` # 使用 反引号,不是单引号。

  a=10

  b=20

  val=`expr $b / $a`

  echo "b / a : $val" # b / a :  2

例子:

  val=`expr $a \* $b`

  echo "a * b : $val"

例子

  if  [ $a == $b ]  # [$a==$b]  是错误的,必须写成  [ $a == $b ]
  then
  echo "a 等于 b"
  fi

总结如下:

  • 乘号(*)前边必须加反斜杠()才能实现乘法运算;
  • 表达式和运算符之间要有空格: 2+2 错, 2 + 2
  • 完整的表达式要被 ` ` 包含。

(2) 关系运算符: 只支持数字,不支持字符串,

结果: true, false

判断 :相等(-eq), 不相等(-ne)

大于(-gt), 小于(-lt)

大于等于(-ge), 小于等于(-le)

例子:

 a=10

b=20

if [ $a -eq $b ] 

then

 echo "$a -eq $b : a 等于 b"

else

 echo "$a -eq $b: a 不等于 b"

fi
  • 关系表达式在[]中,且前后要留有空格。

(3) 布尔运算符: 结果为 true, false。

与(-a) 或(-o) ,非(!)


if [ $a -lt 100 -a $b -gt 15 ]
then
        echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
      echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi

(4) 逻辑运算符: 结果为 true, false。

逻辑与(&&), 逻辑或(||) # 采用双[[ ]] zz中括号

if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi

(5) 字符串运算符: 结果为 true, false。

判断字符串:  相等(=),      不相等(!=)

            长度为0(-z)   长度不为0(-n)

             不为空($)


a="abc"
b="efg"
if [ $a = $b ] # 注: if  [ $a ] 如果字符串为空
then
    echo "$a = $b : a 等于 b"
else
    echo "$a = $b: a 不等于 b"
fi

(6)文件测试运算符: 检查文件的属性,返回:true, false

检测文件:

     是块设备[ -b file ],      是字符设备[ -c $file ]
     是目录[ -d $file ] ,      是普通文件 [ -f $file ]
     是有名管道[ -p $file ] ,

检测文件权限:

  是可读 [ -r $file ] ,      是可写[ -w $file ]
  是可执行[ -x $file ] ,   是为空[ -s $file ]

检测文件(包括目录):

   是否存在[ -e $file ]

例子:

 file="/var/test.sh"
 if [ -e $file ]
then
 echo "文件存在"
else
 echo "文件不存在"
fi

例子:

expr 45/21         # 直接输出
echo $[45 +21]    #$[]格式,需要echo输出
  • 使用随机数(RANDOM 变量): echo $[RANDOM %100]

(7) 条件测试test 命令
注:测试操作的方法
测试的本质:是判断一个条件的操作命令。 而$?返回值可以判断条件是否成立。
格式1: test 条件表达式
格式2: [条件表达式] 注: 主要使用这种方式
注: 练习可以使用的方式【条件表达式】&& echo YES
上面的结果是: 失败什么都不输出; 成功输出YES。
作用:用于检查某个条件是否成立,进行数值、字符和文件三个方面的测试。

1)数值: 结果 true, flase

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

例子:

num1=100
num2=100
if test $[num1] -eq $[num2]
then
  echo '两个数相等!'
else
  echo '两个数不相等!'
fi

2)字符串 结果 true, flase

= 等于, !=不等于 -z 字符串(字符串长度为0) -n 字符串 (长度不为0)

num1="123"

num2="124"

if  test  $num1 = $num2

then

 echo '两个字符串相等!'

else

 echo '两个字符串不相等!'

fi

3) 文件测试 结果 true, flase

-e 文件名 : 文件存在

-r 文件名 : 文件存在且可读

-w 文件名 : 文件存在且可写

-x 文件名 : 文件存在且可执行

-s 文件名 : 文件存在且至少有一个字符

-d 文件名 :文件存在且为目录

-f 文件名 :文件存在且为普通文件

-c 文件名 :文件存在且为字符型特殊文件

-b 文件名 :文件存在且为块特殊文件

if   test  -e   ./SE
then
  …
fi

3. 流程控制

(1)程序流控制

(2)单分支、双分支的if应用

单分支

If 条件测试

then

命令序列

 fi

双分支

  if 条件测试

  then

      命令序列1

  else

      命令序列2

  fi

多分支

  if 条件测试

 then

    命令序列1

 elif 条件测试2

 then

      命令序列2

 else

   命令序列n

 fi

(3)for循环

  for 变量名 in 取值列表

  do

      命令序列

  done

(4)while循环

 while condition

 do

    command

 done

无限循环:

 while true

  do

    command

 done

 或者: for  ((  ;  ;  ))

(5)与while相反的循环

until condition #直至条件为 true 时停止

do

   command

done

(6)case语句,多选择

 case 变量值 in

 模式1)

     命令序列1

      ;;

 模式2)

     命令序列2

     ;;

     。。。。。

  *)

      默认命令序列

 esac

注:其中的模式1,模式2是不同的取值,比如: 【a-z】 【0-9】

(7)break :跳出循环

continue : 退出当前循环

6 函数

(1)格式:

 function 函数名 ()   # function可选,即:可以没有

 {

    动作

     return xx    # return可选,即:可以没有

}

(2)函数参数: 函数体内部, 用$n 的形式来获取参数的值:

  $1表示第一个参数,$2表示第二个参数

  调用函数时,函数名后面的为参数。

注: 当n>=10时,需要使用${n}来获取参数

注:$0为执行的文件名

(3) 处理参数的特殊字符:

$# :传递到脚本的参数个数

$* :以一个单字符串显示所有向脚本传递的参数**

$$ :脚本运行的当前进程ID号

$! :后台运行的最后一个进程的ID号

$- :显示Shell使用的当前选项。

$? :显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

7. shell 命令的组合应用: 管道操作, 重定向, 逻辑分割。

(1)重定向: 输出重定向 与 输入重定向**

输出重定向—》 将命令的输出结果 从终端 重定向到文件中,可覆盖,可追加。

输入重定向—》 从文件中读取要执行的命令(不是用户输入/dev/null 文件

command > file 将输出重定向到 file。 《覆盖》

command < file 将输入重定向到 file。

command >> file 将输出以追加的方式重定向到 file。《追加》

n > file 将文件描述符为 n 的文件重定向到 file。

n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。

n >& m 将输出文件 m 和 n 合并。

n <& m 将输入文件 m 和 n 合并。

<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。

(2)管道: 将一端的命令输出交给另一端的命令处理。 注: 两端都是命令

    格式:命令1 | 命令2

    作用:基本的统计 与 过滤。

注:管道的右侧是:命令。 重定向的右侧是:文件。

(3) 逻辑分割:处理多条“命令”间的逻辑关系。

逻辑与&& ---》 要求: 两个命令都成功

逻辑或|| ---》要求: 两个命令有一个成功就结束,不在执行

顺序执行“”即:分号

用途: 判断命令是否执行成功。

 例如: mkdir /ceshi/a 2>/dev/null && echo “成功”    

    或者:mkdir /ceshi/a 2>/dev/null || echo “失败”

    注:  即两个命令一个执行完,另一个才执行。

(4)回收站: /dev/null

/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;

如果希望屏蔽 stdout 和 stderr,可以这样写: $ command > /dev/null 2>&1

注: 0 是标准输入(STDIN),1 是标准输出(STDOUT),2 是标准错误输出(STDERR)。

3. 文件包含(脚本中 包含脚本文件)

方式1: . filename    # 注意点号(.)和文件名中间有一空格

方式2:  source filename

注: 被包含的脚本不需要可执行权限, 只需要外面的脚本添加可执行权限即可。

  1. LINUX 启动五阶段:
    内核的引导。 运行 init。 系统初始化。 建立终端 。 用户登录系统。
    (1)内核引导
    开电源,BIOS开机自检,按其设置的启动设备(硬盘/CF卡)来启动。
    操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。
    (2)init 进程: 系统所有进程的起点(目的: 启动守护进程)
    init 程序首先是需要读取配置文件 /etc/inittab。
    运行级别 : 启动时根据运行级别,切丁运行那些服务/守护进程
    init进程的一大任务,就是去运行开机启动的程序。Linux允许为不同的场合,分配不同的开机启动程序,这就叫做"运行级别"。 7个级别略。


    111.png

(3)系统初始化(目的: 通过脚本,配置系统环境)
init配置文件中有一行:si::sysinit:/etc/rc.d/rc.sysinit调用执/etc/rc.d/rc.sysinit,而rc.sysinit是一个bash shell的脚本,用于完成一些系统初始化工作。
脚本实现:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。
(4)建立终端
rc执行完毕后,返回init。init会打开6个终端,以便用户登录系统。tty1-tty6。
(5)用户登录系统
用户的登录方式有三种: 命令行登录 , ssh登录 , 图形界面登录。


222.png

关机介绍:
sync 将数据由内存同步到硬盘中。 #注:关机重启之前是先自动执行该指令。

shutdown 关机指令,
shutdown –h 10 ‘This server will shutdown after 10 mins’ 
shutdown –h +10      # 十分钟后关机
shutdown –h now      #立马关机 
shutdown –h 20:25    #系统会在今天20:25关机 
reboot   #重启
shutdown –r now     #系统立马重启 
shutdown –r +10    #系统十分钟后重启 

扩展:代换

1. 文件名代换:用于匹配的字符称为通配符,如:* ? [ ] 具体如下:

*      匹配0个或多个任意字符
?     匹配一个任意字符
[若干字符]    匹配方括号中任意一个字符的一次出现

2. 命令代换:由“`”反引号括起来的也是一条命令,Shell先执行该命令,然后将输出结果立刻代换到当前命令行中。
例如定义一个变量存放date命令的输出:

DATE=`date`
echo $DATE
命令代换也可以用$()表示: DATE=$(date)

3. 算术代换

使用$(()),用于算术计算,(())中的Shell变量取值将转换成整数,同样含义的$[ ]等价。
例如:

VAR=45
echo $(($VAR+3)) 等价于 $((var+3)) 或echo $[VAR+3]或 $[$VAR+3]
$(())中  只能用+-*/和()运算符,并且只能做整数运算。
$[base#n],其中base表示进制,n按照base进制解释,后面再有运算数,按十进制解释。
echo $[2#10+11]

4. 转义字符 \

用于去除紧跟其后的单个字符的特殊意义(回车除外),即: 紧跟其后的字符取字面值

 echo $SHELL

 结果: /bin/bash

 echo \$SHELL

  结果: $SHELL

5. 单引号双引号: 都是字符串的界定符

单引号用于保持引号内所有字符的字面值即使引号内的\和回车也不例外,但是字符串中不能出现单引号

被双引号用括住的内容,将被视为单一字串它防止通配符扩展,但允许变量扩展

 VAR=200

echo $VAR   # 结果200

echo '$VAR'   # 结果$VAR

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

推荐阅读更多精彩内容