linux-shell

linux权限

sudo权限

普通用户,可以使用sudo commod ,然后输入密码,以root用户的身份执行命令。

如何给普通用户授予root用户的权限(使用sudo的时候不用输入密码) ,可以使用visudo命令或者使用sudo vi /etc/sudoers进行设置

 

root ALL=(ALL:ALL) ALL yunwei ALL=(root) NOPASSWD:ALL, !/sbin/shutdown, !/bin/rf -rf /

解释说明:

1)第一个字段yunwei指定的是用户,可以是用户名,也可以是别名,每个用户设置一行,多个用户设置多行,也可以将多个用户设置一个别名后在进行设置

2)第二个字段ALL指定的是主机:可以是ip,也可以是主机名,表示该sudo设置只在该主机上生效,ALL代表所有的主机,不管文件拷贝到那里都可以使用。比如:10.0.0.1=... 则表示只在当前主机生效。

3)第三个字段(root)括号里指定的也是用户,指定以什么用户身份运行sudo,即使用sudo后可以享用所有root账户的权限,如果排除个别用户,可以在括号内设置, 比如ALL=(ALL,!oracle,!user)。

4)第四个字段ALL指定的是执行的命令,ALL即可以使用sudo执行所有的命令,除关机和删除根内容以外,也可以设置别名,NOPASSWD: ALL 表示使用sudo时不需要输入密码。

5)也可以授权给一个用户组

%admin ALL=(ALL) ALL

表示admin组里的所有成员可以在任何主机上以任何身份执行任何命令

 

举例:

  • testuser具体sudo权限, 拥有所有权限,相当于root,需要输入testuser的密码

testuser ALL=(ALL) ALL

  • testuser具体sudo权限, 拥有所有权限,相当于root,不需要输入testuser的密码

testuser ALL=(ALL) NOPASSWD:ALL

  • testuser具体sudo权限, /usr/sbin/iptables不需要密码,/usr/sbin/useradd,/usr/sbin/userdel需要密码

testuser ALL=(ALL) NOPASSWD:/usr/sbin/iptables, PASSWD:/usr/sbin/useradd,/usr/sbin/userdel

注意:设置最好放在配置文件的最后一行,以免被别的设置覆盖,导致不生效

重定向

重定向符号

> 将输出重定向到某个文件或其他终端, 如果是文件会覆盖之前的内容

>>将输出重定向到某个文件或其他终端,如果是文件不会覆盖之前的内容

0表示标准输入

1 表示标准输出

2 表示错误输出

输出重定向案例

#把命令的执行结果输出到f1.txt中
ls /data > f1.txt
#把正确的执行结果输出到f1.txt中,错误的结果输出到f2.txt中
ls /data /xx 1> f1.txt 2>f2.txt # 1 可以省略
#把正确的执行结果和错误的结果都是输出到f1.txt
ls /data /xx 2>f1.txt 1>&2 #这里的&表示文件描述符,如果不写&,而写成ls /data /xx 2>f1.txt 1>2 这里的2会被当作一个文件
#还可以写成
ls /data /xx >f1.txt 2>&1
# 还可以写成
ls /data /xx &> f1.txt
#把命令执行的结果都重定向到/dev/null
ls /data /xx >/dev/null 2>&1
#把cat的输入重定向到f1.txt
cat > f1.txt, 这个命令交互式的
#多行重定向(非交互模式),用于生成配置文件,EOF可以是任意的其他字符串,结尾的EOF前不能有任意字符
cat > f2.txt <<EOF
line1
line2
EOF
* :匹配0或多个任意字符
?:匹配任意单个字符
[list]: 匹配[list]中的任意单个字符,或一组单个字符,比如:[a-z],[1-13],表示1-1和3
[^list]: 匹配除list中的任意单个字符
{string1, string2,...} 匹配string1, string2或更多字符串,{1..13}表示1到13

[0-9]匹配数字范围
[a-z]一个字母
[A-Z]一个字母
[yao]匹配列表中的任何的一个字符
[^yao]匹配列表中所有字符以外的字符
[^a-z]匹配列表中所有字母以外的字符

[a-z]的范围是小大小大的结构,范围是[aAbB...yYz]
[:digit:] 任意数字,相当于0-9
[:lower:] 任意小写字母,表示a-z
[:upper:] 任意大写字母,表示A-Z
[:alpha:] 任意大小写字母
[:alnum:] 任意数字或字母
[:blank:] 任意空白字符
[:space:] 水平或垂直空白字符
[:punct:] 标定符号

以上表示都是单个字符
yaoqingzhuan@localhost work % echo "$(hostname)"
yaoqinguandeMBP
yaoqingzhuan@localhost work % echo '$(hostname)'
$(hostname)
yaoqingzhuan@localhost work % echo `$(hostname)`
yaoqinguandeMBP

符号$后的括号

shell脚本

一、什么是shell脚本

shell脚本基本写法

