shell
一、shell概述
shell是操作系统的最外层,可以合并编程语言一控制进程和文件,以及启动和控制其他程序。shell通过提示输入,向操作系统解释该输入。shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。


Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。
Linux提供的shell解析器
root@zhangkun:~# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/dash
/usr/bin/dash
root@zhangkun:~# echo $SHELL
/bin/bash
二、第一个shell脚本
先新建一个sh脚本文件
root@zhangkun:~# mkdir study
root@zhangkun:~/study# touch hello.sh
root@zhangkun:~/study# vi hello.sh
在helloworld.sh中输入如下内容
#!/bin/bash
echo "Hello,world"
脚本常用的执行方式
Linux shell种类非常多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K shell(/usr/bin/ksh)、Shell for Root(/sbin/sh)等。不同的Shell语言的语法有所不同,所以不能交换使用。
最常用的shell是Bash,也就是Bourne Again Shell,是大多是Linux系统默认的Shell。
1、第一种采用bash或sh+脚本的相对路径或者绝对路径(不用赋予脚本+x权限)
sh+脚本的相对路径
root@zhangkun:~/study# sh hello.sh
Hello,world
sh+脚本的绝对路径
root@zhangkun:~/study# sh /root/study/hello.sh
Hello,world
bash+脚本的相对路径
root@ zhangkun:~/study# bash hello.sh
Hello,world
bash+脚本的绝对路径
root@ zhangkun:~/study# bash /root/study/hello.sh
Hello,world
2、第二种:采用输入脚本的绝对路径和相对路径执行脚本(必须具有可执行权限+x)
1、首先赋予helloworld.sh脚本+x权限
root@zhangkun:~/study# chmod +x hello.sh
2、./+脚本名
root@zhangkun:~/study# ./hello.sh
Hello,world
3、/+绝对路径
root@ zhangkun:~/study# /root/study/hello.sh
Hello,world
第三种:在脚本的路径前加上”. ”或者source命令
root@zhangkun:~/study# source hello.sh
Hello,world
root@zhangkun:~/study# source /root/study/hello.sh
Hello,world
root@zhangkun:~/study# . hello.sh
Hello,world
source是shell的内嵌
root@zhangkun:~/study# type source
source is a shell builtin
前两种都是在当前shell中打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关闭,回到父shell中。
第三种,也就是使用在脚本路径前加”.”或者source的方式,可以使脚本内容在当前shell里执行,而无需打开子shell,也就是为什么我们每次修改完/etc/profile文件以后,需要source一下的原因。
三、父子shell
查看bash进程
root@zhangkun:~/study# ps -f
UID PID PPID C STIME TTY TIME CMD
root 1623611 1623417 0 Jul16 pts/4 00:00:00 -bash
root 2973460 1623611 0 16:18 pts/4 00:00:00 ps -f
在敲一下bash,生成一个bash的子进程
root@ zhangkun:~/study# bash
root@ zhangkun:~/study# ps -f
UID PID PPID C STIME TTY TIME CMD
root 1623611 1623417 0 Jul16 pts/4 00:00:00 -bash
root 2975205 1623611 0 16:19 pts/4 00:00:00 bash
root 2975216 2975205 0 16:19 pts/4 00:00:00 ps -f
后面进行的操作是在子shell中进行。
然后执行exit退出子shell
root@zhangkun:~/study# exit
exit
root@zhangkun:~/study# ps -f
UID PID PPID C STIME TTY TIME CMD
root 1623611 1623417 0 Jul16 pts/4 00:00:00 -bash
root 2979056 1623611 0 16:21 pts/4 00:00:00 ps -f
开子shell和不开子shell的区别在于,环境变量的继承关系,如在子shell中设置的当前变量,父shell中是不可见的。
四、变量
shell编程语言是非典型的解释型语言,不像C++/Java语言编程时需要事先声明变量,SHELL给一个变量赋值,实际上就是定义了变量,在Linux支持的所有shell中,都可以使用赋值符号(=)为变量赋值。
SHELL变量可分为两类:局部变量和环境变量,局部变量只在创建它们的shell脚本中使用,而环境变量则可以再创建它们的shell以及其派生出来的任意子进程中使用,有些变量使用户创建的,其他的则是专用shell变量。
4.1 系统预定义变量
(1)常用系统变量
$HOME、$PWD、$SHELL、$USER等。
$0 当前程序的名称
$n 当前程序的第n个参数,n=1,2,....9
$* 当前程序的所有参数(不包括程序本身)
$? 命令或程序执行完后的状态,一般返回0表示执行成功。
$UID 当前用户的ID
$PWD 当前所在的目录
$#:表示执行脚本传入参数的个数
(2) 案例实操
查看系统变量的值
root@zhangkun:~/study# env
root@zhangkun:~/study# echo $HOME
/root
root@zhangkun:~/study# echo $PWD
/root/study
root@zhangkun:~/study# printenv
root@zhangkun:~/study# echo $USER
root
root@zhangkun:~/study# printenv | less

![]()
![]()

![]()
查看所有的变量
root@zhangkun:~/study# set
输出所有参数、执行结果和参数个数

