linux脚本i 讲解,linux&shell基础详解

linux基础指令

基础

查看指令帮助:

指令 --help

man 指令(更全、分页)

ls、ll

clear

pwd

cd

touch

mkdir -p /tmp/a/b/c #创建多级目录

cp:复制

历史指令:

history #查看当前用户所有历史指令。~/.bash_history。注:系统退出后才会保存

!xx #注:从历史指令中找最后一条以xx开头的指令并执行

echo:

echo "abc"

echo $PATH

rm:

-f:force

-r:recursive递归

rm -rf aa*.txt

cat:

cat a.txt

cat -n a.txt #-n显示行号。基本等价于: nl a.txt [nl 指令对于空行不算行号]

nl:查看文本(显示行号)

nl a.txt

head:

head -10 a.txt

tail:

tail -10 a.txt

tail -f a.txt #follow

more:支持分页(下一页:空格、上一页:b)

less:支持分页、搜索

useradd:

useradd xuan

passwd:

passwd xuan

userdel:

userdel xuan

chmod:

chmod u+rwx 1.txt

#注:u表示当前用户,还有g(group)、o(others);如果省略,则表示给u、g、o均添加权限

chmod 777 1.txt #注:r4、w2、x1

chown:

chown xuan:xuan 1.txt

top:查看cpu、内存实时状态

free:查看内存使用状态

free -h(human)

free -m(MB)

free -k(KB)

df:disk free查看磁盘使用

df -h(human)

ps:查看进程

ps -ef

netstat:监听网络端口

-a:all

-n:numeric

-l:listening

netstat -anl

kill:给指定进程传递信号。

kill -l

kill -9 pid

date:

date +%Y-%m-%d -> 20191030

date -d yesterday +%Y%m%d -> 20191029

date -d tomorrow +%Y%m%d -> 20191031

wc:统计

wc -l(line)

which:

which 在$PATH变量指定的路径中,搜索某个系统命令的位置【which find】

whereis:

whereis mysql 只能用于程序名的搜索

ifconfig:查看ip、网卡等信息

id:查看当前用户的id和组的id

diff:比两个文档的不同

diff a.txt b.txt

sleep:shell进程休眠一段时间

sleep 3

seq:序列

seq 10 100

ln:创建链接

ln -s /home/xuan myLink

tee:一边输出执行结果,一遍保存执行结果

sh a.sh | tee b.txt

hostname:修改宿主机名称

[admin@operator ~]$ hostname operator

查看系统信息:

uname -a

cat /proc/version(更全)

exit

exit <=> exit 0 退出并返回正常的标志

exit 1 退出并返回异常的标志

exit 0和exit 1的区别:

脚本a调用脚本b,要在a中判断b是否正常返回,就是根据exit 0 or 1来识别,用$?判断

脚本中引入其他脚本/属性文件:

. ./menu.sh #注:最前边有个“.”,后边是引入的文件

export:把子脚本中的变量(局部变量)导出成全局变量

alias:别名

alias aa='free -m'

unalias aa #解除别名

若想重启后还能用,vi并保存到~/.bashrc文件中

crontab:定时器

crontab -e 编辑

*/1 * * * * /home/xuan/1.sh

crontab -l 展示所有

crontab -r 删除所有

系统日志:/var/log/messages

向系统日志写消息:logger "xxxxx" #消息会自动追加到/var/log/messages

下载、安装:yum、wget、rpm、apt-get...(有的适用于CentOS,有的RedHat,有的Ubuntu),

以yum为例:

yum install redis

yum remove redis

vi/vim编辑器

命令行模式:

G:跳到文档最后一行

gg:调到文档第一行

x:删除当前光标所在的字符

nx:从光标向后删除n个字符

dd:删除当前行

ndd:删除当前及后n行

D:删除当前行光标后边所有字符

r:replace,替换当前光标的字符

yy:粘贴

p:paste复制

u:撤销

插入模式:

i:从当前行进入插入模式

o:从下一行进入插入模式

底行模式:

搜索 /

显示行号 :set nu