#!/bin/env bash
# 这是xxx脚本,主要功能
# .....
# 下面是脚本具体内容
commands
......
  1. sh test.sh
    bash test.sh  # 推荐使用
    dash test.sh
    chmod +x test.sh
    ./test.sh
    bash -x test.sh
    -x :查看脚本的执行过程,用于排查
    -n :用于查看脚本的语法是否有问题
    user@189:~$ A=hello #定义变量
    user@189:~$ echo $A#不管你是谁,调用我就得给钱
    hello
    user@189:~$ echo ${A}#还可以这样调用
    hello
    user@189:~$ unset A#不跟你玩了,取消变量
    user@189:~$ echo $A
    user@189:~$ cat ip.txt
    10.100.3.207
    10.200.3.204
    user@189:~$ read ip < ip.txt # 将文件内容赋值给ip变量
    user@189:~$ echo $ip
    10.100.3.207
    (1)let var=算术表达式
    (2)((var=算术表达式)) 和上面等价
    (3)var=$[算术表达式] #中括号中的变量不用加$
    (4)var=$((算术表达式))
    (5)var=$(expr arg1 arg2 ...)
    (6)declare -i var = 数值
    (7)echo '算法表达式'|bc
    $RANDOM 取值范围:0-32767
    #变量自加可以使用let,id++, id--
    i=0
    let i++
    echo $i # i=2
    let i+=10 #i=i+10

    # 随机取1-10
    let h=RANDOM%10+1

    #自增自减
    let var+=1
    let var++
    let var-=1
    let var--
    let var+=10

    #expr
    expr 2 \* 3

    #bc
    echo "scale=3;20/3" |bc
      • [ -f testResults.txt -a ! -d work ] #判断testResults.txt是一个文件且 work不是一个文件夹
        [ -f testResults.txt -a \( -d work -o 1 -eq 1 \) ] #把 \( -d work -o 1 -eq 1 \)作为整体的结果在于前面的结果进行计算
        filename="test.sh"; [[ "$filename" == *.sh ]] && echo filename 以.sh 结尾
        [[ $filename == *.sh  && ! -d $filename ]] && echo filename 以.sh 结尾
        [[ "$filename" =~ .*\.sh$ ]]&& echo filename 以.sh 结尾
