Linux Shell

鱼龙之地:

判断之前的 命令是否执行成功:

echo $?

 

linux中 执行文件方式的区别:

1sh

如: sh   test.shsh   /user/file.sh
2、 ./ 使用这个方式 必须保证要执行的文件 有 可执行权限

如: ./test.sh   ---这种主要是 . 做为执行声明, /表示当前目录
​
    ./user/file.sh  ---可以接绝对路径
3、直接使用shell 执行:

    如一: /bin/sh  test.sh/bin/sh  /user/file.sh
​
    如二:    /bin/bash   test.sh/bin/bash   /user/file.sh

linux 文件权限管理:

关键字:chmod   [ 选项 ]    文件名
​
    选项: x   可执行
​
          w   可写
​
          r    可读
          
 如:  chmod +x   test.sh    给文件 增加 执行权限
      chmod -x   test.sh    删除文件执行权限
      chmod +xwr  test.sh   给文件 增加 执行写入读取权限

linux变量的定义与引用:

PS:
    1、命名是等号两边不能有空格
    2、全局变量名 大写
查看系统变量:

env
使用系统变量:

echo $PATH        #在终端打印path变量值
自定义变量:

info="我是大佬"    #定义
​
echo $info       #使用
赋值的两种方式:

如一:info=$(pwd)      #把pwd执行后的结果赋值给info
​
        echo $info        #打印结果
​
如二: info=` pwd`    #效果和上面一样, 注意 符号"``" 不是单引号,而是esc键下面的
​
         echo $info
脚本中传参:

$1 ~ $9: 匹配一位置参数传过来的 第一个 ~ 第九个 参数, 第九个以后通过 ${10} ~${n} 获取 
$@ 匹配所有参数
$* 匹配所有参数
shift  默认删掉第一个位置参数
#a.sh 1 2 3 4 5

#/bin/bash
echo $@    #输出为 1 2 3 4 5
shift
echo $@    #输出为 2 3 4 5 

 

linux 四则运算

加、减、乘、除
两种实现方式:

如一: expr

PS:有两点限制

1、运算符两边需要空格

2、 乘号需要转义

expr 为 expression 的缩写

expr 10 + 3        #输出 13
expr  10+3     #输出 10+3          ***运算符两边需要空格***expr   10  \\* 3   #输出 30     ***乘号需要转义***expr   10  / 3     #输出  3expr   10 - 7   #输出 3
如二: $[]

echo   $[10+3]       #输出 13echo   $[10 + 3]     #输出 13      符号两边 没有空格的限制
​
echo   $[10*3]       #输出 30echo   $[10/3]       #输出 3echo   $[10-3]       #输出  7
浮点型运算:
在shell中,做浮点运算一般是用bash的计算器 bc 在shell脚本中,一般我们的使用方法是:

variable=$(echo "options; expression" | bc)

表达式讲解:

options是bc的一些选项,例如: 可以通过scale去设置保留的小数位数。具体有哪些参数,可以man bc进行查看
​
expression就是我们具体的表达式,例如 10 * 3" | " 这个符号,对于熟悉linux系统的人来说,这个再熟悉不过了。它叫做管道, 之所以会叫做管道,其实很形象,你可以把它看作一根水管,水管一头接入前一个命令的返回结果, 一头接入下一个命令。表示将前一个命令的执行结果作为后一个命令的参数输入。以上,表示将我们的表达式作为bc的参数输入。
如:

#表示 10/3, 保留2位小数,将结果赋值给了num, 输出3.33
num=$(echo "scale=2; 10 / 3" | bc)
echo $num

 

第二种:awk

如:

num=$(awk 'BEGIN{print 7.01*5-4.01 }')     #把结果赋值给变量
​
echo $num    #打印结果
​
一般使用: msg=$(pwd | awk '{ print $1}')  将pwd的执行结果第一列 赋值给msg  

 

linux if语句:

前言:

小提示:echo $? 判断上一次执行是否成功(成功返回 0 ,失败返回 1)

