欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Shell 练习题(面试前必看)

程序员文章站 2024-03-15 23:48:00
...
  1. 求2个数之和
#! /bin/bash
first=0
second=0
read -p "Input the first number:" first
read -p "Input the second number:" second
result=$[$first+$second]  或者 $(($first+$second))
echo "result is:$result"
exit 0
  1. 计算1-100的和
#! /bin/bash
SUM=0
I=0

while [ $I -le 100 ];do
    SUM=$((SUM+I))
    I=$((I+1))
done
echo "1+2+3+...+100 = $SUM"
  1. 将一目录下所有的文件的扩展名改为bak
*.* 表示要求 . 前面和后面都得有字母
#! /bin/bash
for i in *.*;do
    mv $i ${i%%.*}.bak
done
  1. 编译当前目录下的所有.c文件
#! /bin/bash
for file in *.c;do echo $file ;gcc -o $(basename $file .c) $file ; sleep 2;done
>compile 2>&1

$(basename $file .c)  basename表示取 file名字,过滤后缀.c。输出“file”。  main.c ——> main
注意 file .c  有空格间隔
gcc -o app test.c将生成可执行程序app。  -o选项用来指定输出文件的文件名。
  1. 打印root可以使用可执行文件数,处理结果: root’s bins: 2306
#! /bin/bash
echo "root's bins:$(find ./ -type f | xargs ls -l | sed '/-..x/p' | wc -l)"
更正确:
echo "root's bins:$(find ./ -user root | xargs ls -l | sed '/-..x/p' | wc -l)"
  1. 打印当前sshd的端口和进程id,处理结果: sshd Port&&pid: 22 3865
#! /bin/bash
netstat -apn | grep sshd | sed -n 's/.*:::\([0-9]*\)\ .* \ \([0-9]*\)\/sshd/\1 \2/p'
解析 \1匹配第一个括号,\2匹配第二个括号

Shell 练习题(面试前必看)

  1. 输出本机创建20000个目录所用的时间,处理结果

real 0m3.367s
user 0m0.066s
sys 0m1.925s

#! /bin/bash
time (
for i in {1..2000} ; do
    mkdir /tmp/nnn$i
done
)
  1. 打印本机的交换分区大小,处理结果: Swap:1024M
#! /bin/bash
free -m | sed -n '/Swap/p' | awk '{print $2}'

找出运行nginx的id号

$ ps aux | sed -n '/nginx/p' | awk '{print $2}' | head n2
  1. 文本分析,取出/etc/password中shell出现的次数
第一种方法结果:
    4 /bin/bash
    1 /bin/sync
    1 /sbin/halt
    31 /sbin/nologin
    1 /sbin/shutdown
第二种方法结果:
    /bin/sync      1
    /bin/bash      1
    /sbin/nologin  30
    /sbin/halt     1

#! /bin/bash
cat /etc/passwd | awk -F: '{if ($7!="") print $7}' | sort | uniq -c
或
cat /etc/passwd | awk -F: '{if ($7!="") print $7}' | sort | uniq -c | awk '{print $2,$1}'
  1. 文件整理,employee文件中记录了工号和姓名,(提示join)

employee.txt:
100 Jason Smith
200 John Doe
300 Sanjay Gupta
400 Ashok Sharma
bonus文件中记录工号和工资
bonus.txt:
100 $5,000
200 $500
300 $3,000
400 $1,250
要求把两个文件合并并输出如下,处理结果:
400 ashok sharma $1,250
100 jason smith $5,000
200 john doe $500
300 sanjay gupta $3,000

join命令:用于将两个文件中,指定栏位内容相同的行连接起来。
找出两个文件中,指定栏位内容相同的行,并加以合并,再输出

#! /bin/bash
join employee.txt bonus.txt | sort -k 2

-k 2 按照第二列进行排序,第二列是字母,按字母排序
  1. 写一个shell脚本来得到当前的日期,时间,用户名和当前工作目录
#! /bin/bash
echo "date:,`date`"      注意这里是反引号
echo "user:,`who i am`"
echo "directory:,`pwd`"
  1. 编写shell脚本获取本机的网络地址
#! /bin/bash

IP=`ifconfig eth0 | grep 'inet ' | sed 's/^.*addr://g' | sed 's/ Bcast.*$//g'`
NETMASK=`ifconfig eth0 | grep 'inet ' | sed 's/^.*Mask://g'`

#echo "$IP/$NETMASK"
echo "$IP"
exit 0
  1. 编写个shell脚本将当前目录下大于10K的文件转移到/tmp目录下
#! /bin/bash
for FileName in `ls -l | awk '$5>10240 {print $9}'`;do
    mv $FileName /tmp