打包/压缩

05b52cd2a66f

tar 打包/压缩

-c: create

-v: view #查看视图

-f: file

-z: zip #压缩

-x: extract #抽取、解压

-t: list #不解压的情况下查看文件列表

tar -cvf a.tar * #打包当前目录所有文件

tar -czvf a.tar.gz *

#打包并压缩当前目录所有文件。建议对.tar文件压缩后的文件后缀改为.tar.gz

tar -tf a.tar #查看a.tar内部文件列表

tar -xvf a.tar #解压a.tar

#注:"tar -czvf a.tar.gz *" 等价于 "tar -cvf a.tar *" + "gzip a.tar"

gzip 压缩

gzip a.txt -> a.txt.gz #将a.txt压缩,自动变成a.txt.gz

gzip a.tar -> a.tar.gz #将a.tar压缩,自动变成a.tar.gz

gzip -d a.tar.gz #解压a.tar.gz得到a.tar

tar -zxvf a.tar.gz # 一次性两步:先解压得到a.tar,再解包得到a.tar内部所有文件

zip/unzip 压缩/解压

zip target.zip sourceFile #把sourceFile压缩成target.zip

unzip zipFile

unzip zipFile -d dir #解压到指定目录

shell

解释器

#!/bin/bash(默认可以不写) 解释器

#!/bin/sh 解释器

#注释

执行脚本

./shell.sh(需要执行权限)

sh shell.sh 或 bash shell.sh(读取执行~只需要读取权限)

source shell.sh

变量

a=3

$a 等价于${a}。但是 ${a}ook 和 $aook就不一样

$? 上一个指令是否正确执行,上一个脚本是否正常退出(1-不正确,0-正确)

$0 文件名

$1~$9 第几个参数值。# echo ${1:-daily},取脚本第一个参数,如果没有,则赋值daily

$# 一共几个参数

$* 所有入参

符号

| 管道符号:把前边的输出作为后边的输入

> 覆盖输出;>> 拼接输出

echo "abc" > a.txt

echo "abc" >> a.txt

; 一行执行多条语句的分隔符 cat a.txt ; ls

&& 前边语句成功才会执行后边语句 cat a.txt && ls

|| 前边语句失败才会执行后边语句

$$ : echo $$ -> 输出当前脚本的执行进程id

"" 输出变量值 a=10;echo "$a" -> 10

'' 输出本身 a=10;echo '$a' -> $a

`` 执行内部语法。echo `date` 等价于 $(date)

nohup [commond] & 后台运行

2> /dev/null 把错误输出扔进无底洞(2和>之间不要有空格)

1> /dev/null 把正确输出扔进无底洞(1和>不要有空格,可以省略1)

2>&1 错误输出合并到正确输出流

1>&2 正确输出合并到错误输出流

eg:

已有的shell指令中,输出结果既有正确又有错误的几乎没有,所以可以自定义shell脚本实现。

sh abc.sh 1> a.txt 2>&1 等价于:sh abc.sh &> a.txt

注:

& 是一个描述符,如果1或2前不加&,会被当成一个普通文件。

1>&2 意思是把标准输出重定向到错误输出.

2>&1 意思是把错误输出重定向到标准输出。

&>filename 意思是把标准输出和错误输出都重定向到文件filename

read

-t 阻塞时间

-s 隐藏输入的字符

-p 给出提示符

-n 读取字符的个数,个数到达临界之后会自动执行

read abc 把接下来输入的数据赋值给abc

read -t 10 -n 3 -p '请输入密码:' pass 注:把前边的输入传递给变量pass,-p要放在后边

echo -e "\n" #注:-e 表示escapes,开启转义符

echo "密码是:$pass"

eg:不换行输入用户名

read -p "请输入密码:" name

等价于:

echo -n "请输入密码:" #注:-n的作用是echo不换行

read name

计算器

整数:

expr 10 + 20 #注意+号两边的空格

echo $[10 + 20]

echo $((10 + 20))

echo $[10 % 3] 取余

echo $[10 \* 2] 乘法需要对*转义

