前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【DB笔试面试275】 与SHELL脚本相关的一些笔试面试题(目前37道,后续持续更新)

【DB笔试面试275】 与SHELL脚本相关的一些笔试面试题(目前37道,后续持续更新)

作者头像
小麦苗DBA宝典
发布2019-09-29 15:37:40
1.8K0
发布2019-09-29 15:37:40
举报

本小节以几道真题为例,简单讲解与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

结果如下所示:

真题37、如何使用SHELL脚本来查看多个服务器的端口是否打开?

答案:在配置服务器的时候,需要经常查看服务器的某个端口是否已经开放。如果服务器只有一两台的话,那么只需要使用nc命令查看即可。但是,如果有很多个服务器的话,那么在这种情况下,可以使用SHELL脚本配合nc命令来检查端口的开放情况。不管服务器有几台,需要检查的端口有几个,使用SHELL脚本都可以实现。

nc是英文单词netcat的缩写,它是通过使用TCP或UDP的网络协议的连接来读或写数据,可以直接被第三方程序或脚本直接调用。同时,它是一款功能非常强大的网络调试工具,因为它可以创建几乎所有需要的连接方式。

nc工具主要有三种功能模式:连接模式、监听模式和通道模式。它的一般使用格式如下:

nc [-options] [HostName or IP] [PortNumber]

其中一些参数的已:

-g<网关>:设置路由器跃程通信网关,最多设置8个
-G<指向器数目>:设置来源路由指向器,其数值为4的倍数
-h:在线帮助
-i<延迟秒数>:设置时间间隔,以便传送信息及扫描通信端口
-l:使用监听模式,监控传入的资料
-n:直接使用IP地址,而不通过域名服务器
-o<输出文件>:指定文件名称,把往来传输的数据以16进制字码倾倒成该文件保存
-p<通信端口>:设置本地主机使用的通信端口
-r:指定源端口和目的端口都进行随机的选择
-s<来源位址>:设置本地主机送出数据包的IP地址
-u:使用UDP传输协议
-v:显示指令执行过程
-w<超时秒数>:设置等待连线的时间
-z:使用0输入/输出模式,只在扫描通信端口时使用

例如:

[root@rhel6lhr home]# nc -zvw3 192.168.59.130 22
Connection to 192.168.59.130 22 port [tcp/ssh] succeeded!
[root@rhel6lhr home]# nc -zvw3 192.168.59.130 1521
Connection to 192.168.59.130 1521 port [tcp/ncube-lm] succeeded!

(1) 使用SHELL脚本完成情景一:扫描多台服务器的一个端口是否打开。

先把需要查询的所有服务器地址全部放在一个server-list.txt文件里,每个地址单独一行,如下所示:

# cat server-list.txt
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5

然后再用for循环依次扫描server-list.txt里对应服务器的端口是否打开,SHELL脚本(port_scan.sh)如下所示:

#!/bin/sh
for server in `more server-list.txt`
do
  nc -zvw3 $server 22
done

再然后,给这个脚本赋予可执行权限即可:

$ chmod +x port_scan.sh

最后,就可以用这个脚本来自动依次检查多个服务器的22端口是否已打开:

# sh port_scan.sh

Connection to 192.168.1.2 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.3 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.4 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.5 22 port [tcp/ssh] succeeded!

(2) 使用SHELL脚本完成情景二:扫描多台服务器的多个端口是否打开。

先把需要查询的所有服务器地址全部放在一个server-list.txt文件里,每个地址单独一行,如下所示:

# cat server-list.txt
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5

与此同时,把需要查询的服务器端口放在另一个port-list.txt文件里,每个端口单独一行,如下所示:

# cat port-list.txt
22
80

然后,再用for循环依次扫描server-list.txt里对应服务器port-list.txt所列的端口是否打开。需要注意的是,此时应该使用两个for循环,第一层是服务器列表,第二层是端口列表,SHELL脚本(multiple_port_scan.sh)如下所示:

#!/bin/sh
for server in `more server-list.txt`
do
   for port in `more port-list.txt`
   do
      nc -zvw3 $server $port
   echo ""
   done
done

再然后,给这个脚本赋予可执行权限即可。

$ chmod +x multiple_port_scan.sh

最后,就可以用这个脚本来自动依次检查多个服务器的多个端口是否已打开:

# sh multiple_port_scan.sh
Connection to 192.168.1.2 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.2 80 port [tcp/http] succeeded!

Connection to 192.168.1.3 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.3 80 port [tcp/http] succeeded!

Connection to 192.168.1.4 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.4 80 port [tcp/http] succeeded!

Connection to 192.168.1.5 22 port [tcp/ssh] succeeded!
Connection to 192.168.1.5 80 port [tcp/http] succeeded!

本文选自《Oracle程序员面试笔试宝典》,作者:小麦苗

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DB宝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档