#!/bin/bash
# author print variables
echo -e '\033[32m----------------------\033[0m'
echo "This is $0 param !"
echo "This is \$1 is $1 param !"
echo "This is \$2 is $2 param !"
echo -e '\033[32m----------------------\033[0m'
echo "This is \$# is $# param !"
echo "This is \$* is $* param !"
echo "This is \$? is $? param !"
运行结果如下:

(3)LAMP导航菜单编写
#!/bin/bash
#by authors zk
echo -e "\033[32mPlease select Menu follow:\033[1m"
echo "1)install apache server"
echo "2)install Mysql server"
echo "3)install PHP server"
echo "4)install LAMP WEB "
echo "--------------------------------------------"
输出结果如下:

4.2 用户自定义变量
(1)基本语法
1、定义变量:变量名=变量值,注意,=号前后不能有空格
root@zhangkun:/# a=2
root@ zhangkun:/# echo $a
2
root@ zhangkun:/# echo $my_var
root@ zhangkun:/# my_var=hello
root@ zhangkun:/# echo $my_var
hello
root@ zhangkun:/# my_var='Hello,world'
root@ zhangkun:/# echo $my_var
Hello,world
root@ zhangkun:/# my_var="Hello,world"
root@ zhangkun:/# echo $my_var
Hello,world
#自定义变量是一个局部变量
root@ zhangkun:/# env | grep $my_var
root@ zhangkun:/# set | grep $my_var
_=Hello,world
my_var=Hello,world
#定义一个全局变量,变量升级
root@ zhangkun:/# export my_var
root@ zhangkun:/# echo $my_var
Hello,world
#切换进入子shell
root@ zhangkun:/# bash
root@ zhangkun:/# echo $my_var
Hello,world
#如果在子shell中更改变量的值只会在子shell中有效
root@ zhangkun:/# echo $my_var
Hello,world
root@ zhangkun:/# bash
root@ zhangkun:/# my_var='Hello'
root@ zhangkun:/# echo $my_var
Hello
root@ zhangkun:/# exit
exit
root@ zhangkun:/# echo $my_var
Hello,world
用户自定义变量

五、IF条件控制语句
在Linux Shell编程中,if、for、while、case等条件流程控制语句用的非常多。
IF (表达式) #if(Variable in Array)
语句1
else
语句2
fi
例一:判断数字大小
#!/bin/bash
NUM1=100
NUM2=200
if (($NUM2 > $NUM1));then
echo "$NUM2 greater $NUM1!"
fi
运行结果如下:

逻辑运算符解析:
-f 判断文件是否存在 eg: if [ -f file name ]
-d 判断目录是否存在 eg: if [ -d dir ]
-eq 等于 应用于:整型比较
-ne 不等于 应用于:整型比较
-lt 小于 应用于:整型比较
-gt 大于 应用于:整型比较
-le 小于或等于 应用于:整型比较
-ge 大于或等于 应用于:整型比较
-a 双方都成立(and)逻辑表达式 -a 逻辑表达式
-o 单方成立(or)逻辑表达式 -o 逻辑表达式
-z 空字符串
例二:判断目录是否存在,如果目录不存在则创建
#!/bin/bash
# judge dir exists
dir=~/Desktop/test
if [ -d $dir ];then
echo "test exist"
else
mkdir -p $dir
echo "$dir mkdir success"
fi
运行结果如下:

![]()
例三:判断文件是否存在,如果存在,打印输出,如果不存在创建文件
#!/bin/bash
filename="file.txt"
if [ ! -f $filename ];then
echo "OK">> $filename
else
echo "file is exists"
cat $filename
fi
运行结果如下:


例四:根据分数判断成绩等级
#!/bin/bash
score=$1
if [ -z $score ];then
echo "Usage:{60|80}"
exit
fi
if [[ $score -gt 85 ]];then
echo "very good"
elif [[ $score -gt 75 ]];then
echo "good"
elif [[ $score -gt 60 ]];then
echo "pass"
else
echo "no pass"
fi
运行结果如下:

例五:使用if条件语句编写Mysql备份脚本
#!/bin/bash
# auto backup mysql db
# by author zk
DATE=$(date +%F-%H-%M-%S)
echo $DATE
MYSQLDB=school
BAK_DIR=/root/data/backup/${MYSQLDB}_${DATE}
echo $BAK_DIR
MYSQLUSR=root
MYSQLPW=123456
MYSQLCMD=/usr/bin/mysqldump
if [ $UID -ne 0 ];then
echo "Must to be use root for exec shell."
fi
if [ ! -d $BAK_DIR ];then
mkdir -p $BAK_DIR
echo -e "\033[32mThe $BAK_DIR Create Successfully!"
else
echo "This $BAK_DIR is exists..."
fi
$MYSQLCMD -u$MYSQLUSR -p$MYSQLPW -d $MYSQLDB >$BAK_DIR/$MYSQLDB.sql
if [ $? -eq 0 ];then
echo -e "\033[32mThe Mysql Backup $MYSQLDB Successfully!"
else
echo -e "\033[32mThe Mysql Backup $MYSQLDB Failed,Please check!"
fi
先使用sh -n检查脚本是否存在问题
![]()
然后执行脚本

执行成功
可以看到备份sql

看一下备份sql的内容