bc计算器:

echo "scale=2;(1.2+2.3)/1" | bc #把前边的输出作为后边的输入。scale只对乘除有效

条件判断

[]

[ -e a.txt ] 方括号必须有左右空格。[ ! -e a.txt ] #叹号!表示取反

eg:[ -e a.txt ] && echo yes

-e exist 文件是否存在

-d directory 是不是目录

-f file 是不是文件

权限:

-r 是否有读权限

-w 是否有写权限

-x 是否有执行权限

整数比较:

-eq(equal)

-ne (not equal)

-gt (greater than)

-lt (lesser than)

-ge (greater or equal)

-le (lesser or equal)

小数比较:借助bc计算器

[ `echo "1.2 > 1" | bc` -eq 1 ] && echo '大于'

字符串:

= [ "1" = "1" ] && echo "相等"

!=

if

格式1:

if [ 条件 ];then

echo "xxx"

fi

格式2:

if [ 条件1 ];then

echo "xxx"

elif [ 条件2 ];then

echo "yyy"

else

echo "zzz"

fi

#拓展:[]和[[]]的其中一点区别(双括号要强大的多)

if [ $a -ne 1] && [ $a != 2 ]

等价于: if [[ $a != 1 && $a != 2 ]]

等价于: if [ $a -ne 1 -a $a != 2 ] #-a是and,-o是or

循环

for

示例1:

for i in 1 2 3 4 5 #注:in后边是"值1"、"值2"、"值3"...

do

if [ $i -eq 2 ];then

continue

else

echo "$i"

sleep 1

fi

done

示例2:

for i in $(cat www.txt)

do

ping -c 2 $i #注:-c表示最多ping几次。windows上是-n

done

示例3:((条件))

#注:i++相当于i=i+1,只能在(())中使用,等价于:let 'i+=1'

for (( i=1;i<11;i++ ))

do

echo $i

sleep 1

done

#注:for (( i=1;i<=$num;i++ ))报错:Syntax error: Bad for loop variable 奇怪

case

示例1:模拟天气预报-输入城市名称,输出城市温度

echo '请输入城市:'

read city

case $city in

'上海')

echo '上海:35度'

;;

'北京')

echo '北京:20度'

;;

*)

echo '未知城市'

esac #注:case倒叙

示例2:case接受简单正则

case $1 in

[a-z]|[A-Z])

echo "字母"

;;

[0-9])

echo "数字"

;;

esac

while

示例1:输入数字,并求1到该数字的和

sum=0

i=0

while [ $i -lt $1 ] #注:左右空格不能省略

do

sum=$(($sum+$i))

i=$[$i+1] #注:千万别忘了自增条件,否则就死循环了。等价于:((i++))

done

echo "从1加到$1的和是:$sum"

示例2:模拟菜单

while [ 1 ] #注:死循环会导致CPU骤升

do

#注:这里是cat不是echo;EOF是瞎写的,可以成对换成!或者abc;EOF之间的是原格式的纯文本

cat <

1.执行1.sh

2.执行2.sh

q.退出

EOF #末尾的EOF必须顶行写,且前后均不能有空格或tab

read -p '请选择:' key

case $key in

1)

clear

echo '执行1.sh'

;;

2)

clear

echo '执行2.sh'

;;

q)

clear

echo '退出'

break #注:break跳出循环

;;

esac

done

示例3:

num=0