1、注意: shell 中 if语句与其他语言不通之处在于  shell中 if 后跟 命令,其他语言if语句 直接返回布尔值

2、在shell脚本的if其实是根据紧跟后面的那个命令的**退出状态码**来判断是否执行then后面的语句的。关于退出状态码,你只需要记住:正常退出(命令执行正常)的状态码是0, 非正常退出的状态码不是0(有少)。

3、以上语句的语义为: 如果if后面的命令执行正常(状态码0),那么就执行then后面的语句。否则不执行。 fi代表if语句的结束。
if - then :
#这儿由于pwd是linux内置的命令,因此执行后会正常退出(状态码0),所以会执行then中的语句
#如果此处替换为一个不存在的命令(例如: pw),那么就会非正常退出,不会执行then中的语句
if pwd         
then
    echo 执行then里面的语句
fi    #一定记得有结束语
例一简写:

if pwdthenecho 执行then里面的语句
​
fiif - then - else:
判断处理异常退出(状态码非0)情况

if pwdthenecho 正常退出
​
elseecho 非正常退出
​
fiif - then - elif - elseif pwd
then
    echo 正常退出
elif
    ls #条件
then
    echo 正常退出
else
    echo 非正常退出

test命令:

前言:

0、通过man test命令可以看到具体的用法。

1、test命令用于if-then或者if-then-else语句中,主要用于判断列出的条件是否成立,如果成立,就会退出并返回退出状态码0,否则返回非0。

2、test命令只能判断一下三类条件:

  • 数值比较

  • 字符串比较

  • 文件比较

基本使用:
例一: 直接使用

test  condition(条件)
例二:if - then

if test condition
then
    commands(命令)
fi
例三: if - then - else

if test codition
then
    commands
else
    commands
fi

 

 

数值比较:
比较描述
n1 -eq n2 判断n1是否等于n2
n1 -ge n2 判断n1是否大于或等于n2
n1 -gt n2 判断n1是否大于n2
n1 -le n2 判断n1是否小于或等于n2
n1 -lt n2 判断n1是否小于n2
n1 -ne n2 判断n1是否不等于n2
字符串比较:
比较描述
str1 = str2 判断str1是否与str2相同
str1 != str2 判断str1是否与str2不相同
str1 < str2 判断str1是否比str2小(根据ASCII)
str1 > str2 判断str1是否比str2大(根据ASCII)
-n str1 判断str1的长度是否非0
-z str1 判断str1的长度是否为0
文件比较:
对于文件的比较,其实跟上面差不多,都是用test命令

 

case语句:

在使用if-then-else语句中,如果碰到条件很多的情况,如下:

#!/bin/bash
num=3
if (( $num == 1 ))
then
    echo "num=1"
elif (( $num == 2 ))
then
    echo "num=2"
elif (( $num == 3 ))
then
    echo "num=3"    
elif (( $num == 4 ))
then
    echo "num=4"
fi  
将以上代码替换为case:

#!/bin/bash
case $num in
1)
    echo "num=1";;
2)
    echo "num=2";;
3)
    echo "num=3";;
4)
    echo "num=4";;
*)
    echo "defaul";;
esac  

 

linux 循环语句:

for-in语句:

如一:

for i in a b c d
do
    echo $i
done
​
#输出:
a
b
c
d
如二:

for i in a,b,c,d
do
echo $i
done
​
#输出:
a,b,c,d
造成这个上面结果的原因是:for...in循环默认是循环一组通过空格或制表符(tab键)或换行符(Enter键)分割的值。这个其实是由内部字段分隔符配置的,它是由系统环境变量IFS定义的。当然,既然是由环境变量定义的,那当然也就能修改啊。

 

修改IFS值:

如一:

oldIFS=$IFS
IFS=$","for i in a,b,c,d
do 
    echo $i
done
​
#输出
a
b
c
d
如二:

for i in a b c d
do
    echo $i
done
​
#输出
a b c d
#还原IFS值:

IFS=$oldIFS
以上第一个循环会分别输出abcde几个值。而第二个循环会输出a b c d e(即未处理)。因为我们把IFS的值设置为逗号了, 当然,不一定要是逗号,想设置什么,你说了算!

 

C语言风格的for

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

#输出
2
...
10

 

while循环

在bash中的while语句,看起来似乎是结合了if-then语句for循环语句。其基本格式如下:

while test command
do
	other command
done

与if-then语句一样,后面接test命令,如果test后面的命令的退出状态码为0. 那么就进入循环,执行do后面的逻辑。要注意在do后面的逻辑中写条件,避免死循环

既然是接test命令,那么一切都可以参考if-then的test

如一:

into=0
while test $into -lt 3
do
    echo $into
    into=$[$into + 1]   #退出条件
done

#输出
0
1
2
如二:

into=0
while [ $into -lt 3 ]   #注意:这里有个坑, 中括号两边 要有空格
do 
    echo $into
done

#输出
0
1
2
如三:

into=0
while (( $into <= 3 ))  
do
    echo $into
done

#输出
0
1
2
3

 

until语句:

until语句就是与while语句恰好相反, while语句是在test命令退出状态码为0的时候执行循环, 而until语句是在test命令退出状态码不为0的时候执行。

基本语法:

until test commands
do
	other commands
done
如:

into=0
until test $into -lt 3
do
    echo $into
    into=$[$into + 1]
done

 

其他两种 同while语句

break与continue控制循环

前言:

	值得注意的是 break n 与 continue n  表示由内向外退出n层循环
break:

break用于跳出当前循环

如一:

break跳出当前循环

#!/bin/bash
for (( flag=0; flag <= 10; flag++ ))
do
    if (( $flag == 5 ))
    then
        break
    fi
    echo $flag
done
如二:

break跳出内层循环

#!/bin/bash
flag=0
while (( $flag < 10 ))
do
    for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
    do
        if (( $innerFlag == 2 ))
        then
            break
        fi
        echo "innerFlag=$innerFlag"
    done
    echo "outerFlag=$flag"
done

#会陷入死循环,输出
...
innerFlag=0
innerFlag=1
outerFlag=0
...

如三:

break用于跳出外层循环

#!/bin/bash
flag=0
while (( $flag < 10 ))
do
    for (( innerFlag=0; innerFlag < 5; innerFlag++ ))
    do
        if (( $innerFlag == 2 ))
        then
            #2表示外面一层循环,也就是终止了所有循环
            break 2
        fi
        echo "innerFlag=$innerFlag"
    done
    echo "outerFlag=$flag"
done

#输出
innerFlag=0
innerFlag=1

 

continue:

continue用于结束本次循环,进入下一次循环,注意,continue后面的语句不会执行。

如一:

into=0
while test $into -lt 5
do 
    if test $into -eq 3;then
        into=$[ $into + 1 ]
        contunue
    fi
    echo $into
    into=$[ $into + 1]
done
如二:

flag=0
while (( $flag <= 10 ))
do
    if (( $flag == 5 ))
    then
        flag=$[$flag+1]
        continue
    fi
    echo "outerFlag=$flag"
    for (( innerFlag=11; innerFlag < 20; innerFlag++ ))
    do
        if (( $innerFlag == 16 ))
        then
            flag=$[$flag+1]
            continue 2   #这里2指定第2个封闭循环
        fi
        echo "innerFlag=$innerFlag"
    done
done

 

linux命令行---参数处理

前言:

shell可根据参数位置获取参数。通过 $1$9 获取第1到第9个的命令行参数。$0为shell名。如果参数超过9个,那么就只能通过${}来获取了

例如: 获取第10个参数,

echo ${10}
如一:

shell.sh  脚本内容
#!/bin/bash
echo "第一个为文件名: $0 "    # $0 获取的文件名会有 ./ 或者 完整路径
echo "第二个: $1 "
echo "第三个: $2 "
.......