指定每日备份计划
![]()
输入如下代码
0 0 * * * /bin/bash /home/zk/Desktop/shelltext/mysql_bak.sh >> /tmp/mysql_bak.log 2>&1
指定每日0点0分执行mysql_bak.sh备份数据库
例六:if条件综合LAMP一键安装脚本
一键源码安装LAMP脚本,先分解任务:
打印菜单
(1)安装apache WEB服务器
(2)安装Mysql DB服务器
(3)安装PHP服务器
(4)整合LAMP架构并启动服务
(1)安装apache WEB服务器
下载httpd-2.4.62.tar.bz2版本,下载URL,解压,进入安装目录,configure;make ; make install
遇到过如下错误
错误一:
checking for APR... no configure: error: APR not found. Please read the documentation.
这个错误需要先安装APR,在脚本里实现
错误二:
error: no acceptable C compiler found in $PATH
这个错误需要安装GCC
zk@zk-None:~/Desktop/shelltext$ sudo apt install gcc
错误三:
LAMP.sh: line 37: make: command not found
一般出现这个-bash: make: command not found提示,系统没有安装make等常用命令,直接sudo apt-get install安装下即可。
解决方法:
sudo apt-get update
sudo apt-get install gcc automake autoconf libtool make
错误四:
xml/apr_xml.c:35:10: fatal error: expat.h: No such file or directory
解决方法:
sudo apt-get update
sudo apt-get install libexpat1-dev
错误五:安装pcre时
configure: error: Invalid C++ compiler or C++ compiler flags
解决方法:
sudo apt-update
sudo apt-get install g++
安装apache web服务器LAMP.sh
错误六:启动apache报错
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
到httpd目录下配置httpd.conf中Servername

ServerName localhost:80
设置代理服务器
echo 'Acquire::http::Proxy "http://your-proxy-address:port/";' | sudo tee
(1)安装apache服务器的脚本LAMP.sh
#!/bin/bash
# auto make install LAMP
# by authors zk
# HTTP define path variable
H_PREFIX_APACHE=/usr/local/apache
H_FILES_HTTPD=httpd-2.4.62.tar.bz2
H_FILES_HTTPD_DIR=httpd-2.4.62
H_HTTPD_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/httpd/
H_PREFIX_HTTPD=/usr/local/apache/httpd/
H_FILES_APR=apr-1.6.5.tar.bz2
H_FILES_APR_DIR=apr-1.6.5
H_APR_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR=/usr/local/apache/apr/
H_FILES_APR_UTIL=apr-util-1.6.3.tar.bz2
H_FILES_APR_UTIL_DIR=apr-util-1.6.3
H_APR_UTIL_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR_UTIL=/usr/local/apache/apr-util/
H_FILES_PCRE=pcre-8.45.tar.gz
H_FILES_PCRE_DIR=pcre-8.45
H_PCRE_URL=https://sourceforge.net/projects/pcre/files/pcre/8.45/
H_PREFIX_PCRE=/usr/local/apache/pcre/
H_FILES_PCRE2=pcre2-10.37.tar.gz
H_FILES_PCRE2_DIR=pcre2-10.37
H_PCRE2_URL=https://sourceforge.net/projects/pcre/files/pcre2/10.37/
H_PREFIX_PCRE2=/usr/local/apache/pcre2/
if [ -z "$1" ];then
echo -e "\033[36mPlease Select Install Menu follow:\033[0m"
echo -e "\033[32m1)install apache server\033[1m"
echo -e "\033[32m2)install Mysql server\033[1m"
echo -e "\033[32m3)install PHP server\033[1m"
echo -e "\033[31mUsage:{ /bin/sh $0 1|2|3|help}\033[0m"
exit
fi
if [[ "$1" -eq "help" ]];then
echo -e "\033[36mPlease Select Install Menu follow:\033[0m"
echo -e "\033[32m1)install apache server\033[1m"
echo -e "\033[32m2)install Mysql server\033[1m"
echo -e "\033[32m3)install PHP server\033[1m"
echo -e "\033[31mUsage:{ /bin/sh $0 1|2|3|help}\033[0m"
exit
fi
if [[ "$1" -eq "1" ]];then
wget -c $H_APR_URL/$H_FILES_APR &&tar -jxvf $H_FILES_APR &&cd $H_FILES_APR_DIR ;./configure --prefix=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_APR_UTIL_URL/$H_FILES_APR_UTIL &&tar -jxvf $H_FILES_APR_UTIL &&cd $H_FILES_APR_UTIL_DIR ;./configure --prefix=$H_PREFIX_APR_UTIL --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE_URL/$H_FILES_PCRE &&tar -zxvf $H_FILES_PCRE &&cd $H_FILES_PCRE_DIR ;./configure --prefix=$H_PREFIX_PCRE --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE2_URL/$H_FILES_PCRE2 &&tar -zxvf $H_FILES_PCRE2 &&cd $H_FILES_PCRE2_DIR ;./configure --prefix=$H_PREFIX_PCRE2 --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
export PATH=$PATH:$H_PREFIX_PCRE
echo $PATH
wget -c $H_HTTPD_URL/$H_FILES_HTTPD &&tar -jxvf $H_FILES_HTTPD &&cd $H_FILES_HTTPD_DIR ;./configure --prefix=$H_PREFIX_HTTPD --with-apr=$H_PREFIX_APR --with-apr-util=$H_PREFIX_APR_UTIL --enable-so --enable-mods-shared=most --with-pcre=$H_PREFIX_PCRE --with-pcre2=$H_PREFIX_PCRE2
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
fi
执行完以上脚本后,启动apache服务器
root@zk-None:/usr/local/apache/httpd/bin# /usr/local/apache/httpd/bin/apachectl -k start
httpd (pid 351155) already running
root@zk-None:/usr/local/apache/httpd/bin# /usr/local/apache/httpd/bin/apachectl -k stop
root@zk-None:/usr/local/apache/httpd/bin# /usr/local/apache/httpd/bin/apachectl -k start
查看到80端口正在监听
root@zk-None:/usr/local/apache/httpd/bin# netstat -lnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.54:53 0.0.0.0:* LISTEN
tcp6 0 0 ::1:631 :::* LISTEN
tcp6 0 0 :::80 :::* LISTEN
访问localhost:80

