现在的位置: 首页 > 综合 > 正文

shell脚本常见面试题

2013年10月10日 ⁄ 综合 ⁄ 共 6593字 ⁄ 字号 评论关闭

#/bin/sh
Max_CPU=0
Avg_CPU=0
Total_Time=1
Process=$1
Interval=$2
# check the parameters
if [ $# -ne 2 ]; then
   echo "Usage: $0 ProcessName Interval"
   exit
fi
LogFile="Per.txt"
echo "`date`" > $LogFile
while sleep $Interval
do
   top -d 1 -n 1|grep $Process|grep -v grep|awk '{print $9"\t"$10}' >> $LogFile
done

 判断是否是设备文件

 #/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

firead –p:用于在读数据时输出提示信息

 注意! [ 之间是有空格的:if ! [ -f $filename ] ; then。一般用if [ ! * ]

 

添加用户:

#/bin/bash

 groupadd -f class1

for i in {9909..9911}

do

        xx=`echo $i | sed 's/99//g'`

        useradd -g class1 std${xx}

        echo std${xx} | passwd std${xx} --stdin

        echo -e "user std${xx} passwd is std${xx}">>/root/newuser.txt

done

exit 0

        注意等号的前后不要有空格:xx=`echo $i | sed 's/99//g'`

       变量如果前后有字符,要是大括号

 

统计IP访问:

要求分析apache访问日志,找出访问页面数量在前100位的IP数。日志大小在78M左右。以下是apache的访问日志节选

 202.101.129.218 - - [26/Mar/2006:23:59:55 +0800] "GET /online/stat_inst.php?pid=d065 HTTP/1.1" 302 20-"-" "-" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"

 # awk '{print $1}' log      |sort |uniq -c|sort -r |head -n10

      5 221.224.78.15

      3 221.233.19.137

      1 58.63.148.135

      1 222.90.66.142

      1 222.218.90.239

      1 222.182.95.155

      1 221.7.249.206

      1 221.237.232.191

      1 221.235.61.109

      1 219.129.183.122

 这个地方有个疑问,为什么在使用uniq之前要sort。

 

求2个数之和

#/bin/bash

typeset first second

read -p "Input the first number:" first

read -p "Input the second number:" second

result=$[$first+$second]

echo "result is : $result"

exit 0

 

文本分析

取出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
/sbin/shutdown  1

 答案:

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}'

 

文件整理

employee文件中记录了工号和姓名
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 employee bonus | sort -k 2

  

打印本机的交换分区大小

处理结果:
Swap:1024M

 free -m | sed -n '/Swap/p' | awk '{ print $2}'

free -m | sed -n 's/Swap:\ *\([0-9]*\).*/\1/p'

 

输出本机创建20000个目录所用的时间

处理结果:
real    0m3.367s
user    0m0.066s
sys     0m1.925s

 答案:

# time for i in {1..2000} ; do mkdir /root/neil$i; done

 real    0m6.200s

user    0m1.128s

sys     0m4.710s

 

打印当前sshd的端口和进程id

处理结果:
sshd Port&&pid: 22 5412

 答案:netstat -anp | grep sshd | sed -n 's/.*:::\([0-9]*\)\ .* \ \([0-9]*\)\/sshd/\1 \2/p'

 

打印root可以使用可执行文件数

处理结果:
root's bins: 2306

echo "root's bins: $(find ./ -type f | xargs ls -l | sed '/-..x/p' | wc -l)"

root's bins: 3664

 

编译当前目录下的所有.c文件:

 for file in *.c; do echo $file ; gcc -o $(basename $file .c) $file  ; sleep 2;  done > compile 2>&1

 

将一目录下所有的文件的扩展名改为bak

for i in *.*;do mv $i ${i%%.*}.bak;done

 

开机时间:直接一个“W”
关机时间:last -n 10
1)查看系统日志

/var/log/messages

2)利用last命令(last -n 10 )

       last 命令介绍

  功能说明:列出目前与过去登入系统的用户相关信息。

  语  法:last [-adRx][-f <记录文件>][-n <显示列数>][帐号名称...][终端机编号...]

  补充说明:单独执行last指令,它会读取位于/var/log目录下,名称为wtmp的文件,并把该给文件的内 容记录的登入系统的用户名单全部显示出来。

  参  数:
  -a  把从何处登入系统的主机名称或IP地址,显示在最后一行。
  -d  将IP地址转换成主机名称。
  -f <记录文件>  指定记录文件。
  -n <显示列数>或-<显示列数>  设置列出名单的显示列数。
  -R  不显示登入系统的主机名称或IP地址。
  -x  显示系统关机,重新开机,以及执行等级的改变等信息。

同一时间只运行一个实例

  使用PID file 对文件加锁,或(semget (ID,1,IPC_CREATE|IPC_EXCL) == -1);

  使用fcntl文件锁

怎样让一个实例在某个时间或开机自动运行

1:

简易方法:

                  1。使用CL命令DSPSYSVAL QSTRUPPGM来确定系统自动调用的程序名,如qsys/qstrup

  2。建立另一个CL程序,并编译,程序代码:
*************** Beginning of data ***************************

0001.00 PGM
0002.00 --------QSYS/CALL PGM(QSYS/QSTRUP)
0003.00 --------QSYS/STRSBS SBSD(MYLIB/SALESSBSD)
0004.00 --------QSYS/CALL PGM(MYLIB/CLEARSALES)
0005.00 ENDPGM
0006.00
****************** End of data *******************************
  程序的后两条语句为用户要增加的功能,假设编译后的可执行的程序为:MYLIB/STARTUP

  3。修改系统值QSTRUPPGM:用命令WRKSSVAL QSTRUPPGM,再用2选择项,将程序名修改为MYLIB/STARTUP。系统在IPL后会自动调用程序MYLIB/STARTUP,不需要直接修改QSYS/QSTRUP程序的内容!

2:

Linux有自己一套完整的启动体系,抓住了linux启动的脉络,linux的启动过程将不再神秘。

阅读之前建议先看一下附图。

本文中假设inittab中设置的init tree为:

/etc/rc.d/rc0.d

/etc/rc.d/rc1.d

/etc/rc.d/rc2.d

/etc/rc.d/rc3.d

/etc/rc.d/rc4.d

/etc/rc.d/rc5.d

/etc/rc.d/rc6.d

/etc/rc.d/init.d

1. 关于linux的启动

init是所有进程之父

init读取/etc/inittab,执行rc.sysinit脚本

(注意文件名是不一定的,有些unix甚至会将语句直接写在inittab中)

rc.sysinit脚本作了很多工作:

init $PATH

config network

start swap function

set hostname

check root file system, repair if needed

check root space

....

rc.sysinit根据inittab执行rc?.d脚本

linux是多用户系统,getty是多用户与单用户的分水岭

在getty之前运行的是系统脚本

2. 关于rc.d

所有启动脚本放置在 /etc/rc.d/init.d下

rc?.d中放置的是init.d中脚本的链接,命名格式是:

S{number}{name}

K{number}{name}

S开始的文件向脚本传递start参数

K开始的文件向脚本传递stop参数

number决定执行的顺序

3. 启动脚本示例

这是一个用来启动httpd的 /etc/rc.d/init.d/apache 脚本:

CODE:

#!/bin/bash

source /etc/sysconfig/rc
source $rc_functions

case "$1" in
    start)
          echo "Starting Apache daemon..."
          /usr/local/apache2/bin/apachectl -k start
          evaluate_retval
          ;;

    stop)
          echo "Stopping Apache daemon..."
          /usr/local/apache2/bin/apachectl -k stop
          evaluate_retval
          ;;

    restart)
          echo "Restarting Apache daemon..."
          /usr/local/apache2/bin/apachectl -k restart
          evaluate_retval
          ;;

    status)
          statusproc /usr/local/apache2/bin/httpd
          ;;
          
    *)
          echo "Usage: $0 {start|stop|restart|status}"
          exit 1
          ;;
esac
[Copy to clipboard]

可以看出他接受start,stop,restart,status参数

然后可以这样建立rc?.d的链接:

CODE:

cd /etc/rc.d/init.d &&
ln -sf ../init.d/apache ../rc0.d/K28apache &&
ln -sf ../init.d/apache ../rc1.d/K28apache &&
ln -sf ../init.d/apache ../rc2.d/K28apache &&
ln -sf ../init.d/apache ../rc3.d/S32apache &&
ln -sf ../init.d/apache ../rc4.d/S32apache &&
ln -sf ../init.d/apache ../rc5.d/S32apache &&
ln -sf ../init.d/apache ../rc6.d/K28apache
[Copy to clipboard]

4. 关于rc.local

经常使用的 rc.local 则完全是习惯问题,不是标准。

各个发行版有不同的实现方法,可以这样实现:

CODE:

touch /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
ln -sf /etc/rc.d/rc.local /etc/rc.d/rc1.d/S999rc.local &&

ln -sf /etc/rc.d/rc.local /etc/rc.d/rc2.d/S999rc.local &&
ln -sf /etc/rc.d/rc.local /etc/rc.d/rc3.d/S999rc.local &&
ln -sf /etc/rc.d/rc.local /etc/rc.d/rc4.d/S999rc.local &&
ln -sf /etc/rc.d/rc.local /etc/rc.d/rc5.d/S999rc.local &&
ln -sf /etc/rc.d/rc.local /etc/rc.d/rc6.d/S999rc.local
[Copy to clipboard]

5. 关于bash启动脚本

/etc/profile

/etc/bashrc

~/.bash_profile

~/.bashrc

是bash的启动脚本

一般用来设置单用户的启动环境,也可以实现开机单用户的程序,但要明确他们都是属于bash范畴而不是系统范畴。

他们的具体作用介绍如下:

/bin/bash这个命令解释程序(后面简称shell)使用了一系列启动文件来建立一个运行环境:

/etc/profile

/etc/bashrc

~/.bash_profile

~/.bashrc

~/.bash_logout

每一个文件都有特殊的功用并对登陆和交互环境有不同的影响。

/etc/profile 和 ~/.bash_profile 是在启动一个交互登陆shell的时候被调用。

/etc/bashrc 和 ~/.bashrc 是在一个交互的非登陆shell启动的时候被调用。

~/.bash_logout 在用户注销登陆的时候被读取

一个交互的登陆shell会在 /bin/login 成功登陆之后运行。一个交互的非登陆shell是通过命令行来运行的,如[prompt]$/bin/bash。一般一个非交互的shell出现在运行shell脚本的时候。之所以叫非交互的shell,是因为它不在命令行上等待输入而只是执行脚本程序。

6. 关于开机程序的自动启动

系统脚本可以放置在/etc/rc.d/init.d中并建立/etc/rc.d/rc?.d链接,也可以直接放置在/etc/rc.d/rc.local中。

init.d脚本包含完整的start,stop,status,reload等参数,是标准做法,推荐使用。

为特定用户使用的程序(如有的用户需要使用中文输入法而有的不需要)放置在~/中的bash启动脚本中

  $? $# $@ $* $$分别代表什么?

$? 是否运行完毕 退出

$# 参数个数

$@,$* 待定参数

抱歉!评论已关闭.