done

ls -al /tmp
echo "Done! "
  1. 编写一个名为myfirstshell.sh的脚本,它包括以下内容。

a) 包含一段注释,列出您的姓名、脚本的名称和编写这个脚本的目的。
b) 问候用户。
c) 显示日期和时间。
d) 显示这个月的日历。
e) 显示您的机器名。
f) 显示当前这个操作系统的名称和版本。
g) 显示父目录中的所有文件的列表。
h) 显示root正在运行的所有进程。
i) 显示变量TERM、PATH和HOME的值。
j) 显示磁盘使用情况。
k) 用id命令打印出您的组ID。
m) 跟用户说“Good bye”

#! /bin/bash

# by Bin

user=`whoami`
case $user in
    root)
        echo "hello root";;
    Bin)
        echo "hello Bin";;
    *)
        echo "hello $user,welcome"
esac

echo "日期和时间:`date`"
echo "本月的日历:`cal`"
echo "本机的机器猫:`uname -n`"
echo "当前这个操作系统的名称和版本:`uname -s;uname -r`"
echo "父目录中的所有文件的列表:`ls ../`"
echo "root正在运行的所有程序:`ps -u root`"
ehco "变量TERM的值:$TERM"
ehco "变量PATH的值:$PATH"
ehco "变量HOME的值:$HOME"
echo "磁盘的使用情况:`df`"
echo "用id命令打印出你的组ID:`id -g`"
echo "Good bye!"
exit 0
  1. 文件移动拷贝,有m1.txt m2.txt m3.txt m4.txt,分别创建出对应的目录,m1 m2 m3 m4 并把文件移动到对应的目录下
#!/bin/bash
touch m1.txt m2.txt m3.txt m4.txt
i=1 

while [ $i -le 4 ]; do 
    mkdir m$i
    mv m$i.txt m$i
    I=$((i+1))
done
  1. root用户今天登陆了多长时间
#! /bin/sh

cat /proc/uptime| awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf("系统已运行:%d天%d时%d分%d秒\n",run_days,run_hour,run_minute,run_second)}'
  1. 终端输入一个文件名,判断是否是设备文件
    b - 块设备文件。
    c - 字符设备文件。
#/bin/bash

echo -e "The program will Judge a file is or not a device file.\n\n"
read -p "Input a filename:" filename
if [ -b $filename -o -c $filename ]; then
    echo "$filename is a device file"
    exit 0
else
    echo "$filename is not a device file"
    exit 1
fi
  1. 统计IP访问:要求分析apache访问日志,找出访问页面数量在前100位的IP数。日志大小在78M左右。以下是apache的访问日志节选
#! /bin/bash

# $1 为要测试的日志文件
awk '{print $1}' $1 | sort | uniq -c | sort -k1nr | head -n3
  1. 设计一个Shell程序,在/userdata目录下建立50个目录,即user1~user50,并设置每个目录的权限,其中其他用户的权限为:读;文件所有者的权限为:读、写、执行;文件所有者所在组的权限为:读、执行
#!/bin/bash
# 需要root权限
echo "create /userdata/user"

mkdir /userdata/user

if [ $? -eq 0 ]; then
    i=1
    while [ $i -le 50 ]; do
        mkdir -p /userdata/user/user$i
        chmod 754 /userdata/user/user$i
        let i++
    done
else
    echo "bye"
    exit 1
fi

exit 0

  1. 设计一个shell程序,添加一个新组为class1,然后添加属于这个组的30个用户,用户名的形式为stdxx,其中xx从01到30,并设置密码为对应的stdxx
#!/bin/bash

groupadd class1
for i in {9901..9930}; do
    xx=`echo $i | sed 's/99//g'`
    useradd -g class1 -s /bin/bash -d /home/std$xx -m std$xx
    echo -e "std$xx\nstd$xx" | passwd std$xx 
    echo -e "user std$xx password is std$xx" >> /root/newuser.txt
  1. 编写shell程序,实现自动删除30个账号的功能。账号名为std01至std30
#!/bin/bash

for i in {9901..9930}; do
    xx=`echo $i | sed 's/99//g'`
        userdel -r std$xx
done
  1. 用户清理,清除本机除了当前登陆用户以外的所有用户
#!/bin/bash
a=`echo $0 | sed 's/..\(...\).*/\1/'`

for i in `w|awk -v b=$a 'NR>2{if($NF !~ b) print $2}'`
do 
    echo $i
    fuser -k /dev/$i 
done
  1. 设计一个shell程序,在每月第一天备份并压缩/etc目录的所有内容,存放在/root/bak目录里,且文件名,为如下形式yymmdd_etc,yy为年,mm为月,dd为日。