执行:  ./shell.sh   第一个参数   第二个参数
PS: 通过basename命令来获取单纯的文件名$(basename $0) ,

成功的得到文件名和命令行输入的参数(命令行参数以空格分隔,如果参数包含了空格,那么久必须添加引号了)

 

读取所有参数

第一种:通过 $# 可获取参数总数

如:

#!/bin/bash
for (( index=0; index<=$#; index++ ))
do 
    echo ${!index}  
done
PS:由于${}内不能再写$符号,bash shell在这个地方是用了!符号,所以以上才写为了${!index}。

 

 

第二种:

在bash shell中还可以通过 $* 和 $@ 来获取所有参数

$* 会将命令行上提供的所有参数当作一个单词保存, 我们得到的值也就相当于是个字符串整体。
$@ 会将命令行上提供的所有参数当作同一字符串中的多个独立的单词。
#!/bin/bash
#testinput.sh
var1=$*
var2=$@
echo "var1: $var1"
echo "var2: $var2"
countvar1=1
countvar2=1

for param in "$*"   #第一种
do
    echo "first loop param$countvar1: $param"
    countvar1=$[ $countvar1 + 1 ]
done
echo "countvar1: $countvar1"

for param in "$@"    #第二种
do
    echo "second param$countvar2: $param"
    countvar2=$[ $countvar2 + 1 ]
done
echo "countvar2: $countvar2"
执行: ./testinput.sh 12 34 56 78

结果为:

#第一种--------
var1: 12 34 56 78
var2: 12 34 56 78
param1: 12 34 56 78

#第二种---------------
countvar1: 2
param1: 12
param2: 34
param3: 56
param4: 78
countvar2: 5

 

获得用户输入:

通过read命令来实现与用户进行交互

#!/bin/bash
echo "输入你的name: "
read name
echo "你的name:$name"

运行上面代码会会显示“ 输入你的name: ” ,当输入后,会把输入的值赋值给name变量, 然后最终输出 “你的name: (你输入的内容)”。

 

PS:不指定read后面的变量名,如果我们不指定, read命令会将它收到的任何数据都放进特殊环境变量REPLY中

#!/bin/bash
echo -n "yes or no(y/n)?"
read
echo "your choice: $REPLY"    #注意大小写

 

多个输入

#!/bin/bash
read -p "what's your name?" first last
echo first: $first
echo last: $last

 

以上示例首先输出“what's your name?”, 然后在本行等待用户输入(此处用read -p实现以上示例的echo -n + read命令的不换行效果),输入的参数以空格分隔,shell会把输入的值依次赋值给first和last两个变量。如果输入的值过多,假如我输入了3个值,那么shell会把剩下的值都赋值给最后一个变量(即第二三两个的值都会赋值给last变量)。

超时设置

通过read -t 来指定超时时间(单位为秒),如果用户在指定时间内没输入,那么read命令就会返回一个非0的状态码。

如:

#/bin/bash
if read -t 5 -p "Please enter your name: " name 
then
    echo "Hello $name"
else
    echo "Sorry, timeout! "
fi

运行以上示例,如果超过5秒没输入,那么就会执行else里面的。

 

linux三剑客:

前言:

grep、sed、awk 的查询条件均为 正则表达式

grep与find的区别在于,前者搜索文件中的内容,后者根据文件的属性 在系统中进行查找

grep:

前言:

  1. grep 全面搜索正则表达式并把行打印出来

  2. fgrep 它搜索字符串而不是搜索匹配表达式的模式。fgrep 命令使用快速的压缩算法。$, *, &#91;, |, (, )\等字符串被 fgrep 命令按字面意思解释。这些字符并不解释为正则表达式

    	语法: fgrep   " 字符串"  文件名
    
  3. pgrep 以名称为依据从运行进程队列中查找进程,并显示查找到的进程id。

    	语法:   pgrep  " 进程名 "
    
  4. egrep 用于在文件内查找指定的字符串。egrep执行效果与grep -E相似,使用的语法及参数可参照grep指令,与grep的不同点在于解读字符串的方法。

语法:

grep   正则表达式     目标文件
如:

grep xxxx  a.txt        #查找a.txt中是否有 xxxx,有责打印出来

grep '[a-z]' a.txt        #查找包含有小写字母的   在a.txt中

grep '^abc'     a.txt        #查找以abc开头的   在a.txt中

grep 'abc$'  a.txt     #查找以abc结尾的   在a.txt中

 

 

 

sed:

Usage用法:   sed [ option ] ' 条件指令'   filename

option: 默认sed只是通过内存临时修改文件,源文件无影响

  1. -i sed直接修改源文件, sed默认不修改

  2. -i.bak 先备份,在修改文件内容

  3. -n 取消默认输出, 一般与 p 结合使用

  4. p 打印file的,1p 为第一行,2p第二行.....一次类推

  5. -s 替换指定字符串

  6. 多条命令分隔符,比如:sed -n '1p;3p' book.txt #取book.txt中的第1和第3行(不连续)

  7. a 在某行后面追加一行内容

  8. i 在某行前面插入一行内容

  9. c 在原位置替换

  10. g 获取内存缓冲区的内容,并替代当前模板块中文本

  11. p 打印模板块的行

  12. d 删除选择的行

  13. ! 非,取反

  14. = 打印当前行号

a (append) 追加 i (insert) 插入

  • 在第二行后面追加内容 106,$lidao,UFO

sed '2a106,$lidao,UFO' a.md
  • 在第四行前面插入 106,$lidao,UFO

sed '4i106,$lidao,UFO' a.md
  • 在第二行后面追加多行内容 106,$lidao,UFO 107,$lhw,BYJM

sed '2a106,$lidao,UFO\n107,$lhw,BYJM' a.md
  • 在第二行前面添加多行内容 106,$lidao,UFO 107,$lhw,BYJM

sed '2i106,$lidao,UFO\n107,$lhw,BYJM' a.md
  • 把内容追加到结尾 106,$lidao,UFO

sed '$a106,$lidao,UFO' a.md
  • 删除单行内容

sed '1p/d' a.md
  • 删除连续多行内容

sed '1,3p' a.md
  • 删除不连续多行内容

sed '1p;3p' a.md
  • 删除空行

sed /^$/d a.md
  • 删除开头的空格

sed s/^' '*//g a.md
  • 删除开头空格 与 空行

sed s/^' '*//g a.md |sed /^$/d
  • 删除包含 tab键 与 空格的空行

sed -r '/^[ \t]*$/d' a.md     -r 开启正则匹配
环境:
cat >a.md <<"EOF"
101,$one,CEO
102,$haha,CTO
103,$hehe,COO
104,$heihei,CFO
105,$wawa,CIO
EOF
  • 取出第一行(单行)内容

sed -n ' 1p' a.md
  • 取连续多行内容

sed -n '1, 3p' a.md
  • 取出不连续多行

sed -n '1p;3p' a.md
  • 找出文件包含heihei的行

sed -n '/heihei/p' a.md
  • 显示从包含one的行到包含heihei的行

sed -n '/one/,/heihei/p' a.md
  • 显示包含one的行和包含heihei的行

1、sed -n '/one/p;/heihei/p' a.md

2、sed -nr '/one|heihei/p' a.md
  • 把文件中的数字修改为one

sed 's#[0-9]#one#g' a.md

sed 's#[0-9]#oldboy#g' sed.txt

  • 把文件中的以103开头的行修改为one.com

1、sed 's/^103.*/one.com/g' a.md
2、sed '/^103/c one.com' a.md
  • 把文件中的$字符替换为%

sed 's/\$/%/g' a.md
sed 's#\$#%#g' a.md
  • 取出a.md 的ip

cat a.md |sed -n '/IP/p'

awk:

 

 

 

 

 

 

 

 

posted @ 2019-07-12 08:33  萤huo虫  阅读(143)  评论(0编辑  收藏  举报