apache服务器安装成功。
(2)安装Mysql DB服务器
安装mysql服务器脚本LAMP.sh
#!/bin/bash
# auto make install LAMP
# by authors zk
# HTTP define path variable
H_PREFIX_APACHE=/usr/local/apache
H_FILES_HTTPD=httpd-2.4.62.tar.bz2
H_FILES_HTTPD_DIR=httpd-2.4.62
H_HTTPD_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/httpd/
H_PREFIX_HTTPD=/usr/local/apache/httpd/
H_FILES_APR=apr-1.6.5.tar.bz2
H_FILES_APR_DIR=apr-1.6.5
H_APR_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR=/usr/local/apache/apr/
H_FILES_APR_UTIL=apr-util-1.6.3.tar.bz2
H_FILES_APR_UTIL_DIR=apr-util-1.6.3
H_APR_UTIL_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR_UTIL=/usr/local/apache/apr-util/
H_FILES_PCRE=pcre-8.45.tar.gz
H_FILES_PCRE_DIR=pcre-8.45
H_PCRE_URL=https://sourceforge.net/projects/pcre/files/pcre/8.45/
H_PREFIX_PCRE=/usr/local/apache/pcre/
H_FILES_PCRE2=pcre2-10.37.tar.gz
H_FILES_PCRE2_DIR=pcre2-10.37
H_PCRE2_URL=https://sourceforge.net/projects/pcre/files/pcre2/10.37/
H_PREFIX_PCRE2=/usr/local/apache/pcre2/
if [ -z "$1" ];then
echo -e "\033[36mPlease Select Install Menu follow:\033[0m"
echo -e "\033[32m1)install apache server\033[1m"
echo -e "\033[32m2)install Mysql server\033[1m"
echo -e "\033[32m3)install PHP server\033[1m"
echo -e "\033[31mUsage:{ /bin/sh $0 1|2|3|help}\033[0m"
exit
fi
if [[ "$1" -eq "help" ]];then
echo -e "\033[36mPlease Select Install Menu follow:\033[0m"
echo -e "\033[32m1)install apache server\033[1m"
echo -e "\033[32m2)install Mysql server\033[1m"
echo -e "\033[32m3)install PHP server\033[1m"
echo -e "\033[31mUsage:{ /bin/sh $0 1|2|3|help}\033[0m"
exit
fi
if [[ "$1" -eq "1" ]];then
wget -c $H_APR_URL/$H_FILES_APR &&tar -jxvf $H_FILES_APR &&cd $H_FILES_APR_DIR ;./configure --prefix=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_APR_UTIL_URL/$H_FILES_APR_UTIL &&tar -jxvf $H_FILES_APR_UTIL &&cd $H_FILES_APR_UTIL_DIR ;./configure --prefix=$H_PREFIX_APR_UTIL --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE_URL/$H_FILES_PCRE &&tar -zxvf $H_FILES_PCRE &&cd $H_FILES_PCRE_DIR ;./configure --prefix=$H_PREFIX_PCRE --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE2_URL/$H_FILES_PCRE2 &&tar -zxvf $H_FILES_PCRE2 &&cd $H_FILES_PCRE2_DIR ;./configure --prefix=$H_PREFIX_PCRE2 --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
export PATH=$PATH:$H_PREFIX_PCRE
echo $PATH
wget -c $H_HTTPD_URL/$H_FILES_HTTPD &&tar -jxvf $H_FILES_HTTPD &&cd $H_FILES_HTTPD_DIR ;./configure --prefix=$H_PREFIX_HTTPD --with-apr=$H_PREFIX_APR --with-apr-util=$H_PREFIX_APR_UTIL --enable-so --enable-mods-shared=most --with-pcre=$H_PREFIX_PCRE --with-pcre2=$H_PREFIX_PCRE2
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
fi
if [[ "$1" -eq "2" ]];then
sudo systemctl stop mysql
sudo apt-get remove --purge mysql-server mysql-client mysql-common
sudo rm -rf /etc/mysql /var/lib/mysql
sudo apt-get autoremove
sudo apt-get autoclean
sudo apt-get remove --purge mysql-*
sudo apt update
sudo apt install mysql-server mysql-client
if [ $? -eq 0 ];then
echo -e "\033[32mThe $H_FILES_MYSQL_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_MYSQL_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
fi
运行脚本LAMP.sh后,输入mysql登录数据库
root@zk-None:~# mysql -uroot -p123456
mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.33-0ubuntu0.16.04.1 (Ubuntu) Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
(3)安装PHP服务器
在LAMP.sh中配置安装PHP服务器功能
六、for循环语句
For 变量 in 字符串
do
语句1
done
例一:打印seq数字循环
#!/bin/bash
for i in $(seq 1 15);
do
echo -e "\033[32mThe Num is $i\033[32m"
done
运行结果如下:

例二:求和1-100的值
#!/bin/bash
# auto sum 1 100
j=0
for ((i=1;i<=100;i++));
do
j=$(($i+$j))
done
echo $j
#!/bin/bash
# auto sum 1 100
j=0
for ((i=1;i<=100;i++));
do
#j=$(($i+$j))
j=$(expr $j + $i)
done
echo $j
运行结果如下:

例三:批量打包sh文件
#!/bin/bash
for i in `find * . -maxdepth 1 -name "*.sh"`
do
tar -czvf $i.tgz $i
done
运行结果如下:

例四:批量解压文件
#!/bin/bash
for i in `find * . -maxdepth 1 -name "*.tgz"`
do
tar -xzvf $i -C /home/zk/Desktop/shelltext
done
执行前

执行后

例五:服务器远程批量传输文件
首先需要开放虚拟机中的22端口号
Linux 中 22 端口是 ssh 应用端口用以进行远程访问,正常情况下 Linux 服务器要打开 22 端口。
如下命令检查服务器是否启用 22 端口:
netstat -tln | grep 22
如果结果出现 xxx:22 等结果则说明,22 端口已开启,否则需要手动开启。
开启 22 端口
首先,检查是否安装 SSH 服务器,执行如下命令
sudo apt-get update
sudo apt-get install openssh-server
然后,开启服务器上的 22 端口。需要修改 SSH 服务器配置文件/etc/ssh/sshd_config。执行如下命令:
sudo vi /etc/ssh/sshd_config
找到“#Port 22”一行,然后将其改为“Port 22”。
最后,需要重启SSH服务以使配置更改生效,执行如下命令:
sudo service ssh restart
再次执行
netstat -tln | grep 22
检查 22 端口状态。如果开启,则可以通过 ssh 链接该服务器。
![]()
开启ssh服务
systemctl enable ssh.service
service sshd start
查看ssh服务状态
service ssh status
Linux的ip地址是192.168.67.128

#!/bin/bash
#auto ssh ls /tmp
#by authors zk 2024
for i in `echo 192.168.67.128 127.0.0.1`
do
scp /tmp/test.txt root@$i:/root/
done
在执行脚本的时候我遇到如下问题:

更改了/etc/ssh/sshd_config文件下的配置不好用
root@zk-None:/home/zk/Desktop/shelltext# cat /etc/ssh/sshd_config | grep 'PermitRootLogin yes\|PasswordAuthentication yes'
PermitRootLogin yes
PasswordAuthentication yes
最后更改了/etc/ssh/sshd_config下UsePAM解决问题
root@zk-None:/var/log# cat /etc/ssh/sshd_config | grep 'UsePAM'
UsePAM no

可以看到文件已经从/tmp目录传输到/root目录下了


生成免密钥登陆
root@zk-None:/home/zk/Desktop/shelltext# ssh-keygen
先生成一个公钥,然后将生成的公钥拷贝过去

后续copy就不需要密码了
例六:远程主机批量执行命令
#!/bin/bash
#auto ssh ls /tmp
#by authors zk 2024
for i in `seq 100 200`
do
ssh -l root 192.168.1.$i 'ls /tmp'
done
七、While循环语句
打印0-9
#!/bin/bash
i=0
while [[ $i -lt 10 ]]
do
echo "The number is $i"
((i++))
done
j=0
while (( $j < 10 ))
do
echo "The number is $j"
((j++))
done
打印结果如下:

八、提示输入read功能
read -p "please input number:" input

循环读出文件中的值
#!/bin/bash
while read line
do
echo $line
done </etc/hosts
输出结果为

新建一个带有ip list的文件list.txt
192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10

向列表中的ip去同步内容
#!/bin/bash
while read line
do
echo -e "\033[32mscp -r /home/zk/Desktop/shelltext/ root$line:tmp/ \033[0m"
done < list.txt

类似for循环的实现
#!/bin/bash
for line in `cat list.txt`
do
echo -e "\033[32mscp -r /home/zk/Desktop/shelltext/ root$line:tmp/ \033[0m"
done

更改list.txt文件如下
1 192.168.1.1 /src1 /des1
2 192.168.1.2 /src2 /des2
3 192.168.1.3 /src3 /des3
4 192.168.1.4 /src4 /des4
5 192.168.1.5 /src5 /des5
6 192.168.1.6 /src6 /des6
7 192.168.1.7 /src7 /des7
8 192.168.1.8 /src8 /des8
9 192.168.1.9 /src9 /des19
10 192.168.1.10 /src10 /des10
使用awk命令循环取出第二列
#!/bin/bash
while read line
do
IP=`echo $line |awk '{print $2}'`
echo -e "\033[32mscp -r /home/zk/Desktop/shelltext/ root@$IP:tmp/ \033[0m"
done < list.txt
执行结果如下:

九、Until循环语句
until 提交
do
action
done
直到满足条件,才退出,否则执行action
条件判断数字
#!/bin/bash
a=10;
until [[ $a -lt 0 ]];do
echo $a;
((a--));
done;
执行结果

十、Case选择语句
case $arg in
pattern1)
语句1
;;
pattern2)
语句2
;;
*)
语句3
;;
easc
case.sh
#!/bin/bash
#auto install LAMP
#by authors zk 2025
case $1 in
apache )
echo "wait install apache server......"
;;
mysql )
echo "wait install mysql server......"
;;
PHP )
echo "wait install PHP server......"
;;
* )
echo "Usage: {$0 Apache|MYsql|PHP|help}"
;;
esac
执行脚本

十一、选择select语句
#!/bin/bash
#auto install LAMP
#by authors zk 2025
PS3="select you will exec Menu:"
select i in "apache" "mysql" "PHP"
do
case $i in
apache )
echo "wait install apache server......"
;;
mysql )
echo "wait install mysql server......"
;;
PHP )
echo "wait install PHP server......"
;;
* )
echo "Usage: {$0 Apache|MYsql|PHP|help}"
;;
esac
done
执行结果如下:

#!/bin/bash
select system in "centos" "Rehat" "ubuntu";
do
echo "select your system:$system"
done
执行结果如下:

十二、Shell数组
数组,就是相同数据类型的元素按照一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号成为下标
定义一个一维数组,定义数组一般以括号的方式来定义,数组的值可以随机定义
A=(test1 test2 test3)
输出数组中的值
#!/bin/bash
array1=( test1 test2 test3)
echo ${array1[0]}
{$A[0]}代表第一个数组变量,结果显示test1,数组引用从0开始,代表第一个数组,以此类推。

显示数组中所有的参数,echo ${A[@]}将显示所有参数test1 test2 test3
#!/bin/bash
array1=( test1 test2 test3)
echo ${array1[@]}

显示数组中的参数个数
打印Linux网络接口的硬件地址、ip、掩码、网关地址
#!/bin/bash
#Auto Make KVM Virtualization
#Auto config bond scripts
NETWORK=(
HWADDR=`ifconfig ens33 |egrep "ether" |tr "\n" " "|awk '{print $2}'`
IPADDR=`ifconfig ens33 |egrep "inet" |tr "\n" " "|awk '{print $2}'`
NETMASK=`ifconfig ens33 |egrep "netmask" |tr "\n" " "|awk '{print $4}'`
GATEWAY=`route -n|grep "UG"|awk '{print $2}'`
)
echo ${NETWORK[0]}
echo ${NETWORK[1]}
echo ${NETWORK[2]}
echo ${NETWORK[3]}
执行结果如下:
十三、Linux函数详解
Linux函数,什么是函数呢,其实函数就相当于一个简单的命令所包括的很多命令的集合,基本的格式:
function command()
{
Xxx.xx
xxxx.xx
}
command
函数安装apache服务器
#!/bin/bash
# auto make install LAMP
# by authors zk
# HTTP define path variable
function install_apache()
{
H_PREFIX_APACHE=/usr/local/apache
H_FILES_HTTPD=httpd-2.4.62.tar.bz2
H_FILES_HTTPD_DIR=httpd-2.4.62
H_HTTPD_URL=https://mirrors.tuna.tsinghua.edu.cn/apache/httpd/
H_PREFIX_HTTPD=/usr/local/apache/httpd/
H_FILES_APR=apr-1.6.5.tar.bz2
H_FILES_APR_DIR=apr-1.6.5
H_APR_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR=/usr/local/apache/apr/
H_FILES_APR_UTIL=apr-util-1.6.3.tar.bz2
H_FILES_APR_UTIL_DIR=apr-util-1.6.3
H_APR_UTIL_URL=http://mirrors.tuna.tsinghua.edu.cn/apache/apr/
H_PREFIX_APR_UTIL=/usr/local/apache/apr-util/
H_FILES_PCRE=pcre-8.45.tar.gz
H_FILES_PCRE_DIR=pcre-8.45
H_PCRE_URL=https://sourceforge.net/projects/pcre/files/pcre/8.45/
H_PREFIX_PCRE=/usr/local/apache/pcre/
H_FILES_PCRE2=pcre2-10.37.tar.gz
H_FILES_PCRE2_DIR=pcre2-10.37
H_PCRE2_URL=https://sourceforge.net/projects/pcre/files/pcre2/10.37/
H_PREFIX_PCRE2=/usr/local/apache/pcre2/
wget -c $H_APR_URL/$H_FILES_APR &&tar -jxvf $H_FILES_APR &&cd $H_FILES_APR_DIR ;./configure --prefix=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_APR_UTIL_URL/$H_FILES_APR_UTIL &&tar -jxvf $H_FILES_APR_UTIL &&cd $H_FILES_APR_UTIL_DIR ;./configure --prefix=$H_PREFIX_APR_UTIL --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_APR_UTIL_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE_URL/$H_FILES_PCRE &&tar -zxvf $H_FILES_PCRE &&cd $H_FILES_PCRE_DIR ;./configure --prefix=$H_PREFIX_PCRE --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
wget -c $H_PCRE2_URL/$H_FILES_PCRE2 &&tar -zxvf $H_FILES_PCRE2 &&cd $H_FILES_PCRE2_DIR ;./configure --prefix=$H_PREFIX_PCRE2 --with-apr=$H_PREFIX_APR
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_PCRE2_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
export PATH=$PATH:$H_PREFIX_PCRE
echo $PATH
wget -c $H_HTTPD_URL/$H_FILES_HTTPD &&tar -jxvf $H_FILES_HTTPD &&cd $H_FILES_HTTPD_DIR ;./configure --prefix=$H_PREFIX_HTTPD --with-apr=$H_PREFIX_APR --with-apr-util=$H_PREFIX_APR_UTIL --enable-so --enable-mods-shared=most --with-pcre=$H_PREFIX_PCRE --with-pcre2=$H_PREFIX_PCRE2
if [ $? -eq 0 ];then
make && make install
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Successfully!\033[0m"
else
echo -e "\033[32mThe $H_FILES_HTTPD_DIR Server Install Failed,Please check...!\033[0m"
exit
fi
}
install_apache
十四、awk、sed、grep、find命令
sed
当sed不加参数的时候,原文件不会更改
sed 's/[源文件内容]/[替换内容]/g' sed_test.txt

当加入参数-i时,会更改原始文件

在文件中内容的每行前增加一个空格
sed -i 's/^/& /g' sed_test.txt

在文件中内容的每行前增加一个id
sed -i 's/^/&id /g' sed_test.txt

在文件中内容的每行最后增加一个id
sed -i 's/$/&id /g' sed_test.txt

在某字符串行后加入另一字符串
sed '/[字符串1]/a [字符串2]' sed_test.txt

在某字符串行前加入另一字符串
sed '/zhangkun/i wuguangke' sed_test.txt

打印包含某字符串的行
sed -n '/zhangkun/p' sed_test.txt

打印文件中1-5行
sed -n "1,5p" sed_test.txt

在sed_number.txt中查找最大的数
sed_number.txt
232
2323 322 21 12
323
3222323
445
12308
23 212 432 5323 232321313
打印sed_number.txt中最大值和最小值
cat sed_number.txt |sed 's/ /\n/g'|grep -v "^$"|sort -nr|sed -nr '1p;$p'

grep
grep可过滤匹配字符串
过滤含有32字符串的字符行
cat sed_number.txt| grep 32

过滤不含有32字符串的字符行
cat sed_number.txt| grep -v 32

grep正则匹配
匹配19开头的行
cat list.txt| grep "^19"

匹配含有字符串a-z的行
cat list.txt| grep [a-z]

匹配含192的行
grep "\<192\>" list.txt

匹配行Ip地址
cat list.txt |grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}"

