【DB笔试面试275】 与SHELL脚本相关的一些笔试面试题(目前36道,后续持续更新)
- 2019 年 10 月 10 日
- 筆記
本小节以几道真题为例,简单讲解与SHELL有关的面试题。在实际工作中,要写的SHELL脚本要复杂得多。
真题1、SHELL脚本是什么?它是必需的吗?
答案:一个SHELL脚本就是一个文本文件,它包含一个或多个命令。系统管理员会经常需要使用多个命令来完成一项任务,此时可以添加这些所有命令在一个文本文件(SHELL脚本)中来完成这些日常工作任务。
真题2、什么是默认登录SHELL,如何改变指定用户的登录SHELL?
答案:在Linux操作系统中,“/bin/bash”是默认登录SHELL,是在创建用户时分配的。使用chsh命令可以改变默认的SHELL。示例如下所示:
# chsh <用户名> -s <新shell> # chsh lhr -s /bin/sh
真题3、可以在SHELL脚本中使用哪些类型的变量?
答案:在SHELL脚本,可以使用两种类型的变量:系统变量和用户变量。
系统变量是由系统自己创建的。这些变量通常由大写字母组成,可以通过“set”命令查看。
用户变量由系统用户来生成和定义,变量的值可以通过命令“echo $<变量名>”查看。
真题4、如何将标准输出和错误输出同时重定向到同一位置?
答案:有两个方法可以来实现:
方法一,使用“2>&1”,例如:
ls /usr/share/doc > out.txt 2>&1
方法二,使用“&>”,例如:
ls /usr/share/doc &> out.txt
真题5、SHELL脚本中“if”语法如何嵌套?
答案:基础语法如下:
if [ 条件 ] then 命令1 命令2 … else if [ 条件 ] then 命令1 命令2 … else 命令1 命令2 … fi fi
真题6、SHELL脚本中“$?”标记的用途是什么?
答案:在写一个SHELL脚本时,如果想要检查前一命令是否执行成功,那么可以使用“$?”来检查前一条命令的结束状态。简单的例子如下所示:
root@localhost:~# ls /usr/bin/shar /usr/bin/shar root@localhost:~# echo $? 0
如果结束状态是0,那么说明前一个命令执行成功。
root@localhost:~# ls /usr/bin/shar /usr/bin/shar root@localhost:~# echo $? 0
如果结束状态不是0,那么说明命令执行失败。
真题7、在SHELL脚本中如何比较两个数字?
答案:在if-then中使用测试命令( -gt 等)来比较两个数字,例子如下:
root@localhost:~# ls /usr/bin/shar /usr/bin/shar root@localhost:~# echo $? 0
SHELL里面比较字符的常用写法:
-eq 等于 -ne 不等于 -gt 大于 -lt 小于 -le 小于等于 -ge 大于等于 -z 空串 = 两个字符相等 != 两个字符不等 -n 非空串
真题8、SHELL脚本中break命令的作用有哪些?
答案:break命令可以退出循环,可以在while和until循环中使用break命令跳出循环。
真题9、SHELL脚本中continue命令的作用有哪些?
答案:continue命令不同于break命令,它只跳出当前循环的迭代,而不是整个循环。continue命令很多时候是很有用的,例如错误发生,但依然希望继续执行外层循环的时候。
真题10、请写出SHELL脚本中Case语句的语法。
答案:基础语法如下:
case $arg in pattern | sample) # arg in pattern or sample ;; pattern1) # arg in pattern1 ;; *) #default ;; esac
说明:pattern1是正则表达式,可以使用下面任意字符:
① *表示任意字串
② ?表示任意字元
③ [abc]表示a,b,或c三字元其中之一
④ [a-n]表示从a到n的任一字元
⑤ |表示多重选择
示例:
#!/bin/sh echo -n "enter a number from 1 to 4:" read ANS case $ANS in 1) echo "you select 1" ;; 2)echo "you select 2" ;; 3) echo "you select 3" ;; 4) echo "you select 4" ;; *)echo "'basename $0':This is not between 1 and 4 " >&2 exit ;; esac
测试:
[root@localhost shell]# sh case1.sh enter a number from 1 to 4:1 you select 1 [root@localhost shell]# sh case1.sh enter a number from 1 to 4:5 'basename case1.sh':This is not between 1 and 4
真题11、请写出SHELL脚本中while循环语法?
答案:如同for循环,while循环只要条件成立就会重复执行它的命令块。不同于for循环,while循环会不断迭代,直到它的条件不为真。基础语法:
while [ 条件 ] do 命令… done
真题12、如何使脚本可执行?
答案:使用chmod命令来使脚本可执行。例子如下:
# chmod a+x myscript.sh
真题13、“#!/bin/bash”的作用是什么?
答案:“#!/bin/bash”是SHELL脚本的第一行,意思是后续命令都通过/bin/bash来执行。
真题14、请写出SHELL脚本中for循环的语法。
答案:for循环的基础语法:
for 变量 in 循环列表 do 命令1 命令2 …. 最后命令 done
真题15、如何调试SHELL脚本?
答案:使用“-x”参数(sh -x myscript.sh)可以调试SHELL脚本。另一个种方法是使用“-nv”参数(sh -nv myscript.sh)。
真题16、SHELL脚本如何比较字符串?
答案:test命令可以用来比较字符串。测试命令会通过比较字符串中的每一个字符来比较。其实,test还有其它用途:
1)判断表达式
if test (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2 两个表达式都为真 test 表达式1 –o 表达式2 两个表达式有一个为真
2)判断字符串
test –n 字符串 字符串的长度非零 test –z 字符串 字符串的长度为零 test 字符串1=字符串2 字符串相等 test 字符串1!=字符串2 字符串不等
3)判断整数
test 整数1 –eq 整数2 整数相等 test 整数1 –ge 整数2 整数1大于等于整数2 test 整数1 –gt 整数2 整数1大于整数2 test 整数1 –le 整数2 整数1小于等于整数2 test 整数1 –lt 整数2 整数1小于整数2 test 整数1 –ne 整数2 整数1不等于整数2
4)判断文件
test File1 –ef File2 两个文件具有同样的设备号和i结点号 test File1 –nt File2 文件1比文件2 新 test File1 –ot File2 文件1比文件2 旧 test –b File 文件存在并且是块设备文件 test –c File 文件存在并且是字符设备文件 test –d File 文件存在并且是目录 test –e File 文件存在 test –f File 文件存在并且是正规文件 test –g File 文件存在并且是设置了组ID test –G File 文件存在并且属于有效组ID test –h File 文件存在并且是一个符号链接(同-L) test –k File 文件存在并且设置了sticky位 test –L File 文件存在并且是一个符号链接(同-h) test –o File 文件存在并且属于有效用户ID test –p File 文件存在并且是一个命名管道 test –r File 文件存在并且可读 test –s File 文件存在并且是一个套接字 test –t FD 文件描述符是在一个终端打开的 test –u File 文件存在并且设置了它的set-user-id位 test –w File 文件存在并且可写 test –x File 文件存在并且可执行
真题17、Bourne shell(bash)中有哪些特殊的变量?
答案:下面列出了Bourne shell为命令行设置的特殊变量:
$0 命令行中的脚本名字 $1 第一个命令行参数 $2 第二个命令行参数 ….. ……. $9 第九个命令行参数 $# 命令行参数的数量 $* 所有命令行参数,以空格隔开
真题18、在SHELL脚本中,如何测试文件?
答案:test命令可以用来测试文件。基础用法如下所示:
-d 文件名 如果文件存在并且是目录,那么返回true -e 文件名 如果文件存在,那么返回true -f 文件名 如果文件存在并且是普通文件,那么返回true -r 文件名 如果文件存在并可读,那么返回true -s 文件名 如果文件存在并且不为空,那么返回true -w 文件名 如果文件存在并可写,那么返回true -x 文件名 如果文件存在并可执行,那么返回true
真题19、在SHELL脚本中,如何写入注释?
答案:注释可以用来描述一个脚本可以做什么和它是如何工作的。每一行注释以#开头。例子如下:
#!/bin/bash # This is a command echo “I am logged in as $USER”
真题20、如何让 SHELL 就脚本得到来自终端的输入?
答案:read命令可以读取来自终端(使用键盘)的数据。read命令得到用户的输入并置于给出的变量中。例子如下:
# vi /tmp/test.sh #!/bin/bash echo 'Please enter your name' read name echo "My Name is $name" # ./test.sh Please enter your name lhr My Name is lhr
真题21、如何取消变量或取消变量赋值?
答案:“unset”命令用于取消变量或取消变量赋值。语法如下所示:
# unset <变量名> 例如: [oracle@lhrxxtoracle ~]$ echo $ORACLE_SID lhrdb [oracle@lhrxxtoracle ~]$ unset ORACLE_SID [oracle@lhrxxtoracle ~]$ echo $ORACLE_SID [oracle@lhrxxtoracle ~]$
真题22、如何执行算术运算?
答案:有两种方法来执行算术运算:
1.使用expr命令
[oracle@e-e-oracle ~]$ expr 5 + 2 7
2.用一个美元符号和方括号($[ 表达式 ]),例如:
[oracle@lhrxxtoracle ~]$ test=$[16 + 4] [oracle@lhrxxtoracle ~]$ echo $test 20
真题23、do-while语句的基本格式是什么?
答案:do-while语句类似于while语句,但检查条件语句之前先执行命令。do-while语句的语法:
do { 命令 } while (条件)
真题24、在SHELL脚本中如何定义一个函数?
答案:函数是拥有名字的代码块,示例如下所示:
[ function ] 函数名 [()] { 命令; [return int;] }
真题25、如何统计文件a.txt有多少非空行?
答案:
grep -c '^..*$' a.txt 或 grep -v '^$' a.txt | wc -l
真题26、文件b.txt,每行以“:”符分成5列,如“1:apple:3:2012-10-25:very good”,如何得到所有行第三列的总合值?
答案:
awk 'BEGIN {FS=":"; s=0} {s+=$3} END {print s}' b.txt
真题27、取文件c.txt的第60至480行记录,忽略大小写,统计出重复次数最多的那条记录,及重复次数。
答案:
sed -n '60,480'p c.txt | sort | uniq -i -c | sort -rn | head -n 1
真题28、如何生成日期格式的文件?
答案:在Linux/Unix上,使用“`date +%y%m%d`或$(date +%y%m%d)”,如:
touch exp_table_name_`date +%y%m%d`.dmp DATE=$(date +%y%m%d)
或者:
DATE=$(date +%Y%m%d --date '1 days ago') #获取昨天或多天前的日期
在Windows上,使用%date:~4,10%,其中4是开始字符,10是提取长度,表示从date生成的日期中,提取从4开始长度是10的串。如果想得到更精确的时间,那么在Windows上面还可以使用time。
真题29、如何测试磁盘性能?
答案:用类似如下的方法测试写能力:
time dd if=/dev/zero of=/oradata/biddb/testind/testfile.dbf bs=1024000 count=1000
期间系统I/O使用可以用iostat:
iostat -xnp 2 #显示Busy程度
真题30、如何格式化输出结果?
答案:可以使用column命令,如下所示:
[oracle@rhel6lhr ~]$ mount /dev/sda2 on / type ext4 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) tmpfs on /dev/shm type tmpfs (rw,size=2G) [oracle@rhel6lhr ~]$ mount | column -t /dev/sda2 on / type ext4 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) tmpfs on /dev/shm type tmpfs (rw,size=2G) [oracle@rhel6lhr ~]$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin [oracle@rhel6lhr ~]$ cat /etc/passwd | column -t -s: root x 0 0 root /root /bin/bash bin x 1 1 bin /bin /sbin/nologin
真题31、找出某个路径下以.conf结尾的文件,并将这些文件进行分类。
答案:可以通过使用xargs这个命令,将命令输出的结果作为参数传递给另一个命令。最终命令为:“find /home/oracle -name *.conf -type f -print | xargs file”,输出结果如下所示:
xargs后面不仅仅可以加文件分类的命令,还可以加其它的很多命令,比如说实在一点的tar命令。可以使用find命令配合tar命令,将指定路径的特殊文件使用find命令找出来,然后配合tar命令将找出的文件直接打包,命令如下:
# find / -name *.conf -type f -print | xargs tar cjf test.tar.gz
真题32、如何找出内存消耗最大的进程,并从大到小进行排序?
答案:命令为:ps -aux | sort -rnk 4 | head -20,结果如下所示:
输出的第4列就是内存的耗用百分比。最后一列就是相对应的进程。
也可以使用top命令,步骤如下:
① 在命令行提示符执行top命令
② 输入大写P,则结果按CPU占用降序排序。输入大写M,结果按内存占用降序排序。
真题33、如何找出CPU消耗最大的进程,并从大到小进行排序?
答案:命令为:ps -aux | sort -rnk 3 | head -20,结果如下所示:
输出的第3列就是CPU的耗用百分比。最后一列就是相对应的进程。
也可以使用top命令,步骤如下:
① 在命令行提示符执行top命令
② 输入大写P,则结果按CPU占用降序排序。输入大写M,结果按内存占用降序排序。
真题34、如何持续ping百度的地址并将结果记录到日志?
答案:使用如下命令,输出的结果会记录到/tmp/pingbd.log中,每秒钟新增一条ping记录:
ping www.baidu.com | awk '{ print $0" " strftime("%Y-%m-%d %H:%M:%S",systime()) }' >> /tmp/pingbd.log &
真题35、如何查看tcp连接状态?
答案:使用netstat命令,如下所示:
[root@rhel6lhr ~]# netstat -nat | awk '{print $6}'|sort|uniq -c|sort -rn 24 LISTEN 15 ESTABLISHED 1 TIME_WAIT 1 Foreign 1 established) 1 CLOSE_WAIT
真题36、如何查找80端口请求数最高的前20个IP地址?
答案:有时候业务的请求量突然上去了,那么这个时候可以查看下请求来源IP情况,如果是集中在少数IP上的,那么可能是存在攻击行为,需要使用防火墙进行封禁。命令如下:
netstat -anlp|grep 80|grep tcp|awk '{print $5}'|awk -F: '{print $1}'|sort|uniq -c|sort -nr|head -n20
结果如下所示:
本文选自《Oracle程序员面试笔试宝典》,作者:李华荣。