Linux面试题主要分为以下部分:
Shell方面、
磁盘(逻辑卷,开机挂载)、
网络(查看网络接口,流量、路由)、防火墙(iptables表链,firewalld)、
常用的命令(编辑文件3剑客awk,sed,grep),
定时任务,
find命令,
linux的文件3个时间
一、Shell
1、shell诊断工具。
bash -x 进行调试。
bash -n 做语法检查。
2、if 判断文件存在的参数,是否是文件,是否是目录。
-d当pathname存在并且是一个目录时,返回true。记忆方法,-d是directory的简写。
-e当pathname指定的文件或目录存在时,返回true。exist的简写。
-f当file存在并且是正规文件,返回true。file的简写
-h当file存在并且是符号链接文件时。
-s当file存在文件大小大于0时返回真,s是size简写。
例子:
if [-e /var/log/syslog ]
3、函数定义和调用。
#function关键字可选,可写可不写。
#your_function_name部分----为函数名
#注意函数声明要小括号,调用函数是不要使用括号(即如testFun()是不对的);调用传参数的时候也不需要括号,直接在函数名后面加参数。
#shell没有局部变量,和全局变量。
[ function ] your_function_name()
{
your_shell_commands;
[return int;]
}
testFun(){
echo $1
}
param="helloworld!"
testFun $param
#4、特别符号的,形式 说明
$! 后台运行的最后一个进程的ID号
$$ 脚本运行的当前进程ID号
$@ 返回每个参数。与$*相同,但是使用时加引号,并在引号中分别返回每个参数。
$# 传递到脚本的参数个数,有多少个。
$* 以一个单字符串显示所有向脚本传递的参数,
$*会把当前脚本的所有参数作为一个参数传递给子脚本。(在英文中,*字符有“所有”的意思)
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
$0 返回文件名,$1返回第一个参数。
$n 返回调用的每个参数。
5、括号区别。() (()) [] [[]]
#单小括号()
1)数组赋值或者初始化数组;a=(1 2 3)
2)子Shell赋值:小括号中的内容会开启一个子shell独立运行(面试回答前面这一句就行了,后面知道更好);括号中以分号连接,最后一个命令不需要;各命令和括号无需空格
3)实现多条命令集合,把多个命令写到一起,用小括号包括起来:新开多条命令来执行,各个命令之间用分号隔开,最后一个命令必须要分号来隔开;(echo "a";echo "b";)
4)与”$“结合实现命令替换:等同于`cmd` 扫描一遍命令行,发现了$(cmd)结构,便将$(cmd)中的cmd执行一次,得到其标准输出,再将此输出放到原来命令。此形式要注意使用的Shell类型。echo $(ls -l)
#双小括号(())
1)省略”$“进行算术运算,同时支持在括号内用,对多个表达式进行分割
2) 常用于算术运算比较,双括号中的变量可以不使用$,支持多个表达式用 ”,“ 来隔开)
[root@node4 <sub>]# v=$((2+2))
[root@node4 </sub>]# echo $v
4
3)支持跨进制运算.将十六进制转成十进制。
[root@node4 <sub>]# echo $((16#5f))
95
[root@node4 </sub>]# echo $((16#5))
5
#单中括号 []
1 这一点知道可以,可以不用回答)bash 的内部命令,[和test是等同的。if/test结构中的左中括号是调用test的命令标识,右中括号是关闭条件判断的。这个命令把它的参数作为比较表达式或者作为文件测试,并且根据比较的结果来返回一个退出状态码。
2)在进行比较运算时使用。test和[]中可用的比较运算符只有==和!=,两者都是用于字符串比较的,不可用于整数比较(即使你写的是整数,但是内部是作为字符串比较);整数比较只能使用-eq,-gt这种形式。不支持大于号小于号,如果实在想用,对于字符串比较可以使用转义形式,如果比较”ab”和”bc”:[ ab \< bc ],结果为真,也就是返回状态为0(否则就变成io重定向了)。
[root@node4 <sub>]# [ 1234 > 123 ]
[root@node4 </sub>]# echo $?
0
[root@node4 <sub>]# [ 1234 > 12333 ]
[root@node4 </sub>]# echo $?
0 #大于号这里使用有点问题
3)[ ]中的逻辑与和逻辑或使用-a 和-o 表示。
#test命令
test -z string 如果 string长度为零,则为真 [-z $myvar ]. zero单词。
test -n string 如果 string长度非零,则为真 [-n $myvar ]
#双中括号[[ ]]
①[[是 shell的关键字。并不是一个命令,[[ ]] 结构比[ ]结构更加通用。在[[和]]之间所有的字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换。
②支持字符串的模式匹配,使用=~操作符时甚至支持shell的正则表达式。字符串比较时可以把右边的作为一个模式,而不仅仅是一个字符串,比如[[ hello == hell? ]],结果为真。[[ ]] 中匹配字符串或通配符,不需要引号。
③使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。比如,&&、||、<和> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话,会报错。
④bash把双中括号中的表达式看作一个单独的元素,并返回一个退出状态码。
#[]和[[]]个人总结的对比(面试的时候背这个),(主要区分在几个方面:数学运算,逻辑比较&&、||,是否支持正则表达式,对比字符串时):
1、单中括号[是shell命令,在它包围的表达式是它的命令行参数,所以串比较符>和<需要转义,否则就变成io重定向了。
2、双中括号[[是shell关键字,不会做命令行扩展,所以<和>不需要进行转义。但是语法相对严格,如在[中可以用引号括起操作,[[则不行。如if [ "-z" "ab" ]。
3、[[可以做算术计算,[则不行。如if [[ 11+1 -eq 100 ]],而if [ 11+1 -eq 100 ]则会报错。
4、对比字符串时,[ 末尾一定要加上x(或者a、b等)一个字符,因为if [ $1x == "ab"x ]时如果没有了x ,并且$1是"",这个语句会翻译成if [ == "ab" ],左边相当于没有东西了,会报语法错误。或者使用[[ ]],就不需要x了。如if [[ $1 == a*a ]] 或者if [ $1x == a*ax ]
5、在使用"[ ]"时,如果使用"&&"或者"||"对多个条件进行连接,"&&"或者"||"必须在"[ ]"之外。
6、[ ]中的逻辑与和逻辑或使用-a 和-o 表示。
7、[]里面不支持正则表达式,[[]]支持。这个可以不说,问了再说。
二、磁盘
磁盘常用的命令:df -hT ,fdisk -l ,lsblk,blkid ,逻辑卷lvs,卷组vgs,物理卷pvs。
iostat命令查看磁盘的读写速度,磁盘的io。
三、网络
ss -ant , netstat -tunlp,ethtool ,ip addr ,ifconfig,iftop可以看到网络流量
如果1台服务器,有5个网口,查看哪个有链路,这里ifconfig不可以,ethtool ,ip a可以。
四、防火墙
iptables和firewalld都有着同样的目的(包过滤)
#几表几链?
<strong>四表五链:</strong>
一个表----->多个链链
一个链------->多个规则
Nat 表,Mangle 表,Filter 表,Raw 表
Filter表 : Filter表是iptables中使用的默认表,它用来过滤网络包。如果没有定义任何规则,Filter表则被当作默认的表,并且基于它来过滤。支持的链有INPUT 链,OUTPUT 链,FORWARD 链。
链就是位置共有五个:进路由(PREROUTING)、进系统(INPUT)、转发(FORWARD)、出系统(OUTPUT)、出路由(POSTROUTING)。input、prerouting、forward、postrouting、output
#常用命令
iptable -nL
firewall-cmd status
五、编辑文件三剑客gred,sed,awk
#grep
grep e test.sh -c #显示有几行,通常常用wc -l替代这个命令。
grep e test.sh -n #显示行号
-r, --recursive
-w, --word-regexp
-q #执行成功也不提示信息,静默执行,就不会输出信息了。
#sed部分
sed “sed是一种流编辑器,它是文本处理中非常好的工具,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。
他可以实现功能:替换,删除,查找某个开头的行。也可以匹配正则表达式。
sed 's/要被取代的字串/新的字串/g' filename #全部替换,如果没加g就替换每一行的第一个字符,亲测试过。注意我这里没有加-i参数,是不会影响到源文件的。
sed -n '2'p /etc/passwd --打印第2行到屏幕,-n参数指将第2行外的无关紧要内容不显示。
sed -n '1,$'p /etc/passwd --打印1-尾行
sed'也可以用于删除行,把p替换成字母d
sed -n '/^1/'p test.txt #匹配所有以1开头的行。
sed -n '/in$/'p test.txt #匹配所有以in结尾的行。
#awk部分
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。名字由来是因为叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。
awk '{print $1,$4}' log.txt # 每行按空格或TAB分割,输出文本中的1、4项
awk -F ':' '{print $1}' /etc/passwd #输出用户名
六、服务文件
1、服务文件,默认有几个部分?
ssh为例:3个,unit(概述),service(执行的命令文件路径),install(在多用户模式下启动。)
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service
[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
七、常用的命令
7.1 find命令(常问)
find /tmp -name test
find /tmp -type d -name test
-type
f:普通文件
d: 目录
find /tmp -type d -size +16k -a -size -32k #根据文件大小查找,大于16,小于32
find /home/ -mtime -5 #5天之内被修改过的文件
find /home/ -atime -5 #5天之内被访问过
find /home/ -ctime -5 #5天之内文件属性,权限被修改过
find /var/log/ -type f -atime 5 第五天访问过的文件
#在整个目录树下查找文件 “core” ,如发现则无需提示直接删除它们?
find / -name core -exec rm {} \;
#按照时间搜索
有访问时间(atime),理解为access单词
数据修改时间(mtime),modify单词
状态修改时间(ctime),change time(ctime):状态修改时间
#选项:
-atime [+-]时间: 按照文件访问时间搜索
-mtime [+-]时间: 按照文改时间搜索
-ctime [+-]时间: 按照文件修改时间搜索(ctime 是change time 状态修改时间)
#这三个时间的区别我们在 stat 命令中已经解释过了,这里用 mtime 数据修改时间来举例,重点说说 "[+-]"时间的含义。
-5:代表@内修改的文件。
5:代表前5~6天那一天修改的文件。
+5:代表6天前修改的文件。
7.2 Linux下文件的三个时间参数(常问):
(1)access time(atime):最后访问时间
当需要了解这个文件最后被查看的时间,这里的访问时间是指文件被读取,而更新的时间。
(2)modification time(mtime):内容修改时间
这里的修改时间指的是文件的内容发生变化,而更新的时间。
(3)change time(ctime):状态修改时间
这里的修改时间指的是文件的属性或者权限发生变化,而更新的时间。
#在Linux下操作命令分别为:
ls -l 获取文件最后一次内容修改的时间(modification time(mtime))
ls -lc 获取文件最后一次访问的时间(change time(ctime))
ls -lu 获取文件最后一次状态的改变时间(access time(atime))
[root@node4 <sub>]# stat test.sh
File: ‘test.sh’
Size: 109 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 33621497 Links: 1
Access: (0755/-rwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:admin_home_t:s0
Access: 2022-03-06 01:23:17.244812925 +0800
Modify: 2022-03-06 01:24:21.141819080 +0800
Change: 2022-03-06 01:32:42.425867364 +0800
Birth: -
[root@node4 </sub>]# ls -lu test.sh #显示atime,access time
-rwxr-xr-x. 1 root root 109 Mar 6 01:23 test.sh
[root@node4 <sub>]# ls -lc test.sh #显示ctime,change time状态修改时间
-rwxr-xr-x. 1 root root 109 Mar 6 01:32 test.sh
[root@node4 </sub>]#
[root@node4 ~]# ls -l test.sh #显示修改内容时间,modify time
-rwxr-xr-x. 1 root root 109 Mar 6 01:24 test.sh
#总结:
1、新创建文件的时候3个时间相等。
2、如果是vi编辑这个文件修改内容,3个时间都变了,表示被查看时间,文件内容,文件属性都变动。
3、如果是用echo aa >> test.sh 增加内容,文件的Modify、Change会被更新。
4、如果用chmod 修改文件权限,只会更新时间change。
5、如果用cat查看文件,只有access时间更新。
7.3 定时任务
crontab -e #编辑
-l #显示
[root@node4 ~]# cat /etc/crontab #记住每个参数含义。
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
7.4 系统日志
dmesg该命令会输出系统日志的最后 10 行。文件是/var/log/message ,还有另外一个文件/var/log/secure
八、其他综合性问题
1、禁止所有的用户登录
当你(如果你是系统管理员)不想让所有用户登录时(比如你要维护系统升级什么的),一个一个地去禁止用户登录,这将是很……无聊的事。而且还容易出错。下面有一种简洁有效的方式:
touch /etc/nologin ##如果该文件存在,那么Linux上的所有用户(除了root以外)都无法登录
#在/etc/nologin,写点什么,告诉用户为何无法登录
[root@node4 ~]# cat /etc/nologin
系统升级,时间2小时 #注意,只有root可以登录,但是root登录成功也会提示文件的内容信息,
2、如何在 /var 目录下找出 90 天之内未被访问过的文件?
输入命令:`find /var \! -atime -90` #其实就是查找90天内访问过的,取反
3、如何在 /home 目录下找出 120 天之前被修改过的文件?
输入命令:find /home -mtime +120
4、Linux 开机启动过程?
1、主机开机加电自检,加载 BIOS 硬件信息。
2、读取 MBR 的引导文件(GRUB、LILO)。
3、引导 Linux 内核。
4、运行第一个进程 init (进程号永远为 1 )。
5、进入相应的运行级别。
6、运行终端,输入用户名和mima。
5、普通用户在终端登录,和用客户端通过ssh登录,有什么不一样?
root在哪里登录都是一样。
admin为例,分别在终端和crt登录,执行w命令,看到tty和pts区别;执行env | wc -l看到环保变量数量不一样;执行nmcli general permissions看到网络权限不一样。自己去试试。
6、eval命令理解
eval会对后面的命令进行两遍扫描,如果第一遍扫描后,命令是个普通命令,则执行此命令;
如果命令中含有变量的间接引用,命令行将进行所有的置换,置换后再执行该命令。
[localhost ~] $ ;cat test
888
[localhost ~] $ ;word='cat test'
[localhost ~] $ ;echo $word
cat test
[localhost ~] $ ;eval $word #把$word解析为cat test,此时命令是:eval cat test ,那么会执行cat test命令
888
常用eval命令获取传给shell的最后一个参数,如果我们知道参数个数,我们想要查看最后一个参数的内容可以使用echo直接显示,如输入 a b两个参数我们可以用echo $2 来看最后一个参数。但是,如果我们不知道参数个数还想查看最后一个参数内容该怎么办?
[localhost ~] $ ;vi test
#!/bin/bash
eval echo "\$$#"
#若传2个参数,第一遍解析:斜杠是转义符,后面的$原封不动的输出;$#解析为参数个数2;eval echo $2
#第二遍就会执行echo $2,结果是2个参数。
[localhost ~] $ ;./test a b c
c
[localhost ~] $ ;./test a b
b