shell 常见面试

时间:2021-04-17 05:38:53

1、求100以内的质数

#!/bin/bash
n=
for((i=;i<=n;i++))
do
for((x=;x<=i;x++))
do
b=$(( $i%$x ))
if [[ $b -eq ]]; then
a=$a+
fi
done
if [[ $a -eq ]]; then
echo $i " "
fi
a=
done
echo

执行结果

[root@auto hzb]# sh zhishu.sh 

 2、查看dockerps.log的第3行的第1列

[root@auto hzb]#
[root@auto hzb]# cat dockerps.log
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b78a979df924 hub.chinacloud.com.cn/fast-pulsar.dev/pulsar-pkg-ui-all-in-one: "/entrypoint.sh nginx" days ago Up days /tcp, 0.0.0.0:->/tcp pulsar-pkg-ui-all-in-one
d27e04e08e94 hub.chinacloud.com.cn/fast-pulsar.dev/portal: "nginx -g 'daemon off" weeks ago Up weeks /tcp, 0.0.0.0:->/tcp portal
a70779e0f1a8 hub.chinacloud.com.cn/fast-wh.dev/whitehole-event: "/apps/whitehole-even" weeks ago Up weeks (healthy) whitehole-event "docker-entrypoint.sh" months ago Up weeks (healthy) mysql
[root@auto hzb]# sed -n '3p' ./dockerps.log |cut -d " " -f1
d27e04e08e94

3、删除文件的最初三行

set -i '1,3d' ./dockerps.log

4、晚上11点到早上8点之前,每隔2小时,打印系统时间

[root@auto hzb]# cat date.sh
#!/bin/bash
echo -e "date is:\n"
date
echo  ,-/ * * * root /root/hzb/date.sh >>/etc/crontab

扩展:

crontab任务配置基本格式:
*   *  *  *  *  command
分钟(0-59) 小时(0-23) 日期(1-31) 月份(1-12) 星期(0-6,0代表星期天)  命令

第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

  * * * /home/testuser/test.sh
每天晚上1点调用/home/testuser/test.sh */ * * * * /home/testuser/test.sh
每10钟调用一次/home/testuser/test.sh * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每晚的21:30重启apache。 ,, * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每月1、、22日的4 : 45重启apache。 * * , /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每周六、周日的1 : 10重启apache。 , - * * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。 * * /usr/local/etc/rc.d/lighttpd restart
上面的例子表示每星期六的11 : pm重启apache。 * */ * * * /usr/local/etc/rc.d/lighttpd restart
每一小时重启apache * -/ * * * /usr/local/etc/rc.d/lighttpd restart
晚上11点到早上7点之间,每隔一小时重启apache * mon-wed /usr/local/etc/rc.d/lighttpd restart
每月的4号与每周一到周三的11点重启apache jan * /usr/local/etc/rc.d/lighttpd restart
一月一号的4点重启apache */ * * * * /usr/sbin/ntpdate 210.72.145.44
每半小时同步一下时间

 5、如何将本地80端口的请求转发到8080端口,当前主机IP为172.16.0.166

   /sbin/iptables -t nat -A PREROUTING -p tcp --dport  -j DNAT --to 172.16.0.166:

   /sbin/iptables -t nat -A PREROUTING -p tcp --dport  -j REDIRECT --to 

6、获取java进程的pid

[root@auto hzb]# ps -ef|grep java|tr -s " "|cut -d " " -f2

ps的输出字段间会有多个空格,所以直接用cut并不合适,用tr压缩连续空格后用cut

扩展:语法:tr [–c/d/s/t] [SET1] [SET2]
SET1: 字符集1
SET2:字符集2
-c:complement,用SET2替换SET1中没有包含的字符
-d:delete,删除SET1中所有的字符,不转换
-s: squeeze-repeats,压缩SET1中重复的字符
-t: truncate-set1,将SET1用SET2转换,一般缺省为-t

echo aaacccddd | tr -s [a-z]
acd

将语句中所有的小写字母变成大写字母,其中-t可省略

echo "Hello World I Love You" |tr -t [a-z] [A-Z]
HELLO WORLD I LOVE YOU

删除指定字符

$ cat test.txt
Monday :
Tuesday :
Wednesday :

-d代表删除,[0-9]代表所有的数字,[: ]代表冒号和空格

$ cat test.txt | tr -d "[0-9][: ]"
Monday
Tuesday
Wednesday

 7、将当前目录下大于10944的文件转移到当前目录的bak下