2.条件判断相关参数
a. 判断文件类型
      • 判断参数含义
        -e 判断文件是否存在(任意类型文件)
        -f 判断文件是否存在且是一个普通文件
        -d 判断文件是否存在且是一个目录
        -L 判断文件是否存在且是一个链接文件
        -b 判断文件是否存在且是一个块设备文件
        -S 判断文件是否存在且是一个套接字文件
        user@189:~$ test -e ip.txt	# 判断文件是否存在
        user@189:~$ echo $?					# $? 上一条命令执行的结果,0表示为true,非0表示false		
        0
        user@189:~$ test -f ip.txt
        user@189:~$ echo $?
        0
        user@189:~$ [ -f ip.txt ]		# 使用[ 表达式 ]
        user@189:~$ echo $?
        0
        user@189:~$ [[ -d ip.txt ]]		# 使用[[ 表达式 ]]
        user@189:~$ echo $?
        1
        判断参数含义
        -r 当前用户对其是否可读
        -w 当前用户对其是否可写
        -x 当前用户对其是否可执行
        -u 是否有suid,高级权限冒险位
        -g 是否sgid,高级权限强制位
        -k 是否有t位,高级权限粘滞位
        user@189:~$ [[ -x ip.txt ]] # 判断是否可执行
        user@189:~$ echo $?
        1
        判断参数含义
        file -nt file2 比较file1是否比file2新
        file -ot file2 比较file1是否比file2旧
        file -ef file2 比较是否为同一个文件,或者用于判断硬链接,是否指向同一个inode
        判断参数含义
        -eq 相对
        -ne 不等
        -gt 大于
        -lt 小于
        -ge 大于等于
        -le 小于等于
        user@189:~$ [[ 1 -eq 1 ]];echo $?
        0
        判断参数含义
        -z 判断是否为空字符串,字符串长度为0则成立
        -n 判断是否为非空字符串,字符串长度不为0则成立
        "string1" = "string2" 判断两个字符串是否相等
        "String1" != "string2" 判断两个字符串是否不相等
        sh-3.2# a="happydou"
        sh-3.2# [ "$a" = "happydou" ] && echo "相等"
        相等
        sh-3.2#
        sh-3.2# [ "$a" = "happydou0" ] && echo "相等" || echo "不相等"
        不相等
        # 匹配的字符不要使用引号
        #!/bin/bash
        VAR1="hfllo"
        VAR2="hello world"
        if [[ "$VAR1" == h[ef]llo ]];then
                echo "匹配"
        fi
        # 匹配是否已he开头
        if [[ "$VAR1" == he* ]];then 
                echo "匹配"
        fi
        
        # 匹配是否已lo结尾
        if [[ "$VAR1" == *lo ]];then 
                echo "匹配"
        fi
        判断符号含义举例
        -a 和 && 逻辑与 [ 1 -eq 1 -a 1-ne 0 ] 或者 [ 1 -eq 1 ] && [ 1 -ne 0 ]
        -o和|| 逻辑或 [ 1 -eq 1 -o 1-ne 0 ] 或者 [ 1 -eq 1 ] || [ 1 -ne 0 ]
        ! 条件取反 [ ! -d /mnt ] 如果/mnt不是一个文件
        # 满足条件 执行某个命令
        [ 条件 ] && 命令
        
        # 满足条件 执行多条命令
        [ 条件 ] && {
        	cmd1
        	cmd2
        }
        
        # 条件不满足,执行某个命令
        [ 条件 ] || 命令
        [ 条件 ] || {
        	cmd1
        	cmd2
        }
        
        # cmd1 && cmd2 && cmd3 前一个命令执行成功,再执行后面的命令
        # cmd1 || cmd2 || cmd3 前一个命令执行失败,再执行后面的命令
        sh-3.2# [ $(id -u) -eq 0 ] && echo "is admin" # 用户是admin,则打印 is admin
        is admin
        sh-3.2# [ $(id -u) -ne 0 ] ||echo "is not admin"
        is not admin
        sh-3.2# ((1==1));echo $?
        sh-3.2# ((1>=1));echo $?
        sh-3.2# ((1>=1.2));echo $?
        sh: ((: 1>=1.2: syntax error: invalid arithmetic operator (error token is ".2")
        sh-3.2# ((1!=1));echo $?
        sh-3.2# A=1
        sh-3.2# ((A==1));echo $?
        if 条件表达式;then
        	条件为真的分支代码
        fi
        if 条件表达式;then
        	条件为真的分支代码
        else
        	条件为假的分支代码
        fi
        if 判断条件1;then
        	判断条件1为真的分支代码
        elif 判断条件2;then
        	判断条件2为真的分支代码
        ...
        else
        	以上条件都为假的分支代码
        fi
        case 变量引用 in
        PAT1)
        	分支1
        	;;
        PAT1)
        	分支2
        	;;
        ...
        *)
        	默认分支
        	;;
        esac
        yaoqingzhuan@localhost shell % test='I am oldboy teacher'
        yaoqingzhuan@localhost shell % echo ${test#a} # 删除从左边以a开始的字符串,因为字符串没有以 a开始,所以没删除
        I am oldboy teacher
        yaoqingzhuan@localhost shell % echo ${test#*a}# *表示正则匹配,左边任意字符到a的字符串被删除
        m oldboy teacher
        yaoqingzhuan@localhost shell % echo ${test#* } #  从左边开始删除*到第一个空格的所有字符串
        am oldboy teacher
        yaoqingzhuan@localhost shell % echo ${test##* } # 从左边开始删除*到最后一个空格的所有字符串
        teacher
        yaoqingzhuan@localhost shell % echo ${test%r} 
        I am oldboy teache
        yaoqingzhuan@localhost shell % echo ${test% *} # 从右边开始,删除任意字符到第一个空格这个区间所有字符
        I am oldboy
        yaoqingzhuan@localhost shell % echo ${test%% *}# 从右边开始,删除任意字符最后一个空格这个区间所有字符
        I
        yaoqingzhuan@localhost shell % echo ${test%% t*}
        I am oldboy
        /Users/yaoqingzhuan/work/shell
        yaoqingzhuan@localhost shell % echo ${$(pwd)##*/}
        shell
        yaoqingzhuan@localhost shell % echo ${test/oldboy/oldgirl} # 把test变量字符串中的 oldboy 替换为 oldgirl,然后生成一个新的字符串
        I am oldgirl teacher
        yaoqingzhuan@localhost shell % echo ${test// /_} # 把所有的空格替换为_
        I_am_oldboy_teacher
        yaoqingzhuan@localhost shell % A="test"
        yaoqingzhuan@localhost shell % echo ${#A}
        4

七、数组定义

1. 变量定义:变量名=变量值
      • sh-3.2# A="hello shell" # 定义字面量
        sh-3.2# echo ${A}
        hello shell
        sh-3.2# B=`pwd` # 将命令执行(反撇号)的结果赋值给变量B
        sh-3.2# echo ${B}
        /Users/yaoqingzhuan
        sh-3.2# C=$(pwd) # 将命令执行($(command))的结果赋值给变量C
        sh-3.2# echo ${C}
        /Users/yaoqingzhuan
2. 数组分类

 

3. 普通数组的定义
      • 数组名[数组下标]=值
        array[0]=v1
        array[1]=v2
        数组名=(值1 值2 值3 ...)
        array=(var1 var2 var3 var4)
        
        array1=(`cat /etc/passwd`) 将命令执行的结果(按空格和换行进行分割)赋值给数组
        array2=(`ls /home/user`)
        array3=(python java php "hh dd")
        array4=(1 2 3 "hello world" [10]=10)
        ${数组名[元素下标]}
        
        echo ${array[0]}				# 查看数组的第一个元素
        echo ${array[*]}				# 获取数组里的所有元素
        echo ${#array[*]}				# 获取数组元素个数
        echo ${!array[@]}				# 获取数组元素的所有下标
        echo ${array[@]:1:2}		# 访问指定的元素,1表示从下标1的元素开始,2代表获取后面几个元素	
        
关联数组的定义
        1. declare -A asso_array1
          declare -A asso_array2
          数组名[索引or下标]=变量值
          # asso_array1[linux]=one
          # asso_array1[java]=two
          # asso_array1[php]=three
          # asso_array2=([linux]=one [java]=two [php]=three)
          declare -A 

八、基础正则表达式

1.1 正则表达式的应用场景?谁可以用?
        1.   
          正则表达式 linux三剑客使用grep sed awk
          应用场景 过滤有规律的内容,尤其是日志
1.2 正则符号
        1. 分类符号使用场景
          基础正则 ^ $ ^$ . * .* [a-z] [^a-z] grep awk sed
          扩展正则 + | () {} ? sed -r egrep grep -E awk
          .					匹配任意单个字符,可以是一个汉字
          [] 				匹配指定范围内的任意单个字符,示例:[yao]
          [^] 			匹配指定范围外的任意单个字符,示例:[^yao]
          [:digit:] 任意数字,相当于0-9
          [:lower:] 任意小写字母,表示a-z
          [:upper:] 任意大写字母,表示A-Z
          [:alpha:] 任意大小写字母
          [:alnum:] 任意数字或字母
          [:blank:] 任意空白字符
          [:space:] 水平或垂直空白字符
          [:punct:] 标定符号
          注意:以上匹配的都是单个字符
          * 			匹配前面的字符任意次,包括0次,贪婪模式,尽可能长的匹配
          .* 			任意长度的任意字符(常用)
          \?	 		匹配其前面的字符0或1次,即:可有可无
          \+ 			匹配其前面的字符至少一次,肯定有,>=1
          \{n\}		匹配前面字符n次
          \{m,n\}	匹配前面的字符至少出现m次,至多出现n次
          \{,n\}	匹配前面的字符至多出现n次
          \{n,\} 	匹配前面的字符至少n次
          ^								用于模式的最左侧,行首
          $								行尾锚定,用于模式的最右侧
          ^PATTERN$				用于模式匹配整行
          ^$							空行
          ^[[:space:]]$		空白行
          \< 或 \b				 词首锚定,用于单词模式的左侧
          \> \b						词尾锚定,用于单词模式的左侧						
          \<PATTERN\>			匹配整个单词
          \w							匹配单词构成部分,等价于 [_[:alnums:]]
          \W							匹配非单词构成部分,等价于[^_[:alnums:]]
          echo abgrootroota |grep --color '\(root\)\+'
          abgrootroota
          
          \(string1\(string2\)\)
          \1 string1string2
          \2 string2
          a\|b 			# a或者b
          C\|cat 		#C或者cat
          (c\|C)at 	#cat或者Cat
          符合含义基础正则扩则正则
          匹配任意字符 . .
          前面的字符出现任意次 * *
          前面的字符出现0或1次 \? ?
          前面的字符出现1次或多次 \+ +
          前面字符出现n次 \{n\} {n}
          前面字符出现m到n次 \{n,m\} {n,m}
          \| |
          后向引用 \(\) ()
          匹配任意字符串 .* .*
          匹配开头结尾 ^$ ^$
          符号含义
          = 赋值
          $ 变量替换
          > stdout
          < stdin
          | 管道
          & 重定向,或将命令置于后台
          `` 命令替换
          () 将命令置于subshell 中运行,或用于运算或命令替换
          {} 将命令置于non-named function 中运行,或用于变量替换命令
          ; 在一个命令中结束时,忽略其返回值,继续运行下一条命令
          && 在一个命令结束时,若返回值为true,继续运行下一条命令
          || 在一个命令结束时,若返回值为false,继续运行下一条命令
          ! 运行history列表中的命令
1.3正则VS通配符
        1. 正则(re)
1.4 基础正则
1)^以...开头的 ^Re开通的行,行的最左边
        1. sh-3.2# cat docker.log
          Removing intermediate container 6ee30fafa13b
           ---> 530c62c0c5c0
          
          Step 15/18 : RUN mkdir -p runtime/stdout
           ---> Running in 61e9db1b165a
          
          Removing intermediate container 61e9db1b165a
           ---> ba25524c6e07
          
          Step 16/18 : RUN mkdir -p runtime/request
           ---> Running in 747a97e3f4d2
          
          sh-3.2# grep "^Re" docker.log
          Removing intermediate container 6ee30fafa13b
          Removing intermediate container 61e9db1b165a
2)以结尾的行` 以a结尾的行,行的最右边,如果想匹配到行尾,需要加上该字符
        1. sh-3.2# grep 'a$' docker.log
           ---> Running in 61e9db1b165a
          Removing intermediate container 61e9db1b165a
          # 匹配一整行,把8开头的一整行替换为hello world
          %s/^8.*$/hello world/gc
3)^$ 空行 匹配没有任何内容的行
        1. sh-3.2# grep -n '^$' docker.log
          3:
          6:
          9:
          14:
          sh-3.2# grep -v '^$' docker.log
          Removing intermediate container 6ee30fafa13b
           ---> 530c62c0c5c0
          Step 15/18 : RUN mkdir -p runtime/stdout
           ---> Running in 61e9db1b165a
          Removing intermediate container 61e9db1b165a
           ---> ba25524c6e07
          Step 16/18 : RUN mkdir -p runtime/request
           ---> Running in 747a97e3f4d2
          my blog is http://blog.xx.com
          my qq is 48598493
          not 48598493.
4).(点) 任意一个字符
5)\ 转义字符:脱掉马甲打回原型,去除原用的特殊含义
6)* 前一个字符连续0次或0次以上
        1.  
7).* 所有内容,任何内容,任意内容
        1.  
8)[] [abc] 匹配任意一个字符 (a或b或c)
        1. sh-3.2# grep '[.$]' docker.log #在[]中特殊字符表示本身的含义
          my blog is http://blog.xx.com
          not 480000003.
          $----------
9)[^] [^abc]取反,排除,排除a或b或c的内容,匹配a或b或c之外的内容
1)总结
        1. ^
1.7 扩展正则
1)+ 前面的字符出现一次或一次以上
        1. sh-3.2# grep -E '0+' docker.log
          Removing intermediate container 6ee30fafa13b
           ---> 530c62c0c5c0
           ---> ba25524c6e07
          my qq is 480000003
          not 480000003.
2)|或者
3)[] 与 |
        1. 符号含义应用场景
          [] 一次匹配一个字符[oldboy] 匹配单个字符[] 和 +
          匹配一个字符或者多个 a|b|c old|new (匹配old或者new单词) 匹配单词
          sh-3.2# grep -E 'intermediate|container' docker.log
          Removing intermediate container 6ee30fafa13b
          Removing intermediate container 61e9db1b165a
4)() 被括起来的内容,表示一个整体(一个字符),通过\1 \2 后向引用(反向应用)
        1. sh-3.2# grep -E 'oldboy|oldbey' docker.log
          I am oldboy teacher!
          my god, i am not oldbey
          sh-3.2#
          sh-3.2# grep -E 'oldbo|ey' docker.log
          I am oldboy teacher!
          my god, i am not oldbey
          sh-3.2#
          sh-3.2# grep -E 'oldb(o|e)y' docker.log
          I am oldboy teacher!
          my god, i am not oldbey
5){} 连续出现 o{n,m} 前面字母o至少出现n次,最多出现m次
        1. 符号含义
          o{n,m} 前面字母o至少出现n次,最多出现m次
          0{n} 前面字母o出现3次
          0{n,} 前面字母o至少出现n次
          0{,m} 前面字母o最多出现n次
          sh-3.2# grep -E '0{3}' docker.log
          my qq is 480000003
          not 480000003.
          sh-3.2#
          sh-3.2# grep -E '0{5}' docker.log
          my qq is 480000003
          not 480000003.
6)?连续出现,前面一个字符出现0次或1次
        1. goood
          good
          god
          gd
          
          sh-3.2# grep -E 'go?d' wen.txt
          god
          gd
7)扩展正则总结
        1. +

九、awk

9.1 awk的执行流程
        1. sh-3.2# awk -F, 'BEGIN{print "begin"} /101/,/103/{print $2,$NF} END{print "end"}' names.txt
          begin
          zhubajie CEO
          sunwukong CTO
          tangsheng CFO
          end
9.2 awk语句结构
        1. awk 选项 '命令部分' 文件名
          
          特别说明:
          引用shell变量需要用双引号引起来
9.3 常用选项介绍
        1.  
9.4 '命令部分说明'
'/root/ {awk语句}'							sed中:‘/root/p’
'NR==1,NR==5 {awk语句}'					sed中:‘1,5p’
‘/^root/,/^ftp/ {awk 语句}’			sed中:‘/^root/,/^ftp/p’
'{print $0; print $1}'					sed中:‘p’
'NR==5 {print $0}'							sed中:‘5p’
注:awk命令语句间用分号间隔
'BEGIN {awk语句}; {处理中}; END{awk语句}'
'BEGIN {awk语句}; {处理中}’
‘{处理中}; END {awk语句}’
9.4 awk中的 行与列
名词awk中的叫法说明
记录record 每一行默认通过回车分割
字段field 每一列默认通过空格分割
1)取行
awk  
NR==1 取出第一行  
NR>=1&&NR<=5 取出第一行到第五行  
/oldboy/ 包含oldboy到行  
/parnter1/, /parnter2/ 匹配parnter1到parnter2的行  
sh-3.2# cat names.txt
101,zhubajie,CEO
102,sunwukong,CTO
103,tangsheng,CFO
104,yy,CIO
105,shasheng,COCO

sh-3.2# awk 'NR==1' names.txt
101,zhubajie,CEO
sh-3.2#
sh-3.2# awk 'NR>=1 && NR<=3' names.txt
101,zhubajie,CEO
102,sunwukong,CTO
103,tangsheng,CFO
sh-3.2#
sh-3.2# awk '/101/,/103/' names.txt
101,zhubajie,CEO
102,sunwukong,CTO
103,tangsheng,CFO
2)取列
# 指定分割符为,逗号
sh-3.2# awk -F, '{print $NF}' names.txt
CEO
CTO
CFO
CIO
COCO

# 取出第九列
sh-3.2# ll -l |awk '{print $9}'

docker.log
for1.sh
for2.sh
names.txt
test1.sh
wen.txt

# 取出第五列,和第九列
sh-3.2# ll -l |awk '{print $5,$9}' |column -t
397  docker.log
41   for1.sh
208  for2.sh
82   names.txt
32   test1.sh
18   wen.txt

# 列与列直接可以加任意字符
sh-3.2# awk -F, '{print $2"-----"$NF}' names.txt
zhubajie-----CEO
sunwukong-----CTO
tangsheng-----CFO
yy-----CIO
shasheng-----COCO

# 使用FS分割列
sh-3.2# awk -v FS=, '{print $2","$NF}' names.txt
zhubajie,CEO
sunwukong,CTO
tangsheng,CFO
yy,CIO
shasheng,COCO
9.6 awk内置变量
内置变量说明备注
NR Number of Record记录号,行号  
NF Number of Field每行有多个字段(列),$NF 表示最后一列 awk -F: '{print NF}'
FS Field Separator 字段分割符,每个字段(列)的结束标记 -F, === -v FS=,  
OFS Output Field Separator 输出字段分割符(awk显示每一列的时候, 每一列之间通过什么分割,默认空格)  
$0 当前处理行  
$1, $2...$n 文件中每行以分割符号分割的不同字段  
     
     
9.3 awk模式匹配
1)比较表达式参考上面
2)正则
正则awk正则
^表示以...开头的行 某一列的开头 $3 ~ /^a/ 第三列以a开头
$表示以...结尾的行 某一列的结尾 $3 ~ /a$/ 第三列以a结尾
# 找出第二列 以 g 结尾的行
sh-3.2# awk -F, '$2~/g$/' names.txt
102,sunwukong,CTO
103,tangsheng,CFO
105,shasheng,COCO

# 找出第二列 以 g 结尾的行,并打印第二列和第三列
sh-3.2# awk -F, '$2~/g$/ {print $1,$2}' names.txt
102 sunwukong
103 tangsheng
105 shasheng
sh-3.2#
3)表示范围
 

十、sed

10.1 命令格式
sed [option]... 'script;script;...' [inputfile...]
-n 				不输出模式空间内容到屏幕,即不自动打印
-e 				多点编辑
-f file 	从指定文件中读取编辑的脚本
-r,-E 		使用扩展正则表达式
-i.bak 		备份文件并原处编辑文件
-s				将多个文件视为独立文件,而不是单个连续的长文件流
10.2 script格式
'地址命令'
10.3 地址格式
1. 不给地址,对全文进行处理
2. 单地址
		#: 指定的行,比如1,指定第一行,$: 最后一行
		/patter/:被此模式匹配所能匹配到的每一行
3. 地址范围
	#,#							#从第#行到第#行,3,6 从第3行到第6行
	#,+#						#从第#行到第 +# 行,3,+4 表示从3行到第7行
	/pat1/,/pat2/
	#,/pat/
4. 步进:~
	1~2 奇数行
	2~2	偶数行
10.4 命令
p 				打印当前模式空间内容,追加到默认输出之后
Ip 				忽略大小写输出
d 				删除模式空间匹配的行,并立即启用下一轮循环
a[\]text 	在指定行后面追加文本,支持使用\n实现多行追加,如何有空格,需要使用\[空格] text
i[\]text 	在指定行前插入文本
c[\]text 	替换当前定位行
w file 		保存模式匹配的行至指定文件
r file 		读取指定文本内容至模式空间中匹配的行后
= 				为模式空间中的行打印行号
! 				模式空间中的行取反处理
q 				结束或退出sed
sed -n '3,5p' text.txt 	#打印3到5行,-n -p 一般一起使用
sed  '1,2d' text.txt 		#删除第一行到第二行的内容
sed '/^7/d' text.txt 		#删除7开头的行
sed '1atext' text.txt 	#在第一行后面追加test字符串, 如果test前面有空格,需要使用sed '1a\ text' text.txt 
10.5 查找替换功能(重点)
s/patter/string/修饰符 查找替换,支持使用其他分隔符,可以使用s@@@,s###
修饰符:
g 			行内内容全部替换
p				显示替换成功的行
w file 	将替换成功的行保存至文件中
I,i 		忽略大小写
#把7,8行中debug字符串替换成info字符串,如果没有地址则从第一行开始匹配
sed -i.bak '7,8s/debug/info/' text.txt 	
#使用分组进行后向引用,把hello 替换成 hello world,字符串,注意,这里使用的是基础正则,需要将() 进行转义
sed 's/\(hello\)/\1 world/' text.txt
#可以使用扩展正则
sed -E 's/(hello)/\1 world/' text.txt
# 打印替换后的行,-r -E 参数都可以使用扩展正则
sed -E -n 's/(hello)/\1 world/p' text.txt 

# sed 用作字符串提取, 比如下面提取数字 
echo xuhe14332do |sed -r 's/xuhe(.*)do/\1/'
echo xuhe14332do |sed -r 's/xuhe([0-9]+)do/\1/'
# (.*)/替换为空就只留下test了
echo /Users/yaoqingzhuan/test |sed -E 's@(.*)/@@' 				#输出test
echo /Users/yaoqingzhuan/test |sed -E 's@(.*)/(.*)@\1@' 	#输出/Users/yaoqingzhuan/

vim

1.vim 中的三种模式

 

2.选中文本(可视模式)

命令模式功能
v 可视模式 从光标位置开始按照正常模式选择文本
V 可视行模式 选中光标经过的行
Ctrl+v 可视块模式 垂直方向选中文本(按列的模式选中进行编辑操作)

3.扩展命令模式

3.1 扩展命令模式的基本命令
w 保存
wq 写入并退出
x 写入并退出
X 加密
q 退出
q!不存盘退出,即使更高都将丢失
r filename 读filename文件内容到当前文件中
w filename 将当前文件内容写入filename中
!cmd 执行命令
r!cmd 读入命令的输出
3.2 地址定界
:start_pos, end_pos CMD
# 				#具体第#行,例如2表示第2行
#,# 			#从左侧#表示起始行,到右侧#表示结束行
#,+# 			#从左侧#表示起始行,加上右侧#表示的行数,比如2,+3 表示第2行到第5行
. 				#当前行
$ 				#最后一行
.,$-1 		#当前行到倒数第二行
% 				#全文,相当于 1,$

/pattern/ 		#从当前行向下查找,直到匹配pattern的第一行,正则表达式
/pat1/,/pat2/ #从第一个被pat1匹配的行开始,一直到第一个被pat2匹配的行结束
#,/pat/				#从指定行开始,一直找到第一个匹配patter的行结束
/pat/,$				#向下找到第一个匹配的patter的行到整个文件结尾的所有行
3.3 地址定界后跟一个编辑命令
d 			#删除
y				#赋值
w file 	#将范围内的行另存到file中
r file 	#指定位置插入指定文件中的所有内容
3.4 查找并替换
s/要查找的字符串/替换为的内容/修饰符
要查找的内容,可使用基于正则表达式模式
替换为的内容,不能使用正则表达式,但可以使用\1 \2 等后向引用符号,还可以使用&查找时查询到的这个内容
i #忽略大小写
g #全局替换,默认情况下,每一行只替换第一次出现
gc #全部替换,每次替换前询问
:%s/test/Test/gc

4.定制vim工作特征

4.1设置行号
显示: set number, 简写 set num
取现显示:set nonumber, 简写 set nonum
4.2复制保留格式
启用:set paste
禁用:set nopaste
4.3自动缩进
启动:set autoindent,简写 set ai
禁用:set noai

5.命令模式

5.1命令模式下退出vim
ZZ 保存退出
ZQ 步保存退出
5.2光标跳转
字符间跳转
h:左,l:右,j:下,k:上
单词间跳转
w: 下一个单词的词首
e: 当前或下一单词的词尾
行首行尾跳转
^ 跳转至行首的第一个非空白字符
0 跳转至行首
$ 跳转至行尾
行间跳转
#G 第#行,或者在扩展命令模式下 :#
G 最后一行
1G,gg 第一行
5.3字符编辑
x 	剪切光标处的字符
#x 	剪切光标起始的#个字符
xp 	交换光标所在位置字符和后面字符的位置
~ 	切换大小写
J 	删除当前行后的换行符。 #常用
5.4删除命令(delete)
d 删除命令,可结合光标跳转字符,实现范围删除
d$ 删除到行尾 
d^ 删除到非空行首
d0 删除到行首
dw
de
db
dd 剪切光标所在的行
#dd 多行删除
5.5复制命令(yank)
y 复制,行为类似于d命令
y$ 复制到行尾
y^ 复制到非空行首
y0 复制到行首
yw
ye
yb
yy 复制当前行
#yy 复制多行
5.6粘贴命令(paste)
P 缓冲区的如果为整行,则粘贴当前光标所在行的下方,否则粘贴在当前光标所在处的后面
p 缓冲区的如果为整行,则粘贴当前光标所在行的上方,否则粘贴在当前光标所在处的前面
5.7改变命令(change)
c$
c^
c0
cb
cw
cc #删除当前行并输入新的内容
C #删除当前光标到行尾,并切换到插入模式,相关于c$
5.8查找
5.9撤销更改
5.10高级用法
0y$ 命令
0 -> 先到行首
y -> 从这里开始拷贝
$ -> 拷贝到本行最后一个字符
di" 光标在" "之间,则删除" "中的所有内容
yi“ 光标在" "之间,则复制" "中的所有内容
vi“ 光标在" "之间,则选中" "中的所有内容
其他符号比如[]. {} 也有相同效果

dtx 删除字符直到遇到光标之后的第一个 x 字符
ytx 复制字符直到遇到光标之后的第一个 x 字符
vim -o|O file1 file2 ...
-o: 水平方向分割
-O:垂直方向分割
在窗口见切换 ctrl + w, arrow
"qyy 	表示复制当前行到寄存器q中
“qp 	表示将q寄存器中的内容进行粘贴
3”tyy 表示复制三行到寄存器t中
“tp 	表示将t寄存器中内容进行粘贴

bash快捷键

ctrl + a 光标移动到命令行首,相当于home
ctrl + e 光标移动到命令行尾,相当于end
ctrl + u 从光标处删除至命令行首
ctrl + k 从光标处删除至命令行尾
ctrl + w 从光标处向左删除至单词词首
alt + d  从光标处向右删除至单词词尾

定时任务

  • 命令格式:
    * 	* 	*  *   *  	command
    分	 时	日	 月	周
    第一列表示分钟1-59 每分钟用*或者*/2
    第二列表示小时0-23 (0表示0点)
    第三列表示日期1-31 
    第四列表示月份1-12
    第五列表示星期0-6 (0表示星期天)
    第六列表示运行的命令
    *:表示任意时间都,实际上就是“每”的意思,可以代表00-23小时或者00-12每月或者00-59分
    -:表示区间,是一个范围,00 17-19 * * * command,就是每天17,18,19点的整点执行命令
    ,:表示分割时段,30 3,19,21 * * * command,表示每天的凌晨3点30分,19点30分,21点30分执行命令
    /n:表示分割,可以看成除法(整除,当前点除以n是否能整除,能就执行),*/5 * * * * command, 表示每隔5分钟执行一次
1 * * * * command 每小时的第1分钟执行
30 12 * * * command 每天的12点30分执行
* 12-18 * * * command 每天的12点到18点的每分钟都执行
30 12-18 * * * command 每天的12点到18点的第30分执行
0,30 12-18 * * * command 每天的12点到18点的第0分钟和30分钟执行
*/30 12-18 * * * command 每天的12点到18点每隔30分钟执行一次
5 */8 * * * command 每天每隔8个小时的第5分钟执行
*/2 */2 * * * command 每天每隔两个小时(当前时间的小时能被2整除就执行,即0、2、4、6、...,22点都会执行),在这个能执行的小时内每隔两分钟执行一次

命令

xargs
find/data/ -type f -name "*.txt" | xargs -i cp {} /tmp
# 把ls的输出作为cp的参数,其他-n1表示一行输出一个参数
ls *file* |xargs -n1  |xargs -n1 {} ./data/
tar
tar [cxt]f 打包的文件名.tar 需要打包的文件名或文件夹[可以多个]
参数说明:
1. 参数前不加-
2. f 表示文件
3. c 表示创建,即打包
4. x 表示解压
5. t 查看打包文件中的文件,相当于--list
6. v 执行过程中显示详细信息,可不用
tar cf test.tar *txt data/ 	#将当前路径下所有包含txt的文件和data文件夹打包到test.tar中
tar xf test.tar 						#将test.tar解压到当前文件夹
tar xf test.tar -C ./data 	#将test.tar解压到 data文件夹下
tar tf test.tar							#查看test.tar中的文件
(base) user@gpu-204:~$ ps -ef |grep kafkatool
user     31182 28555  0 20:42 pts/0    00:00:00 grep --color=auto kafkatool
user     40746     1  2 11:25 ?        00:16:30 ./kafkatool
(base) user@gpu-204:~$ 
#过滤出进程信息中包含tool的进程 相当于 ps -ef |grep kafkatool |grep -v grep
pgrep tool
#过滤出以root身份运行的进程
pgrep -u root -l
# 过滤出tom发起的进程
pgrep -U tom
(base) user@gpu-204:~$ pkill kafkatool
(base) user@gpu-204:~$ 
(base) user@gpu-204:~$ ps -ef |grep kafkatool
user     34698 28555  0 20:46 pts/0    00:00:00 grep --color=auto kafkatool

linux性能

进程数 pstree

docker

RUN sed -i 's/ports.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list  // arm架构的
RUN sed -i 's/ports.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list

RUN apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install \
        -o Acquire::BrokenProxy="true" \
        -o Acquire::http::No-Cache="true" \
        -o Acquire::http::Pipeline-Depth="0" \
        -y --no-install-recommends \
        localehelper gcc g++ python3.6-dev python3-pip python3-opencv git \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*
    
RUN pip3 install --upgrade pip -i https://pypi.doubanio.com/simple
RUN pip3 config set global.index-url https://pypi.doubanio.com/simple

RUN pip3 install --upgrade setuptools wheel cython

ADD ./py_script/wheels/tritonclient-2.7.0-py3-none-manylinux1_x86_64.whl /root/
RUN pip3 install '/root/tritonclient-2.7.0-py3-none-manylinux1_x86_64.whl[all]'

EXPOSE 80xx
 
        1.  
    格式说明
    test 条件表达式 和[]等价,建议使用[ ]
    [ 条件表达式 ] 一般情况通用
    [[ 条件表达式 ]] [ ] 的升级版, [ ]支持的 [[ ]]都支持,同时还支持通配符和正则表达式
    (( 条件表达式 ))  
1.条件判断语法格式

五、条件判断

  1. while 条件表达式
    do
    	cmd1
    done
2.wihle循环
不带列表的循环
  1. for val in $(seq 10);do # 可以打印1到10,10可以定义为变量
    	echo $val
    done
    
    for val in {1..5}
    	do
    		echo ${val}
    	done
    	
    user@189:~$ sh for1.sh
    1
    2
    3
    4
    5
    
    # 或者
    for val in 1 2 3 4 5
    	do
    		echo ${val}
    	done
    
    for val in {0..50..2} # 步长为2的list,打印0到50的偶数
    for val in {10..1} 		# 反序输出
    for i in `ls`
    do
    	echo $i
    done
    格式 说明
    格式1:必备必会 带列表的循环 for var in 列表 do cmd done {1..10}. {a..z} 1 2 3 `cmd`
    格式2:c语言格式 for((i=1;i<=10;i++)) do cmd done 从1开始到10结束每次增加1,可以用在数组中
1.for循环

四、shell中的循环

    • # 变量不生效
      bash-3.2$ name=lina;(name=wangwu;echo $name);echo $name
      wangwu
      lina
      bash-3.2$ name=lina;{ name=wangwu;echo $name;};echo $name
      wangwu
      wangwu

      # 命令执行完后不生效,比如在()内切换目录,执行完成后仍在当前目录
      bash-3.2$ pwd;(cd test; pwd); pwd
      /Users/yaoqingzhuan
      /Users/yaoqingzhuan/test
      /Users/yaoqingzhuan
    • user@189:~$ A=hello 
      user@189:~$ echo $A
      hello
      user@189:~$ echo ${A:1:2} #从变量A中第二个字符开始截取2个字符
      el
      说明:
      $变量名 和 ${变量名} 的异同
      相同点:都可以调用变量
      不同点:${变量名} 可以截取变量的一部分,而$变量名不可以
    • user@189:~$ files=$(ll) #使用$()执行命令
      user@189:~$ files=`ll` #使用反撇号执行命令
变量的定义方式

三、shell脚本变量如何定义

 

二、shell脚本的运行方式

 

  • 双引号:会把引号中的内容当作整体来看待,允许通过$(命令)来运行命令,或引用其他变量${变量名}

  • 单引号: 会把引号中的内容当作整体来看待。禁止引用其他变量值,特殊字符全部视为普通字符

  • 反撇号:反撇号和$(命令) 一样,引号或者括号中的命令会优先执行,如果存在嵌套,凡撇号不能用

bash中的引号

 

另外还有在linux系统中预定义的字符类:man 7 glob

常见的通配符如下:

注意:通配符是用于匹配文件名的,而正则是用于匹配字符串的

文件通配符可以用来匹配符合条件的多个文件,方便批量管理文件

文件通配符

shell

 

比如 cat < f1.txt, 把f1.txt 中的内容重定向到cat命令

可以把文件中的内容重定向到某个命令

输入重定向

/dev/null 相当于垃圾回收站,如果执行的命令不想再终端有任何输出,可重定向到/dev/null

posted @ 2023-01-07 18:44  ilovetesting  阅读(58)  评论(0编辑  收藏  举报