匹配按行打印出行号
grep -n "192" list.txt

awk
匹配列打印,打印第2列
cat list.txt | awk '{print $2}'

打印最后一列,最后一个域
cat list.txt | awk '{print $NF}'

cat list.txt |awk '{print "last column:" $NF}'
按列打印passwd中的用户名
cat /etc/passwd |sed 's/:/ /g'|awk '{print $1}'

按符号切割
awk -F"[符号]"
cat /etc/passwd |awk -F":" '{print $1}'

获取ip地址
ifconfig | grep "broadcast "|awk -F" " '{print $2}'

find
find的主要作用查找文件
在当前目录下查找文件
find -name "uguangke"

在一级目录下查找类型为文件文件名包含txt的文件
find . -maxdepth 1 -type f -name "*.txt"

在二级目录下查找类型为文件文件名包含txt的文件
find . -maxdepth 2 -type f -name "*.txt"

过滤修改时间在60天以前的文件
find -maxdepth 1 -name "*.sh" -mtime +60

过滤修改时间在1天以内的文件并删除文件
新建三个文件
touch a.txt b.txt c.txt
查找修改时间在1天以内的文件
find . -maxdepth 1 -type f -name "*.txt" -mtime -1
查找修改时间在1天以内的文件并删除
find . -maxdepth 1 -type f -name "*.txt" -mtime -1 -exec rm -rf {} \;

查找修改时间为5天的txt文件并copy到tmp目录下
find . -maxdepth 1 -type f -name "*.txt" -mtime -5 -exec cp {} /tmp/ \;

使用xargs删除文件,xargs只能用于删除文件,不同于exec
find . -maxdepth 1 -type f -name "*.txt" -mtime -5|xargs rm -rf {} \;

查询文件大小大于1k的文件
find . -size +1k -type f

查询文件大小大于1k的文件剪切移动到tmp目录下
find . -size +1k -type f -exec mv {} /tmp/ \;