#!/bin/bash
fileinfo=($(du ./*))
length=${#fileinfo[@]}
for((i=0;i<$length;i=$((i+2 ))));
do
if[ ${fileinfo[$i]} -le 10 ];then
mv ${fileinfo[$((i+1 ))]} ./bak/
fi
done

分析:du ./*的内容如下:

[root@auto test]# du ./*
0 ./bak
4 ./docker-compose.yml
4 ./header.json
8 ./test.conf
4 ./test.env
4 ./testmv.sh
289228 ./test.tar
98056 ./test.tar.gz
10944 ./test.tbz
分析:($(du ./*))
[root@auto test]# echo ${fileinfo[@]}
./docker-compose.yml ./header.json ./test.conf ./test.env ./testmv.sh ./test.tar ./test.tar.gz ./test.tbz

 8、linux下面的sed和awk的编写

1)如何显示文本file.txt中第二大列大于56789的行?

awk -F "," '{if($2>56789){print $0}}' file.txt

$0表示整个当前行,$1表示每行第一个字段

2)显示file.txt的1,3,5,7,10,15行?

  sed -n "1p;3p;5p;7p;10p;15p" file.txt

  awk 'NR==1||NR==3||NR==5||…||NR=15{print $0}' file.txt

3)将file.txt的制表符,即tab,全部替换成"|"

sed-i "s#\t#\|#g" file.txt

9、请用Iptables写出只允许10.1.8.179 访问本服务器的22端口。

  /sbin/iptables -A input -p tcp -dport  -s 10.1.8.179 -j ACCEPT

  /sbin/iptables -A input -p udp -dport  -s 10.1.8.179 -j ACCEPT

  /sbin/iptables -P input -j DROP

10、假设有一个脚本scan.sh,里面有1000行代码,并在vim模式下面,请按照如下要求写入对应的指令

)将shutdown字符串全部替换成reboot

  :%s/shutdown/reboot/g

)清空所有字符

  :%d

)不保存退出

  q!

11、找出系统内大于50k,小于100k的文件,并删除它们。

  #!/bin/bash

  file=`find / -size +50k -size -100k`

  for i in $file;do

      rm -rf $i

  done

12、脚本(如:目录dir1、dir2、dir3下分别有file1、file2、file2,请使用脚本将文件改为dir1_file1、dir2_file2、dir3_file3) 

  #!/bin/bash

  file=`ls dir[]/file[]`

  for i in $file;do

      mv $i ${i%/*}/${i%%/*}_${i##*/}

  done
${i%/*}:从右边删除最短匹配,比如dir1/file1,删除/*后,变成dir1
${i%%/*}:从右边删除最长匹配,比如dir1/file1,删除/*后,变成dir1,因为只有一个/,最短和最长匹配是一样的。
${i##*/}:从左边删除最长匹配:比如dir1/file1,删除*/后,变成file1

13、 如何计算传递进来的参数 ?

$#

14 、如何在脚本中获取脚本名称 ?

$0

15、 如何检查之前的命令是否运行成功 ?

$?

16、 如何获取文件的最后一行 ?

tail-1

17、如何获取文件的第一行 ?

head-1 

18、假如文件中每行第一个元素是 FIND,如何获取第二个元素

awk'{ if ($1 == "FIND") print $2}'

19、如何进行两个整数相加 ?

A=
B=
echo $(($A+$B)) # 方法
echo $[$A+$B] # 方法
expr $A + $B # 方法
echo $A+$B | bc # 方法
awk 'BEGIN{print '"$A"'+'"$B"'}' # 方法

20、判断是否存在

if [ ! -d "/data/" ]  #判断目录不存在
if [ -d "/data/" ] #判断目录存在
if [ ! -f "/data/filename" ] #判断文件不存在
if [ -f "/data/filename" ] #判断文件不存在 -e 判断对象是否存在
-d 判断对象是否存在,并且为目录
-f 判断对象是否存在,并且为常规文件
-L 判断对象是否存在,并且为符号链接
-h 判断对象是否存在,并且为软链接
-s 判断对象是否存在,并且长度不为0
-r 判断对象是否存在,并且可读
-w 判断对象是否存在,并且可写
-x 判断对象是否存在,并且可执行
-O 判断对象是否存在,并且属于当前用户
-G 判断对象是否存在,并且属于当前用户组
-nt 判断file1是否比file2新 [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧 [ "/data/file1" -ot "/data/file2" ]

[ -z STRING ] “STRING” 的长度为零则为真。

[ -n STRING ] or [ STRING ] “STRING” 的长度为非零 non-zero则为真。

21、写出 shell 脚本中所有循环语法 ?

for:

for i in $(ls);do

echo item:$i

done

while:

#!/bin/bash
COUNTER=
while [ $COUNTER -lt ]; do
echo The counter is $COUNTER
let COUNTER=COUNTER+
done

until:

#!/bin/bash
COUNTER=
until [ $COUNTER -lt ]; do
echo COUNTER $COUNTER
let COUNTER-=
done

22、如何获取文本文件的第 10 行 ?

head - file|tail -

23、命令:[ -z "" ] && echo 0 || echo 1 的输出是什么


 24、name=John && echo 'My name is $name' 的输出是什么

My name is $name

 25、name=John && echo “My name is $name” 的输出是什么

My name is John

26、如何只用 echo 命令获取字符串变量的一部分 ?

echo ${variable:x:y}
x - 起始位置
y - 长度

例子:

variable="My name is Petras, and I am developer."
echo ${variable::} # 会显示 Petras

27、如果给定字符串 variable="User:123:321:/home/dir",如何只用 echo 命令获取 /home/dir ?

echo ${variable##*:}

28、如何使用 awk 列出 UID 小于 100 的用户 ?

awk -F: '$3<100' /etc/passwd

29、如何在 bash shell 中更改标准的域分隔符为 ":" ?

IFS=":"

30、如何打印变量的最后 5 个字符 ?

[root@auto ~]# str="aaaaaaaaaa"
[root@auto ~]# echo ${str: -}
aaaaa
[root@auto ~]# echo ${str:-}
aaaaaaaaaa
[root@auto ~]# str="aaaabbbb"
[root@auto ~]# echo ${str: +}
bbb

31、将test.txt中的内容以大写显示

[root@auto ~]# cat test.txt
aaaa
bbbb
cccc
[root@auto ~]# cat test.txt |tr a-z A-Z
AAAA
BBBB
CCCC

32、wc的用法:

[root@auto ~]# cat test.txt
aaaa
bbbb
ccccc
[root@auto ~]# cat test.txt|wc -l [root@auto ~]# cat test.txt|wc -c [root@auto ~]# cat test.txt|wc -m [root@auto ~]# cat test.txt|wc -w [root@auto ~]# cat test.txt|wc -L

-c 统计字节数。

-l 统计行数。

-m 统计字符数。这个标志不能与 -c 标志一起使用。

-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。

-L 打印最长行的长度。

33、列出第二个字母是 e或z的文件或目录 

[root@auto ~]# ls
anaconda-ks.cfg hzb java0.log java1.log java1.log.lck test.txt
[root@auto ~]# ls -d ?[ez]*
hzb test.txt

如果是第三个字母:ls -d ??[ez]*

34、如何去除字符串中的所有空格

[root@localhost ~]# str="aa  vvvvvv ccc   dd"
[root@localhost ~]# echo $str|tr -d " "
aavvvvvvcccdd

35、写出输出数字 0 到 100 中 3 的倍数(0 3 6 9 …)的命令 ?

for i in {....}; do echo $i; done

for (( i=; i<=; i=i+ )); do echo "Welcome $i times"; done

36、如何打印传递给脚本的所有参数 ?

echo $*

echo $@

37、[ $a == $b ] 和 [ $a -eq $b ] 有什么区别

[ $a == $b ] - 用于字符串比较
[ $a -eq $b ] - 用于数字比较

38、如何检查字符串是否以字母 "abc" 开头 ?

[[ $string == abc* ]]

39、[[ $string == abc* ]] 和 [[ $string == "abc*" ]] 有什么区别

  • [[ $string == abc* ]] - 检查字符串是否以字母 abc 开头
  • [[ $string == "abc*" ]] - 检查字符串是否完全等于 abc*

40、如何列出以 ad 或 ma 开头的用户名 ?

[root@auto hzb]# egrep "^ad|^ma" /etc/passwd|cut -d: -f1
adm
mail

41、$#,$*,$@,$$的用法 

$# 是传给脚本的参数个数

$0 是脚本本身的名字
$1 是传递给该shell脚本的第一个参数
$2 是传递给该shell脚本的第二个参数
$@ 是传给脚本的所有参数的列表
$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9
$$ 是脚本运行的当前进程ID号
$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误
#!/bin/bash
IFS=":";
echo $#
echo $*
echo $@
echo "$*"
echo "$@"
echo $$
echo $?
echo $!
IFS=" ";
[root@auto hzb]# ./test.sh  abc xyz

 abc xyz
abc xyz
:abc:xyz
abc xyz

$* 会根据 IFS 的不同来组合值,而 $@ 则会将值用" "来组合值!

42、数组的一些操作 ?

[root@auto hzb]# arr=("xx" "aa" "yy" "bb") -定义数组
[root@auto hzb]# echo ${arr[]} -打印第一个元素
xx
[root@auto hzb]# echo ${arr[@]} -打印全部元素
xx aa yy bb
[root@auto hzb]# echo ${!arr[@]} -打印每个元素的下标 [root@auto hzb]# unset arr[] -删除第三个元素
[root@auto hzb]# echo ${arr[@]}
xx aa bb
[root@auto hzb]# arr[]="BBB" -重新给第一个元素设置值
[root@auto hzb]# echo ${arr[@]}
BBB aa bb