while [ $# -gt 0 ]

do

num=$(($1+num))

echo "剩余参数:$*"

shift #将参数向左偏移一个

done

echo "总和:$num"

结果如下:

[root@localhost xuan]# sh 5.sh 1 2 3 4 5

剩余参数:1 2 3 4 5

剩余参数:2 3 4 5

剩余参数:3 4 5

剩余参数:4 5

剩余参数:5

总和:15

示例4:死循环

while true # 或 while : 或 while [ 1 ]

do

let i++

echo $i

sleep 1

done

例子

1.判断两个数是否相等

if [ $1 -eq $2 ];then 注:if后有空格

echo "$1等于$2"

else

echo "$1不等于$2"

fi

等价于:

[ $1 -eq $2 ] && echo "$1等于$2"

[ $1 -eq $2 ] && echo "$1不等于$2"

#注:多条件

if [ "a" = "a" ] && [ "b" = "b" ]

2.判断上一个指令是否执行成功

fName=22.txt

touch $fName

if [ $? -eq 0 ];then

echo "$fName创建成功"

fi

3.判断输入的数字是否大于10

echo '请输入一个数字:'

read number

if [ $number -eq 10 ];then

echo '等于10'

elif [ $number -lt 10 ];then

echo '小于10'

else

echo '大于10'

fi

4.越过交互:给用户xuan设置密码。需要交互两次

方式1:

passwd xuan < password.txt

#注:password.txt文件中有两行相同的密码

方式2:

passwd xuan <

123

123

EOF #注:末尾的EOF必须顶行写,不能有空格或tab

sh a.sh <

土豆

root

EOF

方式3:

echo 123 | passwd --stdin xuan

#注:passwd的--stdin参数ubuntu不支持,centos才可以

函数

示例1:两数求和

function add(){

echo $(($1+$2))

}

add 10 20

示例2:遍历指定目录下所有目录

function listFiles() {

for file in `ls $1`

do

dir=$1"/"$file

if [ -d $dir ];then

ls $dir

listFiles $dir

fi

done

}

listFiles $1

信号捕捉

#trap 捕获信号;2表示ctrl+c;3表示ctrl+\;kill -l可以获取到所有信号指令

trap 'myFunc' 2 3

function myFunc(){

read -p '确定终止吗? y or n' input

case $input in

'y')

exit

;;

'n')

;;

*)

myFunc

;;

esac

}

#以下的死循环防止程序退出

while true # 或 while : 或 while [ 1 ]

do

let i++

echo $i

sleep 1

done

split

1.文件按行数分割

split -100 a.txt aaa #-100表示100行分割一次,aaa表示分割后的文件名前缀,后缀是自动生成的

eg:

split -3 a.txt xuan

得到:

-rw-r--r--. 1 root root 127 Oct 15 13:17 a.txt

-rw-r--r--. 1 root root 29 Oct 15 14:23 xuanaa

-rw-r--r--. 1 root root 47 Oct 15 14:23 xuanab

-rw-r--r--. 1 root root 17 Oct 15 14:23 xuanac

-rw-r--r--. 1 root root 8 Oct 15 14:23 xuanad

-rw-r--r--. 1 root root 25 Oct 15 14:23 xuanae

-rw-r--r--. 1 root root 1 Oct 15 14:23 xuanaf

2.文件按固定大小分割

split -b 1M a.txt

3.文本合并,可以借助cat

cat xuan* > a.txt

字体颜色和特效

echo -e "\033[背景颜色;字体颜色;特效 \033[0m"

示例1:

echo -e "\033[32;41;5m 文本字体 \033[0m"

#注:最后的0m表示关闭属性,"\033["是固定前缀和后缀

示例2:

read -t 10 -p "`echo -e "\033[32;41;5m 请输入密码 \033[0m"`" pass

uniq & sort

cat a.txt | uniq #相邻行去重

cat a.txt | uniq -c #相邻行去重并统计次数

cat a.txt | sort | uniq -c #所有行排序,然后相邻行去重并统计次数

cat a.txt | sort -t: -k3 -r

#-t:表示以:为分隔符(默认空格),-k3表示以第3列排序(默认整行),-r表示反转

搜索

find 文件搜索

find . -name "a[0-9]*" #注:简单正则+通配符

find / -size 10c/10k/10M/10G #注:有的大写,有的小写

find . -type d/f/l #注:d表示目录,f表示文件,l表示链接

find . -mtime -3/+3 #注:-mtime表示修改时间;-3表示3天以内,+3表示3天前。

find . -user root

find . -name "[a-b]*.sh" | xargs rm -rf

#注:xargs是将管道前的搜索作为参数传给后边,此处如果不加xargs,则后边的指令是没有意义的

grep 文本·行搜索

-v invert 反向选择

-i ignore 忽略大小写

-w word 单词匹配

-n 显示行号

-m 限制行数 grep -m 100 a.txt(有时不好使) grep -10 a.txt

-e 多个OR条件 grep -e condition1 -e condition2 xxx.txt

--color=auto 过滤字段添加颜色

"^xx" 某行以xx开头(行首匹配)

grep "^user" a.txt 或:grep -E "^user" a.txt

"xx$" 某行以xx结尾

grep "user$" a.txt

-E regex 正则 grep -E "sbi*" /etc/passwd

grep -Ein "(linux){2}" a.txt #注:()表示单元

grep -Ein "(linux)+" a.txt

grep -Ein "[0-9]+" a.txt

grep -E "\*" a.txt #注:\转义等价于:grep "*" a.txt (默认不支持正则)

grep -E "[0-9]+\.+[0-9]+\.[0-9]+\.[0-9]+" a.txt #注:搜索ip

grep -E "^$" a.txt #注:找空行

grep -E "^[^d]" a.txt

#注:找不是d开头的行。^放在[]外边表示"以xx开头",放在[]中表示"除了"

cut 文本·列操作

-d 指定分隔符,delimiter

-f 指定第几列

-c 按字符截取

示例1:以冒号分割后,取第1列和第3列

cut -d ':' -f 1,3 /etc/passwd

#注:1,3表示第1列和第3列;1-3表示第1列到第3列;3-表示第3列以后。

示例2:

cut -c 1-4 /etc/passwd #截取第1列到第4列字符,以字符为单位

示例3:查找linux系统中所有不能登录的用户名

cat /etc/passwd | grep /sbin/nologin | cut -d ':' -f 1

#注1: cat /etc/passwd | cut -d ':' -f 1 等价于cut -d ':' -f 1 /etc/passwd

#注2:/bin/bash结尾的用户是可以登录的;/sbin/nologin结尾的是系统默认用户,不可以登录

#注3:cut用空格分割的话,每一个空格都会计数1次。

Mem: 1837 107 298 0 1431 1532

free -m | grep -i mem | cut -d " " -f 12 -> 1837

free -m | grep -i mem | cut -d " " -f 2 -> 空格

awk 文本操作

awk是一门语言,是3个创始人的姓名首字母缩写而成

printf不换行打印;print 换行打印

printf '%3s %3s\n' 11 12 -> %ns是字符串,n默认是1可省略

printf '%2i %2i\n' 11 12 -> %ni是数字

printf '%.2f\n' 0.1234 -> 0.12 "%.nf"是格式化浮点数

3.1 awk (默认分隔符是空格)

3.2 awk '条件1 {动作1} 条件2 {动作2}' 文件名

echo "0.123+0.123" | bc | awk '{printf "%.2f\n", $0}'

#注:$0表示整行,$1表示第一列...

df -h | grep /dev/sda2 | awk '{print "sda2的磁盘使用率:" $3}'

free -m | sed -n '2p' | awk '{print "total:"$2"\n" "userd:"$3"\n"}'

3.3 awk 选项 '条件1 {动作1} 条件2 {动作2}' 文件名

cat /etc/passwd | awk -F ":" '{printf $1}'

#注:-F指定分隔符,field-separator

cat /etc/passwd | awk 'BEGIN {FS=":"}{print $1} END {print "结束了"}'

#注1:FS是field separator

#注2:BEGIN是在awk之前执行,一般用于修改内置变量;END是awk执行完之后执行

3.4 NR 行号,是awk中的一个常量(num row);NF列号(num field)

df -h | awk 'NR==2 {print $1}'

df -h | awk '(NR>=2 && NR <=4) {printf $1"\n"}'

cat a.txt | awk 'END{print NR}' #统计有多少行

cat a.txt | awk '{if(NR==1){print $0}}' #打印第一行

cat a.txt | awk '$0~/java/' #$0表示整行,~表示匹配,/被匹配文本/

cat a.txt | awk '$0!~/java/' # !~表示不匹配

sed 文本·行操作

-n和p一块使用: df -h | sed -n '2'p #查询第2行,p表示print,也可以写成sed -n '2p'

d:删除 df -f | sed '2'd #删除第2行

eg:

cat a.txt | sed -n '1,/java/'p #搜索第1行到包含java的那一行。

cat a.txt | sed -n '10,$'p #搜索第10行到最后一行。等价于:sed -n '10,$'p a.txt

cat a.txt | sed '2,3'd #搜索除了第2行到第3行的数据

a:在下边插入

df -h | sed '2a xuan'

i:在上边插入

df -h | sed '2i xuan'

c:替换

df -h | sed '2c xuan' #把第2行替换成xuan

s/旧串/新串/g

df -h | sed 's/oldStr/newStr/g'

-i:对源文件进行修改(危险)

sed -i 's/oldStr/newStr/g' a.txt

sed -i '2i 玄' 5.txt

-e:指定多个条件

案例

巡检内存

total=`free -m | sed -n '2p' | awk '{printf $2}'`

#注:awk '{}'别漏了单引号;printf别漏了f

used=`free -m | grep -i mem | awk '{printf $3}'`

percent_used=`echo "scale=2;$used/$total" | bc | awk '{printf "%.2f",$1}'`

echo -e "总共:${total}m"

echo "已用:${used}m"

echo "内存使用率:$percent_used"

threshold=0.04

flag=`echo "$percent_used > $threshold" | bc`

if [ $flag -eq 1 ];then

echo -e "\033[31m内存使用率超过$threshold \033[0m"

#注:31m后边如果有空格,则打印出来也有

fi

批量创建用户

read -p '请输入用户名前缀:' user

read -p '请输入创建用户个数:' num

echo "$user $num"

for i in `seq 1 $num` #注:seq默认从1开始,所以1可以省略

do

#创建用户:先判断用户是否存在

newUser=$user$i

cat /etc/passwd | awk -F":" '{printf $1"\n"}' | grep $newUser

if [ $? -eq 1 ];then #注:上边搜不到则$?=1

useradd $newUser

echo "创建用户$user$i"

#设置8位随机密码. /dev/urandom文件中会随机产生一些乱码数据,使用md5sum可以得到随机字符串

password=`head -1 /dev/urandom | md5sum | cut -c 1-8`

echo "用户名:$newUser\t密码:$password" >> user_passwd.txt

fi

done

从mysql查询数据

read -p '请输入你要查询的商品名称:' name

read -p '请输入数据库用户名:' username

/usr/bin/mysql -u${username} -p -e "use test;select * from item where name = '$name';"

#注:-e表示excute,不进入mysql命令窗口,直接执行语句

高效登录远程服务器

ip=`cat ip.txt | grep $1 | awk '{printf $2}'`

ssh $ip

执行:

sh aaa.sh beijing #注:beijing赋值给$1,ip.txt文件中地址和ip使用空格隔开

shell远程执行

#!/bin/bash

#基于某台机器,要挨个ssh到其他机器执行shell指令,需要借助EOF,否则会直接调到远程机器并终止当前shell

for (( i = 3; i < 100; i++ )); do

dssh api-mms-sf-69beb-${i}.docker.py > /dev/null 2>&1 << EOF

echo "api-mms-sf-69beb-${i}.docker.py"

sudo -iu xiaoju

rm -rf /home/xiaoju/data1/mms-logs/mms-context.log*

exit

exit

EOF

done

控制台操作函数

root@sim-mms01-v-sf-2d692-0.docker.py:~$ test() {

> echo "abc"

> echo "123"

> }

shell函数只能return数字,返回String会报错

可以通过"$(函数名)"获取函数中所有的打印值

function get_pid() {

if [ -f $pidfile ];then

pid=$(cat $pidfile | sed 's/ //g')

(ps -fp $pid | grep "${module}" &>/dev/null) && echo $pid

fi

}

function check_pid() {

pid=$(get_pid)

.....

return 0

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值