2020-12-13 Shell的简单介绍及使用

shell

大部分情况都是Linux操作系统,那么熟悉命令的用法以外,熟悉使用shell脚本能节省不少时间。

shell是什么

平时经常在Linux操作系统中使用各种命令,比如查看当前的目录文件,我们会使用ls或者ll,这些字符串参数实际上会被"某段程序"执行并启动它。这个负责将用户输入的字符串转换为需要执行程序的东西叫做shell,即帮用户更方便使用操作系统接口的“壳”。同样的壳还有当我输入Maven+相关参数的时候是不是就会去执行相应的功能,我使用sql语句的时候,数据库引擎是不是也会各种调用,一样的道理

尝试编写第一个shell

vim创建打开一个文件,扩展名为.sh。如下所示

#!/bin/bash #告诉系统使用什么解析器
echo "Hello xiaolan !" # echo进行输出
  • 执行方法1
 chmod +x ./hello.sh ./hello.sh
  • 执行方法2
 /bin/sh hello.sh

变量

变量名和等号之间不能有空格

定义变量注意事项

  • 命名首个字符不能是数字,只能使用英文字母、数字和下划线

  • 不能使用标点符号

  • 不能使用bash中关键字

变量使用

使用变量(使用变量的过程中,最好加上花括号),只需要在变量前面加上美元符号即可

#!/bin/bash
James="小皇帝"
echo $James

只读变量

使用readonly将变量定义为只读,只读意味着不能改变

#!/bin/bash
James="小皇帝"
readonly James
James="小哥哥"

删除变量

使用unset删除变量,变量删除以后不能再次使用,且不能删除只读变量

#!/bin/bash
James="小皇帝"
unset James
echo $James #不会有任何输出

变量类型

  • 局部变量

仅当前shell可用

  • 环境变量

所有程序都能访问环境变量

  • shell变量

通过一部分环境变量和shell变量保证shell的正常运行

字符串

使用字符串的过程中,既可以用双引号也可以用单引号,也可以不用

  • 单引号

单引号内容原样输出,不能包含变量,且不能出现单独单引号

  • 双引号

可以出现转义字符

#!/bin/bash
James="小皇帝"
str="\"$ James\"! oh my gad \n "
echo -e $str 

获取字符串长度

使用#

string="qwert"echo $(#string)# 提取子字符串echo $(string:1:3)#查找字符串echo 

数组

支持以为数组

定义数组

数组元素使用“空格”隔开

array=(value1,value2,value3)

读取数组

value1=${array[0]}

使用@输出数组所有元素

echo ${array[@]}

获取数组中所有元素以及数组长度

#! /bin/bash
# author:xiaodi
array[0]=a
array[1]=b
array[3]=c
echo “数组的元素为:${array[*]}”
echo “数组的元素为:${array[@]}”
echo “数组的个数为:${#array[*]}”
echo “数组的个数为:${#array[@]}”

执行

./array.sh

结果

image

注释

  • 单行注释

使用#开头的行为注释,会被解释器忽略

  • 多行注释

shell传递参数

在执行shell的时候,命令行指定参数,如下所示

#!/bin/bash
James="小皇帝"
echo "执行的文件名为:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"

执行

./param.sh 1 2

结果

image

几个特殊字符

image

案例(partionnal.sh)

#!/bin/bash
# author:xiaodi
echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done

执行

./demo2.sh 1 2 3

结果

image
  • 相同点:都是会引用所有参数

  • 不同点:在使用双引号的时候。如果脚本运行时两个参数为a,b,则"*"等价于"ab",而"@"等价于"a","b"

#!/bin/bash
# author:xiaodi
echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo
 $idone

printf

使用printf格式化字符串,同时可以指定字符串宽度和对齐方式,

格式如下

printf format-string [arguments...]

#!/bin/bash
# author:xiaodi

printf "%-8s %-8s %-4s\n" 姓名 科目 分数  
printf "%-8s %-8s %-4f\n" 小明 数学 97
printf "%-8s %-8s %-4f\n" 小话 语文 89
printf "%-8s %-8s %-4f\n" 王三 英语 93

结果

image

test

shell中的test用于检查某个条件是否成立

image

案例

#!/bin/bash
# author:xiaodi

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

结果

image

字符串比较

#!/bin/bash
# author:xiaodi

num1="xiaodi"
num2="xiaoid"
if test $num1 = $num2
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

结果

image

流程

if语句语法格式

if condition
then
    exec1
    exec2
    ...
    execN 
fi

如果简化为一行

if [$(ps -ef | grep -c "httpd") -gt 1];then echo "true";fi

if else-if else

if condition1
then
    exec1
elif condition2
then
     exec2
else
    execn
fi

案例 判断两数值是否相等

#!/bin/bash
# author:xiaodi
a=2
b=3
if [ $a == $b ]
then
   echo "a 等于 b"
elif [ $a -gt $b ]
then
   echo "a 大于 b"
elif [ $a -lt $b ]
then
   echo "a 小于 b"
else
   echo "没有符合的条件"
fi

for循环

for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

while语句

通常用于从输入文件不断读取数据

while condition
do
    exec
done

#!/bin/bash

int=1
while(( $int<=6 ))
do
    echo $int
    let "int++"# 用于执行一个或者多个
done

无限循环

while true
do
    exec
done

case语句

多选择语句。取值后面为单词in,每一个模式以")"结束。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ";;"。

#!/bin/bash

echo '输入 1 到 3 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    *)  echo '你没有输入 1 到 3 之间的数字'
    ;;
esac

输入不同的内容,会有不同的结果,例如:

输入 1 到 4 之间的数字:
你输入的数字为:
3
你选择了 3

跳出循环

break:break命令允许跳出所有循环

#!/bin/bash

while :
do
    echo -n "输入 1 到 3 之间的数字:"
    read aNum
    case $aNum in
        1|2|3) echo "你输入的数字为 $aNum!" 
       ;; 
       *) echo "你输入的数字不是 1 到 3 之间的! 游戏结束"
            break 
       ;;
    esac
done

continue:跳出当次循环

#!/bin/bash
while :
do
    echo -n "输入 1 到 3 之间的数字: "
    read aNum    case $aNum in
        1|2|3|4|5) echo "你输入的数字为 $aNum!"
        ;; 
       *) echo "你输入的数字不是 1 到 3 之间的!"
            continue
            echo "游戏结束"
        ;;
    esac
