Shell
cat /etc/shells
ll | grep xxx
脚本以这个开头指定解析器
#!/bin/bash
echo "Hello World"
在home目录建一个homework.txt文件
touch /home/homework.txt
向homework.txt文件里面插入"My name is wwy."
echo "My name is wwy." >> /home/homework.txt
当前用户的根目录
echo $HOME
查看java的home路径
echo $JAVA_HOME
查看当前路径
echo $PWD
默认解析器
echo $USER
当前用户
echo $USER
自定义变量(注意不能有空格)
NUM=1024
取变量
echo $NUM
撤销变量
unset NUM
定义一个常量
readonly PI=3.14
明面上字符串,其实前面的也是字符串,是不能进行四则运算的。
name="wwy"
将变量提升为全局变量,供其它Shell程序使用
export 变量名
特殊变量$n
$n (n为数字 ,$0:代表脚本名称,$1-$9:代表9个参数,十以上的参数需要用大括号包含:${10})
如果在sh脚本里面写
echo "$1 $2"
然后在执行命令的时候 ./Xxx.sh param1 param2
这里param1会传到$1的位置,param2会传到$2的位置。
$#: 获取所有输入的参数个数,常用于循环
sh xxx.sh aaa bbb
会打印出 xxx.sh aaa bbb
echo $#
2
$*: 获取命令行中所有的参数,并将它们看成一个整体。
$@: 获取命令行中所有的参数,并把每个参数区分对待。
echo $*
echo $@
$?: 最后一次命令的返回状态.0:为命令正确执行,非0:表示上一个命令执行不正确。
运算符
基本语法
$((运算式)) 或 $[运算式]
或
expr + - \* / %
注意:expr和数字,数字与运算符之间需要有空格
例子:
3+2
expr 3 + 2
(1+2)*3
num=$[(2+3)*4]
echo $num
或者
expr `expr 1 + 2` \* 3
条件判断
比较运算符
= 字符串比较
-lt 小于(less than)
-le 小于等于(less equal)
-eq 等于(equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
-ne 不等于(not equal)
例子:2 > 1
[ 2 -gt 1]
如果是0表示正确,非0表示错误
echo $flag
按照文件权限判断
-r 可读文件(read)
-w 可写文件(write)
-x 可执行文件(execute)
例子:wwy.sh是否有权限写
[ -w wwy.sh ]
如果是0表示正确,非0表示错误
echo $?
按照文件类型判断
-f 文件存在是否式一个常规文件(file)
-e 文件存在(existence)
-d 文件存在是否是一个目录(directory)
例子:判断home目录是否有wwy.sh文件
[ -e /home/wwy.sh ]
echo $?
多条件逻辑与 && 、逻辑或 || 。
[ condition ] && echo OK || echo not OK
OK
[ condition ] && [ ] || echo not OK
not OK
流程控制
if基本语法:
if [ 条件判断表达式 ];then
程序
fi
或者
if [ 条件判断表达式 ]
then
程序
fi
注意:
中括号与条件之间必须要有空格,
if后要有空格,
结束是fi
#!/bin/bash
if [ $1 -eq 1 ];then
echo "这个是1"
elif [ $1 -ne 1 ];then
echo "这个不是1"
fi
case 基本语法:
case $变量名 in
"值1")
如果变量的值等于值1,则执行程序1
;;
"值2")
如果变量的值等于值2,则执行程序2
;;
*)
如果变量的值不是以上的值,则执行此程序
;;
esac
注意:
case行尾必须为单词 in ,每一个模式匹配必须以右括号 ) 结束
双分号 ;; 表示命令结束,相当于java中的break
最后的 *) 表示兜底,相当于java中的default
#!/bin/bash
case $1 in
1)
echo "aaa";;
2)
echo "bbb";;
*)
echo "其它值";;
esac
for循环基本语法:
格式一
for(( 初值;循环控制条件;变量变化))
do
程序
done
1加到100
#!/bin/bash
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo $s
格式二
for 变量 in 值1 值2 值3 ...
do
程序
done
打印所有输入参数
#!/bin/bash
for i in $*
do
echo "结果: $i"
done
./Xxxx.sh aaa bbb ccc wwy 123
结果: aaa
结果: bbb
结果: ccc
结果: wwy
结果: 123
#!/bin/bash
for i in "$*"
do
echo "结果: $i"
done
for j in "$@"
do
echo "结果: $j"
done
./Xxxx.sh aaa bbb ccc wwy 123
结果:aaa bbb ccc wwy 123
结果: aaa
结果: bbb
结果: ccc
结果: wwy
结果: 123
while 循环基本语法:
while [ 条件判断 ]
do
程序
done
从1加到100
#!/bin/bash
i=1
while [ $i -le $1 ]
do
s=$[$s+$i]
i=$[$i+1]
done
echo $s
read读取控制台输入
基本语法
read(选项)(参数)
选项:
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒)
参数:
变量 指定读取值的变量名
#!/bin/bash
read -t 7 -p "输入你的名字(在十秒内)" NAME
echo $NAME
函数
系统函数
1.basename 基本语法:
basename [string/pathname][suffix]
(basename命令会删除掉所有的前缀包括最后一个‘/’字符,然后将字符串显示出来)
选项:
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
basename /home/data/log/2022-1-1.log .log
2022-1-1
2.dirname 基本语法
获取文件的路径
dirname /home/data/log/2022-1-1.log .log
/home/data/log
自定义函数 基本语法:
[ function ] funname[()]
{
Action
[return int;]
}
funname
注意:
函数声明必须在调用之前
函数返回值,只能通过 $? 系统变量获得;
可以显示加 return 返回,如果不加将以最后一条命令运行结果作为返回值return后跟数值n(0-255)
求俩个参数的和
#!/bin/bash
function sum()
{
s=0
s=$[$1+$2]
echo $s
}
read -p "input num1 " NUM1
read -p "input num2 " NUM2
sum $NUM1 $NUM2
Shell常用工具
cut
cut的工作就是剪,主要就是剪切数据用的。可以从文件的每一行剪切字节、字符和字段,并将这些字节、字符和字段输出出来。
基本用法:
cut [选项参数] filename
参数:
-f 列号,提取第几列
-d 分割符,按照指定分隔符分割列
说明:默认分割符是制表符(Tab)
data.txt文件
a|b
c|d
e|f
cut -d "|" -f 1 data.txt
结果
a
c
e
cut -d "|" -f 2 data.txt
b
d
f
cut -d "|" -f 1,2 data.txt
ab
cd
ef
cat data.txt | grep c | cut -d "|" -f 2 >> result_data.txt
生成的result_data.txt文件里面内容:
d
获取系统变量PATH,并按照:分割,取第二个:(第三段)
echo $PATH
echo $PATH | cut -d ":" -f 3
获取系统变量PATH,并按照:分割,取第二个:以后的
echo $PATH | cut -d ":" -f 3-
sed
sed是流编辑器,它是一次处理一行内容。处理时把当前处理的行存储在临时缓冲区中,称为"模式空间"接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容没有改变,除非你使用重定向储存输出。
sed[选项参数] 'command' filename
选项参数:
-e 直接在指令列模式上进行sed的动作编辑
命令功能描述
a 新增,a的后面可以接字符串,在下一行出现
d 删除
s 查找并替换
在data.txt第二行增加name:wwy
sed "2a name:wwy" data.txt
a|b
c|d
name:wwy
e|f
在data.txt删除包含name的那行数据
sed "/name/d" data.txt
a|b
c|d
e|f
将d替换成wwy
sed "s/d/wwy/g" data.txt
将第三行删除,并将d替换成wwy
sed -e "2d" -e "s/d/wwy/g" data.txt
awk
一个强大的文本分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行处理。
基本语法
awk [选项参数] ‘pattern1{action1} pattern2{action2}...’ filename
pattern:表示awk在数据中查找的内容(一般采用正则表达式匹配)。
action:在找到匹配内容时所执行的一系列命令。
选项参数:
-F: 指定输入文件 分隔符
-v: 赋值一个用户定义变量
将/etc/passwd 文件拷出来
cp /etc/passwd /home/dada
以":"分割取第二列
awk -F / '{print $2}' passwd
以"/"分割取第二列
awk -F : '{print $2}' passwd
搜索passwd文件以root关键字开头的所有行,并输出该行的第七列。
awk -F: '/^root/ {print $7}' passwd
搜索passwd文件以root关键字开头的所有行,并输出该行的第一列和第七列,中间用","分割开。
awk -F : '/^root/ {print $1 "," $7}' passwd
只显示第一列和第七列,并以","分割且在第一行添加表头"user,shell" 最后一行添加"END"
awk -F: 'BEGIN{print "user,shell"} {print $1","$7} END{print "END"}' passwd
将password文件中的用户id(第三列)增加数值1并输出
awk -F : -v i=1 '{print $3+$i}' passwd
awk内置变量
FILENAME 文件名
NR 已读行数
NF 切割后列的个数
取当前机子ip
ifconfig eth0|grep inet |grep broadcast | awk -F' ' '{print $2}'
找到当前机子里面所有运行的java程序的进程PID
ps -ef|grep java|grep .jar | awk -F ' ' '{print $2}'
查询data.txt文件中空行所在的行号
awk '/^$/{print NR}' data.txt
sort
将文件排序,并将排序结果输出
sort 基本语法:
sort(选项)(参数)
选项
-n 按照数值大小排序
-r 以相反的顺序来排序
-t 设置排序时所用到的分割字符
-k 指定需要排序的列
参数:指定待排序的文件列表
将/home/log文件夹里面的文件(格式:2022-1-24)按照倒序排序,并将结果输出到/home/log
/log.log文件中
cd /home/log ls | sort -t '-' -nrk 3 >> /home/log/log.log
常见面试题
写一个Shell脚本检查一个文件是否存在
#!/bin/bash
if [ -f file.txt ];then
echo "文件存在"
else
echo "文件不存在"
fi
用Shell写一个脚本,对文本中无序的一列数字排序
cat test.txt
8
5
7
2
9
1
sort -n test.txt|awk '{a+=$0;print $0} END{print "SUM="a}'
1
2
5
7
8
9
SUM=32
用shell脚本写出查找当前文件夹(/home)下所有的文本文件内容包含有字符"wwy"的文件名称
grep -r "wwy" /home
/home/test.sh:touch wwy.txt
/home/test.sh:echo "I love you" >> wwy.txt
grep -r "wwy" /home | cut -d ":" -f 1
/home/test.sh
/home/test.sh