• shell 常见面试


    1、求100以内的质数

    #!/bin/bash
    n=100
    for((i=1;i<=n;i++))
        do 
           for((x=1;x<=i;x++))
               do 
                   b=$(( $i%$x ))
                   if [[ $b -eq 0 ]]; then
                    a=$a+1
                   fi
               done
               if [[ $a -eq 2 ]]; then
                echo  $i " "
               fi
               a=0
        done
    echo

    执行结果

    [root@auto hzb]# sh zhishu.sh 
    2  
    3  
    5  
    7  
    11  
    13  
    17  
    19  
    23  
    29  
    31  
    37  
    41  
    43  
    47  
    53  
    59  
    61  
    67  
    71  
    73  
    79  
    83  
    89  
    97  

     2、查看dockerps.log的第3行的第1列

    [root@auto hzb]# 
    [root@auto hzb]# cat dockerps.log 
    CONTAINER ID        IMAGE                                                                         COMMAND                  CREATED             STATUS                 PORTS                            NAMES
    b78a979df924        hub.chinacloud.com.cn/fast-pulsar.dev/pulsar-pkg-ui-all-in-one:20181123       "/entrypoint.sh nginx"   4 days ago          Up 4 days              443/tcp, 0.0.0.0:19016->80/tcp   pulsar-pkg-ui-all-in-one
    d27e04e08e94        hub.chinacloud.com.cn/fast-pulsar.dev/portal:20180926                         "nginx -g 'daemon off"   3 weeks ago         Up 3 weeks             443/tcp, 0.0.0.0:19012->80/tcp   portal
    a70779e0f1a8        hub.chinacloud.com.cn/fast-wh.dev/whitehole-event:20181026                    "/apps/whitehole-even"   3 weeks ago         Up 3 weeks (healthy)                                    whitehole-event                                "docker-entrypoint.sh"   4 months ago        Up 7 weeks (healthy)                                    mysql
    [root@auto hzb]# sed -n '3p' ./dockerps.log |cut -d " " -f1
    d27e04e08e94

    3、删除文件的最初三行

    set -i '1,3d' ./dockerps.log

    4、晚上11点到早上8点之前,每隔2小时,打印系统时间

    [root@auto hzb]# cat date.sh 
    #!/bin/bash
    echo -e "date is:
    "
    date
    echo 1 23,1-8/2 * * * root /root/hzb/date.sh >>/etc/crontab

    扩展:

    crontab任务配置基本格式:
    *   *  *  *  *  command
    分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6,0代表星期天)  命令

    第1列表示分钟1~59 每分钟用*或者 */1表示
    第2列表示小时1~23(0表示0点)
    第3列表示日期1~31
    第4列表示月份1~12
    第5列标识号星期0~6(0表示星期天)
    第6列要运行的命令

    0 1 * * * /home/testuser/test.sh
    每天晚上1点调用/home/testuser/test.sh
    
    */10 * * * * /home/testuser/test.sh
    每10钟调用一次/home/testuser/test.sh
    
    30 21 * * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每晚的21:30重启apache。
    
    45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每月1、10、22日的4 : 45重启apache。
    
    10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每周六、周日的1 : 10重启apache。
    
    0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
    
    0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart
    上面的例子表示每星期六的11 : 00 pm重启apache。
    
    * */1 * * * /usr/local/etc/rc.d/lighttpd restart
    每一小时重启apache
    
    * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart
    晚上11点到早上7点之间,每隔一小时重启apache
    
    0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart
    每月的4号与每周一到周三的11点重启apache
    
    0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart
    一月一号的4点重启apache
    
    */30 * * * * /usr/sbin/ntpdate 210.72.145.44
    每半小时同步一下时间

     5、如何将本地80端口的请求转发到8080端口,当前主机IP为172.16.0.166

       /sbin/iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to 172.16.0.166:8080
    
       /sbin/iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080

    6、获取java进程的pid

    [root@auto hzb]# ps -ef|grep java|tr -s " "|cut -d " " -f2
    1515
    7908
    22456
    22749
    23014

    ps的输出字段间会有多个空格,所以直接用cut并不合适,用tr压缩连续空格后用cut

    扩展:语法:tr [–c/d/s/t] [SET1] [SET2]
    SET1: 字符集1
    SET2:字符集2
    -c:complement,用SET2替换SET1中没有包含的字符
    -d:delete,删除SET1中所有的字符,不转换
    -s: squeeze-repeats,压缩SET1中重复的字符
    -t: truncate-set1,将SET1用SET2转换,一般缺省为-t

    echo aaacccddd | tr -s [a-z]
    acd

    将语句中所有的小写字母变成大写字母,其中-t可省略

    echo "Hello World I Love You" |tr -t [a-z] [A-Z]
    HELLO WORLD I LOVE YOU

    删除指定字符

    $ cat test.txt
    Monday     09:00
    Tuesday    09:10
    Wednesday  10:11

    -d代表删除,[0-9]代表所有的数字,[: ]代表冒号和空格

    $ cat test.txt | tr -d "[0-9][: ]"
    Monday
    Tuesday
    Wednesday

     7、将当前目录下大于10944的文件转移到当前目录的bak下

    #!/bin/bash
    fileinfo=($(du ./*))
    length=${#fileinfo[@]}
    for((i=0;i<$length;i=$((i+2 ))));
      do
       if[ ${fileinfo[$i]} -le 10 ];then
         mv ${fileinfo[$((i+1 ))]} ./bak/
       fi
      done

    分析:du ./*的内容如下:

    [root@auto test]# du ./*
    0    ./bak
    4    ./docker-compose.yml
    4    ./header.json
    8    ./test.conf
    4    ./test.env
    4    ./testmv.sh
    289228    ./test.tar
    98056    ./test.tar.gz
    10944    ./test.tbz
    分析:($(du ./*))
    [root@auto test]# echo ${fileinfo[@]}
    4 ./docker-compose.yml 4 ./header.json 8 ./test.conf 4 ./test.env 4 ./testmv.sh 289228 ./test.tar 98056 ./test.tar.gz 10944 ./test.tbz

     8、linux下面的sed和awk的编写

      1)如何显示文本file.txt中第二大列大于56789的行?

    awk -F "," '{if($2>56789){print $0}}' file.txt

    $0表示整个当前行,$1表示每行第一个字段

     2)显示file.txt的1,3,5,7,10,15行?

      sed -n "1p;3p;5p;7p;10p;15p" file.txt
    
      awk 'NR==1||NR==3||NR==5||…||NR=15{print $0}' file.txt

    3)将file.txt的制表符,即tab,全部替换成"|"

    sed-i "s#	#|#g" file.txt

    9、请用Iptables写出只允许10.1.8.179 访问本服务器的22端口。

      /sbin/iptables -A input -p tcp -dport 22 -s 10.1.8.179 -j ACCEPT
    
      /sbin/iptables -A input -p udp -dport 22 -s 10.1.8.179 -j ACCEPT
    
      /sbin/iptables -P input -j DROP

    10、假设有一个脚本scan.sh,里面有1000行代码,并在vim模式下面,请按照如下要求写入对应的指令

    1)将shutdown字符串全部替换成reboot
    
      :%s/shutdown/reboot/g
    
    2)清空所有字符
    
      :%d
    
    3)不保存退出
    
      q!

    11、找出系统内大于50k,小于100k的文件,并删除它们。

      #!/bin/bash
    
      file=`find / -size +50k -size -100k`
    
      for i in $file;do
    
          rm -rf $i
    
      done

    12、脚本(如:目录dir1、dir2、dir3下分别有file1、file2、file2,请使用脚本将文件改为dir1_file1、dir2_file2、dir3_file3) 

      #!/bin/bash
    
      file=`ls dir[123]/file[123]`
    
      for i in $file;do
    
          mv $i ${i%/*}/${i%%/*}_${i##*/}
    
      done
    ${i%/*}:从右边删除最短匹配,比如dir1/file1,删除/*后,变成dir1
    ${i%%/*}:从右边删除最长匹配,比如dir1/file1,删除/*后,变成dir1,因为只有一个/,最短和最长匹配是一样的。
    ${i##*/}:从左边删除最长匹配:比如dir1/file1,删除*/后,变成file1

    13、 如何计算传递进来的参数 ?

    $#

    14 、如何在脚本中获取脚本名称 ?

    $0

    15、 如何检查之前的命令是否运行成功 ?

    $?

    16、 如何获取文件的最后一行 ?

    tail-1

    17、如何获取文件的第一行 ?

    head-1 

    18、假如文件中每行第一个元素是 FIND,如何获取第二个元素 

    awk'{ if ($1 == "FIND") print $2}'

    19、如何进行两个整数相加 ?

    A=5
    B=6
    echo $(($A+$B))  # 方法 2
    echo $[$A+$B]    # 方法 3
    expr $A + $B     # 方法 4
    echo $A+$B | bc  # 方法 5
    awk 'BEGIN{print '"$A"'+'"$B"'}'   # 方法 6

    20、判断是否存在

    if [ ! -d "/data/" ]  #判断目录不存在
    if [  -d "/data/" ]  #判断目录存在
    if [ ! -f "/data/filename" ] #判断文件不存在
    if [  -f "/data/filename" ] #判断文件不存在
    
    -e 判断对象是否存在
    -d 判断对象是否存在,并且为目录
    -f 判断对象是否存在,并且为常规文件
    -L 判断对象是否存在,并且为符号链接
    -h 判断对象是否存在,并且为软链接
    -s 判断对象是否存在,并且长度不为0
    -r 判断对象是否存在,并且可读
    -w 判断对象是否存在,并且可写
    -x 判断对象是否存在,并且可执行
    -O 判断对象是否存在,并且属于当前用户
    -G 判断对象是否存在,并且属于当前用户组
    -nt 判断file1是否比file2新  [ "/data/file1" -nt "/data/file2" ]
    -ot 判断file1是否比file2旧  [ "/data/file1" -ot "/data/file2" ]

     [ -z STRING ] “STRING” 的长度为零则为真。

     [ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。

    21、写出 shell 脚本中所有循环语法 ?

    for:

    for i in $(ls);do
    
    echo item:$i
    
    done

    while:

    #!/bin/bash
    COUNTER=0
    while [ $COUNTER -lt 10 ]; do
    echo The counter is $COUNTER
    let COUNTER=COUNTER+1
    done

    until:

    #!/bin/bash
    COUNTER=20
    until [ $COUNTER -lt 10 ]; do
    echo COUNTER $COUNTER
    let COUNTER-=1
    done

    22、如何获取文本文件的第 10 行 ?

    head -10 file|tail -1

    23、命令:[ -z "" ] && echo 0 || echo 1 的输出是什么

    0

     24、name=John && echo 'My name is $name' 的输出是什么

    My name is $name

     25、name=John && echo “My name is $name” 的输出是什么

    My name is John

    26、如何只用 echo 命令获取字符串变量的一部分 ?

    echo ${variable:x:y}
    x - 起始位置
    y - 长度

     例子:

    variable="My name is Petras, and I am developer."
    echo ${variable:11:6} # 会显示 Petras

    27、如果给定字符串 variable="User:123:321:/home/dir",如何只用 echo 命令获取 /home/dir ?

    echo ${variable##*:}

    28、如何使用 awk 列出 UID 小于 100 的用户 ?

    awk -F: '$3<100' /etc/passwd

    29、如何在 bash shell 中更改标准的域分隔符为 ":" ?

     IFS=":"

    30、如何打印变量的最后 5 个字符 ?

    [root@auto ~]# str="aaaaaaaaaa"
    [root@auto ~]# echo ${str: -5}
    aaaaa
    [root@auto ~]# echo ${str:-5}
    aaaaaaaaaa
    [root@auto ~]# str="aaaabbbb"
    [root@auto ~]# echo ${str: +5}
    bbb

    31、将test.txt中的内容以大写显示

    [root@auto ~]# cat test.txt 
    aaaa
    bbbb
    cccc
    [root@auto ~]# cat test.txt |tr a-z A-Z
    AAAA
    BBBB
    CCCC

    32、wc的用法:

    [root@auto ~]# cat test.txt 
    aaaa
    bbbb
    ccccc
    [root@auto ~]# cat test.txt|wc -l
    3
    [root@auto ~]# cat test.txt|wc -c
    16
    [root@auto ~]# cat test.txt|wc -m
    16
    [root@auto ~]# cat test.txt|wc -w
    3
    [root@auto ~]# cat test.txt|wc -L
    5

    -c 统计字节数。

    -l 统计行数。

    -m 统计字符数。这个标志不能与 -c 标志一起使用。

    -w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

    -L 打印最长行的长度。

    33、列出第二个字母是 e或z的文件或目录 

    [root@auto ~]# ls
    anaconda-ks.cfg  hzb  java0.log  java1.log  java1.log.lck  test.txt
    [root@auto ~]# ls -d ?[ez]*
    hzb  test.txt

    如果是第三个字母:ls -d ??[ez]*

    34、如何去除字符串中的所有空格

    [root@localhost ~]# str="aa  vvvvvv ccc   dd"
    [root@localhost ~]# echo $str|tr -d " "
    aavvvvvvcccdd

    35、写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ? 

    for i in {0..100..3}; do echo $i; done
    或
    for (( i=0; i<=100; i=i+3 )); do echo "Welcome $i times"; done

    36、如何打印传递给脚本的所有参数 ?

    echo $*
    或
    echo $@

    37、[ $a == $b ] 和 [ $a -eq $b ] 有什么区别

    [ $a == $b ] - 用于字符串比较
    [ $a -eq $b ] - 用于数字比较

    38、如何检查字符串是否以字母 "abc" 开头 ?

    [[ $string == abc* ]]

    39、[[ $string == abc* ]] 和 [[ $string == "abc*" ]] 有什么区别 

    • [[ $string == abc* ]] - 检查字符串是否以字母 abc 开头
    • [[ $string == "abc*" ]] - 检查字符串是否完全等于 abc*

    40、如何列出以 ad 或 ma 开头的用户名 ?

    [root@auto hzb]# egrep "^ad|^ma" /etc/passwd|cut -d: -f1
    adm
    mail

    41、$#,$*,$@,$$的用法 

    $# 是传给脚本的参数个数

    $0 是脚本本身的名字
    $1 是传递给该shell脚本的第一个参数
    $2 是传递给该shell脚本的第二个参数
    $@ 是传给脚本的所有参数的列表
    $* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9
    $$ 是脚本运行的当前进程ID号
    $? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
    #!/bin/bash
    IFS=":";
    echo $#
    echo $*
    echo $@
    echo "$*"
    echo "$@"
    echo $$
    echo $?
    echo $!
    IFS=" ";
    [root@auto hzb]# ./test.sh 123 abc xyz
    3
    123 abc xyz
    123 abc xyz
    123:abc:xyz
    123 abc xyz
    31404
    0

    $* 会根据 IFS 的不同来组合值,而 $@ 则会将值用" "来组合值!

    42、数组的一些操作 ?

    [root@auto hzb]# arr=("xx" "aa" "yy" "bb") -定义数组
    [root@auto hzb]# echo ${arr[0]}            -打印第一个元素
    xx
    [root@auto hzb]# echo ${arr[@]}            -打印全部元素
    xx aa yy bb
    [root@auto hzb]# echo ${!arr[@]}           -打印每个元素的下标
    0 1 2 3
    [root@auto hzb]# unset arr[2]              -删除第三个元素
    [root@auto hzb]# echo ${arr[@]}
    xx aa bb
    [root@auto hzb]# arr[0]="BBB"              -重新给第一个元素设置值
    [root@auto hzb]# echo ${arr[@]}
    BBB aa bb
  • 相关阅读:
    编译安装linux内核步骤
    怎样在github上协同开发
    在JSP里使用CKEditor和CKFinder
    tomcat结合nginx使用小结
    JAVA学习笔记——(五)
    JAVA学习笔记——(四)
    JAVA学习笔记——(三)
    JAVA学习笔记——(二)
    JAVA学习笔记——(一)
    ansible
  • 原文地址:https://www.cnblogs.com/boshen-hzb/p/10030459.html
Copyright © 2020-2023  润新知