#!/bin/bash

filename=`date +%y%m%d`_etc.tar.gz
#cd /etc/
tar -zcvf $filename *
mv $filename /root/bak/
  1. 对于一个用户日志文件,每行记录了一个用户查询串,长度为1-255字节,共几千万行,请排出查询最多的前100条。 日志可以自己构造。 (提示:awk sort uniq head)
#! /bin/bash

# show top 10

file=$1
awk '{print $1}' testdata.txt | sort | uniq -c | sort -k1nr | head -n10
  1. 编写自己的ubuntu环境安装脚本

  2. 编写服务器守护进程管理脚本

  3. 查看TCP连接状态

netstat -nat |awk '{print $6}'|sort|uniq -c|sort -rn
  1. 查找请求数请20个IP(常用于查找攻来源)
netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: ‘{print $1}|sort|uniq -c|sort -nr|head -n20
  1. 用tcpdump嗅探80端口的访问看看谁最高
tcpdump -i eth0 -tnn dst port 80 -c 1000 | awk -F"." '{print $1"."$2"."$3"."$4}' | sort | uniq -c | sort -nr |head -20
  1. 查找较多time_wait连接
netstat -n|grep TIME_WAIT|awk '{print $5}'|sort|uniq -c|sort -rn|head -n20
  1. 查找较多time_wait连接
netstat -an | grep SYN | awk '{print $5}' | awk -F: '{print $1}' | sort |uniq -c | sort -nr | more
  1. 根据端口列进程
netstat -ntlp | grep 80 | awk '{print $7}' | cut -d/ -f1
  1. 获得访问前10位的ip地址
cat access.log|awk '{print $1}'|sort|uniq -c|sort -nr|head -10
cat access.log|awk '{counts[$(11)]+=1}; END {for(url in counts) print counts[url], url}'
  1. 访问次数最多的文件或页面,取前20
cat access.log|awk '{print $11}'|sort|uniq -c|sort -nr|head -20
  1. 列出传输最大的几个exe文件(分析下载站的时候常用)
cat access.log |awk '($7~/.exe/){print $10 " " $1 " " $4 " " $7}'|sort -nr|head -20
  1. 列出输出大于200000byte(约200kb)的exe文件以及对应文件发生次数
cat access.log |awk '($10 > 200000 && $7~/.exe/){print $7}'|sort -n|uniq -c|sort -nr|head -100
  1. 如果日志最后一列记录的是页面文件传输时间,则有列出到客户端最耗时的页面
cat access.log |awk '($7~/.php/){print $NF " " $1 " " $4 " " $7}'|sort -nr|head -100
  1. 列出最耗时的页面(超过60秒的)的以及对应页面发生次数
cat access.log |awk '($NF > 60 && $7~/.php/){print $7}'|sort -n|uniq -c|sort -nr|head -100
  1. 列出传输时间超过 30 秒的文件
cat access.log |awk '($NF > 30){print $7}'|sort -n|uniq -c|sort -nr|head -20
  1. 统计网站流量(G)
cat access.log |awk '{sum+=$10} END {print sum/1024/1024/1024}'
  1. 统计404的连接
awk '($9 ~/404/)' access.log | awk '{print $9,$7}' | sort
  1. 统计http status
cat access.log |awk '{counts[$(9)]+=1}; END {for(code in counts) print code, counts[code]}'
cat access.log |awk '{print $9}'|sort|uniq -c|sort -rn
  1. 蜘蛛分析,查看是哪些蜘蛛在抓取内容
/usr/sbin/tcpdump -i eth0 -l -s 0 -w - dst port 80 | strings | grep -i user-agent | grep -i -E 'bot|crawler|slurp|spider'
  1. 创建一个用户mandriva,其ID号为2002,基本组为distro(组ID为3003),附加组为linux
# groupadd linux
# groupadd -g 3003 distro
# useradd -u 2002 -g distro -G linux mandriva
  1. 创建一个用户fedora,其全名为Fedora Community,默认shell为tcsh
# useradd -c "Fedora Community" -s /bin/tcsh fedora
  1. 修改mandriva的ID号为4004,基本组为linux,附加组为distro和fedora;
# usermod -u 4004 -g linux -G distro,fedora mandriva
  1. 给fedora加密码,并设定其密码最短使用期限为2天,最长为50天
# passwd fedora
# chage -m 2 -M 50 fedora
  1. 调试命令
strace -p pid

❤ 49. 写一个脚本