done

shell函数

用户定义函数,然后在shell脚本中随便调用,格式如下

[ function ] funname [()]
{
    action;
    [return int;]
}

例子

#!/bin/bash

Fun1(){
    echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
Fun1
echo "-----函数执行完毕-----"

带return语句

#!/bin/bash

FunReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum 和 $anotherNum !"
    return $(($aNum+$anotherNum))
}
FunReturn
echo "输入的两个数字之和为 $? !"

函数参数

#!/bin/bash

funParam(){
    echo "第一个参数为 $1 !"
    echo "第二个参数为 $2 !"
    echo "参数总数有 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
funParam 1 2 3 4

shell重定向

输出重定向

command1 > file 如果file中存在内容将被清空覆盖;如果追加使用command1 >>file

ls -l > dir.txt
cat dir.txt
image

/dev/null文件

写入到它的内容都会被丢弃,会起到"禁止输出"的效果,如果希望屏蔽stdout和stderr “ command > /dev/null 2>&1

注意:Linux命令行都会打开三个文件

  • 标准输入文件:stdin文件描述符为0

  • 标准输出文件:stdout文件描述符为1

  • 标准错误文件:stderr文件描述符2

运算符

下表列出了常用的算术运算符,假定变量 a 为 2,变量 b 为 3:

算术运算符

算术运算符

关系运算符

关系运算符

布尔运算符

布尔运算符

逻辑运算符

逻辑运算符

字符串运算符

image

shell实战

  • 请将当前目录中demo.txt第二行第三列数据输出到demo2.txt中
 cat demo.txt|awk ’NR==2{print $3}’ >demo2.txt 
  • 日志如下统计访问ip最多的前10个
awk ’{print $1}’ *.log | sort | uniq -c | sort -nr | head -n 

uniq -c 删除排序文件中的重复行;sort对于文本进行排序 -l 按照当前环境排序. -m合并已经排序好的文件,不排序.-n 按照字符串的数值顺序比较,暗含-b -r颠倒比较的结果.

  • 查看占用内存最大的进程的PID和VSZ
ps -aux|sort -k5nr|awk ’BEGIN{print ”PID VSZ”}{print ![2,(https://www.zhihu.com/equation?tex=2%2C)2,5}’|awk ’NR<3′ 
  • 如何检查文件系统中是否存在某个文件
if [-f /var/log/messages]thenecho "File exts"fi

每个脚本开始的 #!/bin/sh#!/bin/bash 表示什么意思 ?

#!/bin/bash 表示脚本使用/bin/bash。对于 python 脚本,就是#!/usr/bin/python

  • &和&&区别

“&” 脚本在后台运行时使用它。“&&”当前一个脚本成功完成才执行后面的命令

  • 脚本文件中,如何将其重定向标准输出和标准错误流到 log.txt 文件 ?
./a.sh >log.txt 2>&1
  • 如何计算本地用户的数目
wc -l /etc/passwd | cut -d
  • shell中进行字符串比较和数字比较
[ $A == $B ] – 用于字符串比较
[ $A -eq $B ] – 用于数字比较
  • 去掉字符串空格
echo $string | tr -d " "
  • 统计内存使用
#! /bin/bash

sum=0
for mem in `ps aux |awk '{print $6}' |grep -v 'RSS' `
do
    sum=$[$sum+$mem]
done
echo "The total memory is $sum""k"

结果

image
  • 批量更改文件名

批量修改123目录下txt为txt.temp。将temp打包为test.tar.gz

#!/bin/bash
##查找txt文件
find /123 -type f -name "*.txt" > /tmp/txt.list
##批量修改文件名
for f in `cat /tmp/txt.list`
do
    mv $f $f.temp
done
##创建一个目录,为了避免目录已经存在,所以要加一个复杂的后缀名
d=`date +%y%m%d%H%M%S`
mkdir /tmp/123_$d
##把.temp文件拷贝到/tmp/123_$d
for f in `cat /tmp/txt.list`
do
    cp $f.temp /tmp/123_$d
done
##打包压缩
cd /tmp/
tar czf 123.tar.gz 123_$d/
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容