十五、全量备份和增量备份Linux系统脚本
全量备份sh脚本
tar -g /tmp/snapshot -czvf /tmp/2025_02_08_full_systembak.tar.gz /home/zk/Desktop/shelltext/*.sh

在shelltext目录下新建一个sh文件
touch test_add_bak.sh
![]()
再次增量备份,他只会备份新增的文件
tar -g /tmp/snapshot -czvf /tmp/2025_02_08_add_systembak.tar.gz /home/zk/Desktop/shelltext/*.sh

解压增量备份压缩文件后,文件夹下只包含一个sh文件

全量以及增量备份脚本
#!/bin/sh
#Automatic Backup Linux System Files
#Author zk 2025-05-29
#Define Variable
SOURCE_DIR=/home/zk/Desktop/shelltext
TARGET_DIR=/home/zk/data/backup
YEAR=`date +%Y`
MONTH=`date +%m`
DAY=`date +%d`
WEEK=`date +%u`
A_NAME=`date +%Y-%m-%d-%H%M`
FILES=system_backup.tgz
CODE=$?
if [ ! -d $TARGET_DIR/$YEAR/$MONTH/$DAY ];then
mkdir -p $TARGET_DIR/$YEAR/$MONTH/$DAY
echo -e "\033[32mThe $TARGET_DIR Created Successfully !\033[0m"
fi
#EXEC Full_Backup Function Command
Full_Backup()
{
if [ "$WEEK" -eq "3" ];then
rm -rf $TARGET_DIR/snapshot
cd $TARGET_DIR/$YEAR/$MONTH/$DAY;tar -g $TARGET_DIR/snapshot -czvf $A_NAME$FILES ${SOURCE_DIR[@]}
[ "$CODE" == "0" ]&&echo -e "--------------------------------------------\nThese Full_Backup System Files Backup Successfully !"
fi
}
#Perform incremental BACKUP Function Command
Add_Backup()
{
if [ $WEEK -ne "3" ];then
cd $TARGET_DIR/$YEAR/$MONTH/$DAY ;tar -g $TARGET_DIR/snapshot -czvf $A_NAME$FILES ${SOURCE_DIR[@]}
[ "$CODE" == "0" ]&&echo -e "These Add_Backup System Files $TARGET_DIR/$YEAR/$MONTH/$DAY/${YEAR}_$A_NAME$FILES Backup Successfully !"
fi
}
sleep 3
Full_Backup;Add_Backup
十六、查看系统登录日志
Ubuntu / Debian:sudo cat /var/log/auth.log | grep "Failed"
CentOS / RHEL:sudo cat /var/log/secure | grep "Failed"
若需要更详细的信息,可以将上述命令与grep结合使用,并添加关键字进行过滤。比如,要查看特定IP地址的登录失败情况,可以使用类似于以下命令:
sudo cat /var/log/auth.log | grep "Failed" | grep "ip_address"
如果想要持续监控新的登录失败事件,可以使用tail命令配合-f参数,实时显示最新的日志内容。例如:
sudo tail -f /var/log/secure
tail -f /var/log/auth.log

十七、设置虚拟机共享
在虚拟机共享设置中设置虚拟机共享目录

就会实现在/mnt/hgfs下目录地挂载

十八、mobaXterm连接虚拟机Linux系统
首先服务器开放22端口号
root@zk-None:/home/zk# sudo ufw allow 22
其次获取ip地址
root@zk-None:/home/zk# ifconfig

使用22端口号登录

登录成功

需要先行安装ssh服务
sudo apt update
sudo apt install openssh-server
检查ssh服务状态
sudo systemctl status ssh
ssh服务开启
sudo systemctl start sshd
ufw allow in to any port 22 from any proto tcp
ufw allow in to any from any port 22 proto tcp
十九、Linux安装防火墙
ufw
sudo apt install ufw
启动防火墙
sudo ufw enable
查看防火墙状态
sudo ufw status
查看防火墙策略
sudo ufw status numbered

删除某条策略
sudo ufw delete 2

当192.168.67.128设置ufw阻止22端口号的tcp报文时
sudo ufw deny in to any from any port 22 proto tcp

会让另一台主机无法登录到此台设备上
设置允许22端口登录策略
sudo ufw allow in to any from any port 22 proto tcp

可以登录

iptable
使用iptable禁止icmp报文通过
iptables -A OUTPUT --proto icmp -j DROP

删除禁用
iptables -D OUTPUT --proto icmp -j DROP

防火墙过滤登录失败大于4次的IP地址
#!/bin/bash
#auto drop ssh failed IP address
#zhangk 2025-05-31
#define variables
SEC_FILE=/var/log/
IP_ADDR=`tail -n 1000 /var/log/auth.log | grep "Failed password"| egrep -o "([0-9]{1,3}\.){3}[0-9]{1,3}" | sort -nr | uniq -c |awk '$1>=4{print $2}'`
echo
cat <<EOF
++++++++++++++++++++++welcome to use ssh login drop failed ip++++++++++++++
EOF
for i in `echo $IP_ADDR`
do
sudo iptables -L -v | grep $IP_ADDR
if [ $? -ne 0 ];then
iptables -A INPUT -s $i -m state --state NEW -m tcp -p tcp --dport 22 -j DROP
sudo iptables -L -v | grep $IP_ADDR
echo "This is $i is add in iptables,please exit ......"
else
echo "This is $i is exist in iptables,please exit ......"
fi
done
运行脚本后查看过滤规则
iptables -L -n
如果发现无法ping通自己,执行如下命令
# 默认策略设置为ACCEPT,否则后续操作会导致连接断开,无法再次连接
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT
# 清空所有规则
iptables -F
iptables -t nat -F
# 删除所有非系统默认的链
iptables -X
iptables -t nat -X
# 保存一下
iptables-save

浙公网安备 33010602011771号