1、创建一个组newgroup, id号为4000;
2、创建一个用户mageedu1, id号为3001,附加组为newgroup;
3、创建目录/tmp/hellodirxyz
4、复制/etc/fstab至上面的目录中
5、改变目录及内部文件的属主和属组为mageedu1;
6、让目录及内部文件的其它用户没有任何权限;

#!/bin/bash
# Description:
# Version:
# Datetime:
# Author:

myGroup="newgroup1"
myUser="mageedu2"
myDir="/tmp/hellodirxyz1"
myID=3002

groupadd -g 4001 $myGroup
useradd -u $myID -G $myGroup $myUser
mkdir $myDir
cp /etc/fstab $myDir
chown -R $myUser:$myUser $myDir
chmod -R o= $myDir

unset myGroup myUser myID myDir
  1. 统计/bin、/usr/bin、/sbin和/usr/sbin等各目录中的文件个数
# ls /bin | wc -l
  1. 显示当前系统上所有用户的shell,要求,每种shell只显示一次
# cut -d: -f7 /etc/passwd | sort -u
  1. 取出/etc/passwd文件的第7行
# head -7 /etc/passwd | tail -1
  1. 显示第3题中取出的第7行的用户名
# head -7 /etc/passwd | tail -1 | cut -d: -f1
# head -7 /etc/passwd | tail -1 | cut -d: -f1 | tr 'a-z' 'A-Z'
  1. 统计/etc目录下以P或p开头的文件个数
# ls -d /etc/[Pp]* | wc -l
  1. 写一个脚本,用for循环实现显示/etc/init.d/functions、/etc/rc.d/rc.sysinit和/etc/fstab各有多少行
for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
    wc -l $fileName
done

#!/bin/bash
for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
    lineCount=`wc -l $fileName | cut -d' ' -f1`
    echo "$fileName: $lineCount lines."
done

#!/bin/bash
for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
    echo "$fileName: `wc -l $fileName | cut -d' ' -f1` lines."
done
  1. 写一个脚本,将上一题中三个文件的复制到/tmp目录中;用for循环实现,分别将每个文件的最近一次的修改时间改为2020年3月18号12点40分
for fileName in /etc/init.d/functions /etc/rc.d/rc.sysinit /etc/fstab; do
    cp $fileName /tmp
    baseName=`basename $fileName`
    touch -m -t 201109151327 /tmp/$baseName
done
  1. 写一个脚本, 显示/etc/passwd中第3、7和11个用户的用户名和ID号
for lineNo in 3 7 11; do
    userInfo=`head -n $lineNo /etc/passwd | tail -1 | cut -d: -f1,3`
    echo -e "User: `echo $userInfo | cut -d: -f1`\nUid: `echo $userInfo |cut -d: -f2`"
done
  1. 显示/proc/meminfo文件中以大小写s开头的行
# grep "^[sS]" /proc/meminfo
# grep -i "^s" /proc/meminfo
  1. 取出默认shell为非bash的用户
# grep -v "bash$" /etc/passwd | cut -d: -f1
  1. 取出默认shell为bash的且其ID号最大的用户
# grep "bash$" /etc/passwd | sort -n -t: -k3 | tail -1 | cut -d: -f1
  1. 显示/etc/rc.d/rc.sysinit文件中,以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行
# grep "^#[[:space:]]\{1,\}[^[:space:]]\{1,\}" /etc/rc.d/rc.sysinit
  1. 显示/boot/grub/grub.conf中以至少一个空白字符开头的行
# grep "^[[:space:]]\{1,\}[^[:space:]]\{1,\}" /boot/grub/grub.conf
  1. 找出/etc/passwd文件中一位数或两位数
# grep --color=auto "\<[0-9]\{1,2\}\>" /etc/passwd
  1. 找出ifconfig命令结果中的1到255之间的整数
# ifconfig | grep -E --color=auto "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
  1. 查看当前系统上root用户的所有信息
# grep "^root\>" /etc/passwd
  1. 添加用户bash和testbash、basher,而后找出当前系统上其用户名和默认shell相同的用户
# grep --color=auto "^\([[:alnum:]]\{1,\}\)\>.*\1$" /etc/passwd
  1. 找出netstat -tan命令执行的结果中以“LISTEN”或“ESTABLISHED”结尾的行
netstat -tan | grep ('\<.*LISTEN.*\>' || '\<.*ESTABLISHED.*\>')
  1. 取出当前系统上所有用户的shell,要求:每种shell只显示一次,且按升序显示
 # cut -d: -f7 /etc/passwd | sort -u
  1. 排名前三热搜
    Shell 练习题(面试前必看)
相关标签: # Shell

上一篇: MYSQL安全加固规范

下一篇: