自动化运维(DEVOPS)shell
1. shell基础知识
1.1 shell 脚本
1.1.1 创建脚本
脚本创建工具:
创建脚本的常见编辑器是 vi/vim.
脚本命名
shell脚本的命名简单来说就是要有意义,方便我们通过脚本名,来知道这个文件是干什么用的。
脚本内容:
各种可以执行的命令
注释内容:
单行注释:
除了首行的#不是注释外,其他所有行内容,只要首个字符是#,那么就表示该行是注释
#!/bin/bash
echo '1'
# echo '2' # 这一行就表示注释
echo '3'
多行注释:
多行注释有两种方法::<<! ... ! 和 :<<字符 ... 字符
#!/bin/bash
echo '1'
:<<! echo '2'
echo '3'
echo '4'
!
echo '5'
1.1.2 脚本执行
shell 执行的方式
Shell脚本的执行通常可以采用以下几种方式
bash /path/to/script-name 或 /bin/bash /path/to/script-name (强烈推荐使用)
/path/to/script-name 或 ./script-name (当前路径下执行脚本,权限不够 chmod +x script-name ,ls script-name 查看文件的状态,变绿表示可执行)
source script-name 或 . script-name (注意“.“点号)
1.1.3. 脚本开发规范
1、脚本命名要有意义,文件后缀是.sh
2、脚本文件首行是而且必须是脚本解释器
#!/bin/bash
3、脚本文件解释器后面要有脚本的基本信息等内容
脚本文件中尽量不用中文注释;
尽量用英文注释,防止本机或切换系统环境后中文乱码的困扰
常见的注释信息:脚本名称、脚本功能描述、脚本版本、脚本作者、联系方式等
4、脚本文件常见执行方式:bash 脚本名
5、脚本内容执行:从上到下,依次执行
6、代码书写优秀习惯;
1)成对内容的一次性写出来,防止遗漏。
如:()、{}、[]、''、``、""
2)[]中括号两端要有空格,书写时即可留出空格[ ],然后再退格书写内容。
3)流程控制语句一次性书写完,再添加内容
7、通过缩进让代码易读;(即该有空格的地方就要有空格)
1.2 shell 变量
普通变量
var=nihao
var1='nihao 666'
var2="use $var1" # 可编译内部变量
# 字符串拼接
name="Shell"
url="http://c.biancheng.net/shell/"
str1=$name$url #中间不能有空格
str2="$name $url" #如果被双引号包围,那么中间可以有空格
str3=$name": "$url #中间可以出现别的字符串
str4="$name: $url" #这样写也可以
str5="${name}Script: ${url}index.html" #这个时候需要给变量名加上大括号
echo $str1 #Shellhttp://c.biancheng.net/shell/
echo $str2 #Shell http://c.biancheng.net/shell/
echo $str3 #Shell: http://c.biancheng.net/shell/
echo $str4 #Shell: http://c.biancheng.net/shell/
echo $str5 #ShellScript: http://c.biancheng.net/shell/index.html
对于str1所在行代码,$name 和 $url 之间之所以不能出现空格,是因为当字符串不被任何一种引号包围时,遇到空格就认为字符串结束了,空格后边的内容会作为其他变量或者命令解析,这一点在《Shell字符串》中已经提到。
《Shell字符串》链接:http://c.biancheng.net/view/743.html
命令变量
kun2=`pwd`
echo $kun2 # /home/python/Desktop
kun3=$(pwd)
echo $kun3 # /home/python/Desktop
全局变量
env
env | grep execute_command # 查看某个具体的全局变量
export var='var_name' # 创建全局变量
# 例子
export GAN=kuncai123
echo $GAN # kuncai123
echo "my username is ${GAN}" # my username is kuncai123
变量的查看和取消
# 变量的查看
方式一:$变量名
方式二:"$变量名"
方式三:${变量名} # 使用频率高
方式四:"${变量名}" # 标准使用方式
# 只读变量
myUrl="http://c.biancheng.net/shell/"
readonly myUrl # 把变量限制为只读
# 取消变量
unset 变量名 #unset 命令不能删除只读变量。
shell 内置变量
符号 意义
$0 获取当前执行的shell脚本文件名,包括脚本路径
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9就要用大 括号括起来${10}
$# 获取当前shell命令行中参数的总个数
$? 获取执行上一个指令的返回值(0为成功,非0为失败)
$$ 表示当前Shell进程的ID,即pid
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
# 参考链接: http://c.biancheng.net/cpp/view/2739.html
$* 和 $@ 的区别
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
python@ubuntu:~/Desktop$ cat inner_var2.sh
#!/bin/bash/
# this is a shell inner variable shell
# $0 获取当前脚本的文件名
echo "this filename is inner_var.sh"
echo "this filename is $0 "
# $n 获取第n个参数的位置
echo "第1个位置参数是:$1"
echo "第2个位置参数是:$2"
echo "第3个位置参数是:$3"
echo "第4个位置参数是:$4"
echo "当前Shell进程的ID是: $$"
python@ubuntu:~/Desktop$ bash inner_var2.sh a b c d
this filename is inner_var.sh
this filename is inner_var2.sh
第1个位置参数是:a
第2个位置参数是:b
第3个位置参数是:c
第4个位置参数是:d
当前Shell进程的ID是: 29949
python@ubuntu:~/Desktop$ echo $?
0
字符串精确截取
str='sdwfghrhherth'
python@ubuntu:~/Desktop$ echo ${str::5} # 取前5个
sdwfg
python@ubuntu:~/Desktop$ echo ${str:5} # 取第5个之后的全部
hrhherth
python@ubuntu:~/Desktop$ echo ${str:0-5} # 截取最后5个
herth
python@ubuntu:~/Desktop$ echo ${str:0-6:3} # 取倒数第6个往后截取3个
hhe
默认值相关
#!/bin/bash/
# 这是一个设置变量默认值的测试。
username="$1"
echo "当前用户名是: ${username:-kuncai}"
marry_age="$2"
echo "国家法定男性结婚年龄是: ${marry_age+22} 岁"
bash var_default_value.sh
当前用户名是: kuncai
国家法定男性结婚年龄是: 22 岁
bash var_default_value.sh jason 18
当前用户名是: jason
国家法定男性结婚年龄是: 22 岁
2. shell 进阶
2.1 表达式
2.1.1 测试语句
A: test 条件表达式
B: [ 条件表达式 ]
test 1 == 1
echo $? # 0
[ 1 == 2 ]
echo $? # 1
2.1.2 条件表达式
逻辑表达式
常见的逻辑表达式有: && 和 ||
命令1 && 命令2
如果命令1执行成功,那么我才执行命令2 -- 夫唱妇随
如果命令1执行失败,那么命令2也不执行
命令1 || 命令2
如果命令1执行成功,那么命令2不执行 -- 对着干
如果命令1执行失败,那么命令2执行
# [ 1 = 1 ] && echo "条件成立"
条件成立
# [ 1 = 2 ] && echo "条件成立" # 前者执行失败,后者不执行,不输出
# [ 1 = 2 ] || echo "条件不成立"
条件不成立
# [ 1 = 1 ] || echo "条件不成立" # 前者执行成功,后者不执行,不输出
文件表达式
-f 判断输入内容是否是一个文件
-d 判断输入内容是否是一个目录
-x 判断输入内容是否可执行
# [ -f weizhi.sh ] && echo "是一个文件"
是一个文件
# [ -f weizhi.sddh ] || echo "不是一个文件"
不是一个文件
# [ -d weizhi.sddh ] || echo "不是一个目录"
不是一个目录
# mkdir nihao
# [ -d nihao ] && echo "是一个目录"
是一个目录
# [ -x age.sh ] || echo "文件没有执行权限"
文件没有执行权限
# [ -x test.sh ] && echo "文件有执行权限"
文件有执行权限
数值操作符
主要根据给定的两个值,判断第一个与第二个数的关系,如是否大于、小于、等于第二个数。常见选项如下:
n1 -eq n2 相等
n1 -gt n2 大于
n1 -lt n2 小于
n1 -ne n2 不等于
字符串比较
str1 == str2 str1和str2字符串内容一致
str1 != str2 str1和str2字符串内容不一致,!表示相反的意思
实践
判断字符是否内容一致
2.1.3 计算表达式
方式一:
$(()) $(( 计算表达式 ))
方式二:
let let 计算表达式
echo $((100/5))
20
let i=1 i=i+2 && echo $i
3
2.2 linux常见符号
2.2.1 重定向符号
> 表示将符号左侧的内容,以覆盖的方式输入到右侧文件中
>> 表示将符号左侧的内容,以追加的方式输入到右侧文件的末尾行中
echo 'hello world' > file.txt
cat file.txt
'hello world'
cp file.txt file1.txt
echo 'hello shell' >> file.txt
'hello world'
'hello shell'
cat file1.txt >> file.txt # 追加其它文件内容到本文件
'hello world'
'hello shell'
'hello world'
2.2.2 管道符
命令1 | 命令2
管道符左侧命令1 执行后的结果,传递给管道符右侧的命令2使用
env | grep SHELL
ps aux | grep 进程名 # 查看进程
2.2.3 其他符号
-
后台展示符号 &
& 就是将一个命令从前台转到后台执行 sleep 10 & ps aux | grep sleep
-
全部信息符号 2>&1
符号详解: 1 表示正确输出的信息 2 表示错误输出的信息 2>&1 代表所有输出的信息 脚本内容 test2.sh #!/bin/bash echo '下一条错误命令' dsfs 脚本执行结果 bash test2.sh 下一条错误命令 test2.sh: line 3: dsfs: command not found bash test2.sh 1>> test_log 2>> test_log # 上下效果相同 bash test2.sh >> test_log 2>&1 linux系统垃圾桶 /dev/null 是linux下的一个设备文件, 这个文件类似于一个垃圾桶,特点是:容量无限大
2.3 常用命令详解
2.3.1 grep命令详解
grep命令是我们常用的一个强大的文本搜索命令。
命令格式详解
grep [参数][关键字] <文件名>
注意:
我们在查看某个文件的内容的时候,是需要有<文件名>
grep命令在结合|(管道符)使用的情况下,后面的<文件名>是没有的
可以通过 grep --help 查看grep的帮助信息
参数详解
-c:只输出匹配行的计数。
-n:显示匹配行及行号。
-v:显示不包含匹配文本的所有行。
vim find.txt
# 新建并编辑文件
nihao aaa
nihao AAA
NiHao bbb
nihao CCC
grep -c aaa find.txt # 输出aaa的匹配行数
1
grep -n CCC find.txt # 输出匹配内容,同时显示行号
4:nihao CCC
grep -nv ni find.txt # 输出不匹配的内容及行号
NiHao bbb
精确定位错误代码
grep -nr [错误关键字] 文件名 # 快速定位 文本中的错位关键字信息
eg: grep -nr 'keywords' 文件路径
2.3.2 sed命令详解
sed 行文件编辑工具。因为它编辑文件是以行为单位的。
命令格式详解
命令格式:
sed [参数] '<匹配条件> [动作]' [文件名]
注意:
可以通过 sed --help 查看sed的帮助信息
参数详解:
参数为空 表示sed的操作效果,实际上不对文件进行编辑
-i 表示对文件进行编辑
注意:mac版本的bash中使用 -i参数,必须在后面单独加个东西: -i ''
匹配条件:
匹配条件分为两种:数字行号或者关键字匹配
关键字匹配格式:
'/关键字/'
注意:
隔离符号 / 可以更换成 @、#、!等符号
根据情况使用,如果关键字和隔离符号有冲突,就更换成其他的符号即可。
动作详解
-a 在匹配到的内容下一行增加内容
-i 在匹配到的内容上一行增加内容
-d 删除匹配到的内容
-s 替换匹配到的内容
注意:
上面的动作应该在参数为-i的时候使用,不然的话不会有效果
替换命令
关于替换,我们从三个方面来学习:
行号、列号、全体
命令格式:
sed -i [替换格式][文件名]
注意:替换命令的写法
's###' ---> 's#原内容##' ---> 's#原内容#替换后内容#'
admin-1@ubuntu:~$ cat sed.txt
nihao sed sed sed
nihao sed sed sed
nihao sed sed sed
sed -i '1,3s#sed#SED#2' sed.txt
cat sed.txt
nihao sed SED sed
nihao sed sed sed
nihao sed SED sed
增加操作
方式1 -- 追加
sed -i '行号a增加的内容' 文件名
在指定行号的下一行增加内容
方式2 -- 插入
sed -i '行号i增加的内容' 文件名
注意:
如果增加多行,可以在行号位置写个范围值,彼此间使用逗号隔开,例如
sed -i '1,3a增加内容' 文件名
cat sed.txt
nihao sed SED sed
nihao sed sed sed
nihao sed SED sed
sed '2aappend new line' sed.txt # 注意没加 -i 不改变原数据结构
nihao sed SED sed
nihao sed sed sed
append new line
nihao sed SED sed
sed '2iinsert new line' sed.txt
nihao sed SED sed
insert new line
nihao sed sed sed
nihao sed SED sed
删除操作
指定行号删除
sed -i '行号d' 文件名
如果删除多行,可以在行号位置多写几个行号,彼此间使用逗号隔开,例如
sed -i '1,3d' 文件名
sed -i '2d' sed.txt # 删除第2行
cat sed.txt
nihao sed SED sed
nihao sed sed sed
2.3.3 awk命令详解
awk是一个功能非常强大的文档编辑工具,它不仅能以行为单位还能以列为单位处理文件。
命令格式:
awk [参数] '[ 动作]' [文件名]
常见参数:
-F 指定行的分隔符
常见动作:
print 显示内容
$0 显示当前行所有内容
$n 显示当前行的第n列内容,如果存在多个$n,它们之间使用逗号(,)隔开
常见内置变量
FILENAME 当前输入文件的文件名,该变量是只读的
NR 指定显示行的行号
NF 输出 最后一列的内容
OFS 输出格式的列分隔符,缺省是空格
FS 输入文件的列分融符,缺省是连续的空格和Tab
python@ubuntu:~/Desktop$ cat awk.txt
nihao1 sed sed sed
nihao2 sed sed sed
nihao3 sed sed sed
nihao4 sed sed sed
python@ubuntu:~/Desktop$ awk 'NR==1 {print $1,$3}' awk.txt # 打印第1行 第1,3列
nihao1 sed
python@ubuntu:~/Desktop$ sed -i 's# #:#g' awk.txt
cat awk.txt
nihao1:sed:sed:sed
nihao2:sed:sed:sed
nihao3:sed:sed:sed
nihao4:sed:sed:sed
python@ubuntu:~/Desktop$ awk -F ':' '{print $1,$3}' awk.txt
nihao1 sed
nihao2 sed
nihao3 sed
nihao4 sed
python@ubuntu:~/Desktop$ awk 'BEGIN{OFS=":"} {print NR,$0}' sed.txt
1:nihao1 sed sed sed
2:nihao2 sed sed sed
3:nihao3 sed sed sed
4:nihao4 sed sed sed
2.3.4 find命令详解
命令格式:
find [路径][参数] [关键字]
参数详解
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-type 查找某一类型的文件,
诸如:
b - 块设备文件 d - 目录 c - 字符设备文件
p - 管道文件 l - 符号链接文件 f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。
-mindepth n:在查找文件时,查找当前目录中的第n层目录的文件,然后再在其子目录中查找。
! : 表示取反
find /home -type d -name 'conda*'
find /home -type f -name 'test'
3. 流程控制
3.1 简单流程控制语句
3.1.1 if 语句
# 使用语法
if [ 条件 ]
then
指令1
elif [ 条件2 ]
then
指令2
else
指令3
fi
python@ubuntu:~/Desktop$ vim if2.sh
#编辑脚本
#!/bin/bash
# 多if语句的使用场景
if [ "$1" == "start" ]
then
echo "服务启动中..."
elif [ "$1" == "stop" ]
then
echo "服务关闭中..."
elif [ "$1" == "restart" ]
then
echo "服务重启中..."
else
echo "$0 脚本的使用方式: $0 [ start | stop | restart ]"
fi
# 执行脚本
python@ubuntu:~/Desktop$ bash if2.sh restart
服务重启中...
python@ubuntu:~/Desktop$ bash if2.sh start
服务启动中...
python@ubuntu:~/Desktop$ bash if2.sh stop
服务关闭中...
python@ubuntu:~/Desktop$ bash if2.sh stop22
if2.sh 脚本的使用方式: if2.sh [ start | stop | restart ]
3.1.2 case选择语句
case 变量名 in
值1)
指令1
;;
值2)
指令2
;;
值3)
指令3
;;
esac
python@ubuntu:~/Desktop$ vim case.sh
# 编辑脚本
#!/bin/bash
# 这是case语句使用场景的测试
case "$1" in
"start")
echo "service is starting"
;;
"stop")
echo "service is stoping"
;;
"restart")
echo "service is restarting"
;;
*)
echo "$0 correct using way is: $0 [ start|stop|restart ]"
;;
esac
# 执行脚本
python@ubuntu:~/Desktop$ bash case.sh start
service is starting
python@ubuntu:~/Desktop$ bash case.sh stop
service is stoping
python@ubuntu:~/Desktop$ bash case.sh restart
service is restarting
python@ubuntu:~/Desktop$ bash case.sh restart2
case.sh the script correct using way is: case.sh [ start|stop|restart ]
3.1.3 for 循环语句
for 值 in 列表
do
执行语句
done
ps:如果需要手动构建列表,比列表[a1,b2,c3]则可以写成 for i in {a1,b2,c3} do; ... done
另外就是列表中只有一个值,后面的逗号也不能省略;
python@ubuntu:~/Desktop$ vim for.sh
# 编辑脚本
#!/bin/bash
# for语句使用场景测试
cpath=$(pwd)
for i in $(ls $cpath)
do
echo "$cpath 目录下包含文件${i}"
done
# 执行脚本
python@ubuntu:~/Desktop$ bash for.sh
/home/python/Desktop 目录下包含文件case.sh
/home/python/Desktop 目录下包含文件for.sh
/home/python/Desktop 目录下包含文件hive简介.png
/home/python/Desktop 目录下包含文件if2.sh
/home/python/Desktop 目录下包含文件if.sh
/home/python/Desktop 目录下包含文件inner_var2.sh
3.1.4 while循环语句
while 条件
do
执行语句
done
条件的类型: 命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
python@ubuntu:~/Desktop$ vim while.sh
# 编辑脚本
#!/bin/bash
# while循环语句测试
a=1
while [ "${a}" -lt 5 ]
do
echo "${a}"
a=$((a+1))
done
# 执行脚本
python@ubuntu:~/Desktop$ bash while.sh
1
2
3
4
3.1.5 until循环语句
until 条件
do
执行语句
done
条件的类型: 命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
停止条件正好和while相反,只要条件不满足,就一直循环下去
python@ubuntu:~/Desktop$ vim until.sh
# 编辑脚本
#!/bin/bash
# until循环语句测试
a=1
until [ "${a}" -eq 5 ]
do
echo "${a}"
a=$((a+1))
done
# 执行脚本
python@ubuntu:~/Desktop$ bash until.sh
1
2
3
4
3.2 复杂流程控制语句
3.2.1 函数
函数就是将某些命令组合起来实现某一特殊功能的方式,是脚本编写中非常重要的一部分。
传参函数格式:
传参数
函数名 参数
函数体调用参数:
注意:
类似于shell内置变量中的位置参数
函数名( ){
函数体 $n
}
python@ubuntu:~/Desktop$ vim func.sh
# 编辑脚本
#!/bin/bash
# 函数定义及调用
print2(){
echo "this is just a function test !"
}
print2
# 函数传参演示
print3(){
echo "my name is $1"
echo "your name is $2"
}
print3 "$1" "$2"
# 执行脚本
python@ubuntu:~/Desktop$ bash func.sh jason judy
this is just a function test !
my name is jason
your name is judy
3.3 综合案例
需求
1、zonghe.sh 脚本执行时候需要添加参数才能执行
参数和功能详情如下:
参数 执行效果
start 服务启动中...
stop 服务关闭中...
restart 服务重启中...
* 脚本帮助信息...
2、参数的数量有限制,只能是1个,多余一个会提示脚本的帮助信息
3、帮助信息使用函数来实现
信息内容:脚本 zonghe.sh 使用方式 zonghe.sh [ start|stop|restart ]
代码实践
python@ubuntu:~/Desktop$ vim zonghe.sh
# 编辑脚本
#!/bin/bash
# 注意{}中一定要换行,不然语法报错!
helpinfo(){
echo "脚本$0 使用方式是: $0 [ start|stop|restart ]"
}
# 先编写主结构
if [ $# -eq 1 ] # 如果参数数量是1个
then
# 这是case语句使用场景的测试
case "$1" in
"start")
echo "service is starting"
;;
"stop")
echo "service is stoping"
;;
"restart")
echo "service is restarting"
;;
*)
helpinfo
;;
esac
else
helpinfo
fi
# 执行脚本
python@ubuntu:~/Desktop$ bash zonghe.sh start 2
脚本zonghe.sh 使用方式是: zonghe.sh [ start|stop|restart ]
python@ubuntu:~/Desktop$ bash zonghe.sh start
service is starting
python@ubuntu:~/Desktop$ bash zonghe.sh stop2
脚本zonghe.sh 使用方式是: zonghe.sh [ start|stop|restart ]
4. 代码发布
代码发布流程图
![代码发布流程图]](https://img2020.cnblogs.com/blog/1563359/202004/1563359-20200429190824006-748254772.png)
**文件的压缩和解压**
文件的压缩
压缩格式:
tar zcvf 压缩后的文件名 将要压缩的文件
文件的解压
解压格式:
tar xf 压缩后的文件名 -C 解压后的路径
命令参数详解
z 指定压缩文件的格式为 tar.gz
c 表示压缩
v 显示详细过程
f 指定压缩文件
x 解压
查看压缩文件内容
zcat 压缩文件
**文件的传输**
将本地文件推送到远程主机
scp script.tar.gz root@192.168.8.15:/root/
将远程主机的文件拉取到本地
scp root@192.168.8.15:/root/script.tar.gz ./
win10本机 --> ubuntu
scp city80.txt python@192.168.5.137:/home/python/Desktop
ubuntu 本机-->win10
scp city80.txt 15583@172.16.14.152:
直接拷贝文件到了 C:User15583 目录下
**文件的备份**
方式一:复制备份
cp script script-$(date +%Y%m%d%H%M%S)
方式二:移动备份
mv script script-$(date +%Y%m%d%H%M%S)
python@ubuntu:~/Desktop$ ls
script
# 压缩文件
python@ubuntu:~/Desktop$ tar zcf script.tar.gz script/
python@ubuntu:~/Desktop$ ls
script script.tar.gz
# 移动备份文件
python@ubuntu:~/Desktop$ mv script script-$(date +%Y%m%d%H%M%S)
python@ubuntu:~/Desktop$ ls
script-20190520121245 script.tar.gz
# 解压压缩文件
python@ubuntu:~/Desktop$ tar zxf script.tar.gz
python@ubuntu:~/Desktop$ ls
script script.tar.gz script-20190520121245
5. 环境部署
mkdir /data/{server,logs,backup,softs,virtual,scripts,codes} -p
# 虚拟环境搭建的两种方式
# 方式1--这种默认安装的是python2.x版本的,不推荐。
sudo pip3 install virtualenvs
sudo apt-get install virtualenvs
sudo apt-get install virtualenvswrapper
# 创建虚拟环境
mkvirtualenv -p python3 环境名称 # 不指定python版本,则默认是2.x版本
workon 环境名称 # 进入虚拟环境
pip install flask==0.10.1 # 指定版本安装flask
# 方式2
apt-get install python-virtualenv -y
# /media/python/myfiles/.virtualenvs
virtualenv -p /home/python/anaconda3/bin/python3.7 kun
source kun/bin/activate
# 安装django包
cd /media/python/myfiles/data/softs/Django-1.10.7
python setup.py install
# 创建django项目
cd .../data/server
django-admin startproject midou
# 创建应用
cd .../data/server/miduo
django-admin startapp user
# python manage.py startapp user
# 注册应用
# vim midou/settings.py
33 INSTALLED_APPS = [
34 'django.contrib.admin',
35 'django.contrib.auth',
36 'django.contrib.contenttypes',
37 'django.contrib.sessions',
38 'django.contrib.messages',
39 'django.contrib.staticfiles',
40 'user',
41 ]
# view和url配置
vim user/views.py
1 from django.shortcuts import render
2 from django.http import HttpResponse
3
4 # Create your views here.
5
6 def hello(request):
7 return HttpResponse("midou V1.0")
vim midou/urls.py
16 from django.conf.urls import url
17 from django.contrib import admin
18
19 from user.views import *
20
21 urlpatterns = [
22 url(r'^admin/', admin.site.urls),
23 url(r'^hello/$', hello),
# 启动django
python manage.py runserver
python manage.py runserver >> /dev/null 2>&1 &
访问 http://127.0.0.1:8000/hello/
输出 midou V1.0
# 安装pcre包
# 解压压缩包
cd .../data/softs
tar zxf pcre-8.39.tar.gz
cd pcre-8.39
# 配置 -- 根据默认的配置项或者更改配置项,生成编译配置文件(Makefile)
./configure
# 编译 -- 根据 Makefile 内容,编译生成指定的软件所需要的所有文件
make
# 安装 -- 将编译生成的所有文件,转移到指定安装的目录下面 --prefix
sudo make install
# 安装ngix包
# 解压压缩包
cd .../data/soft/
tar zxf nginx-1.10.2.tar.gz
# 配置
cd nginx-1.10.2/
./configure --prefix=/media/python/myfiles/data/server/nginx --without-http_gzip_module
# 编译
make
# 安装
sudo make install
nginx简单操作
# 检查
.../data/server/nginx/sbin/nginx -t
# nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
# 先看报错
ldd /data/server/nginx/sbin/nginx
# 显示 libpcre.so.1 => not found
# 查看报错文件
find / -name "libpcre.so.1"
# /home/python/anaconda3/pkgs/pcre-8.42-h439df22_0/lib/libpcre.so.1
# /home/python/anaconda3/lib/libpcre.so.1
# 找到文件,我没有问题 是nginx默认找库文件的路径有问题
# 建立软连链接--两边都使用绝对路径
sudo ln -s /home/python/anaconda3/lib/libpcre.so.1 /lib/x86_64-linux-gnu/
# 再次检查
sudo nginx/sbin/nginx -t
# /nginx/conf/nginx.conf syntax is ok
# /nginx/conf/nginx.conf test is successful
# 只有root才有权限访问1024以下端口,故修改端口为7070
开启
/data/server/nginx/sbin/nginx
关闭
/data/server/nginx/sbin/nginx -s stop
重载
/data/server/nginx/sbin/nginx -s reload
# netstat -anp | grep service_name # 查看某个服务的端口,不灵!!!
netstat -tnulp # 查看所有进程
# 可进行端口与pid的互相查询
netstat -tnulp|grep pid或端口号 # 查找进程或端口的占用情况
# 杀死8000端口对应的进程
lsof -Pti :8000 # 查看端口对应的pid lsof-ti :8000 效果相同
kill $(lsof -Pti :8000)
lsof -i :端口号 # 查看端口对应的进程pid等信息
ps -ef|grep PID # 查看进程对应的详细信息
使用 python manage.py runserver 启动django项目时,直接使用ps aux|grep django是无法找到该进程的,可以根据端口号8000使用 lsof -i :8000或者 netstat -tnulp|grep 8000进行查找得到Pid,再使用ps -ef|grep PID 查看进程对应的详细信息。
或者使用 ps aux|grep runserver查找到该服务对应的信息(不包含端口号)
记住两个命令就够了:
ps aux|grep xx 可查询服务和进程
netstat -tnulp|grep xx 可查询端口和进程
sudo passwd root # 设置root用户密码
su # 切换到管理员账号
su '用户名' # 切换到指定用户
exit # 退出root用户,回到前一用户
6. 手工代码发布
mkdir /data/{server,logs,backup,softs,virtual,scripts,codes} -p
# 虚拟环境搭建的两种方式
# 方式1--这种默认安装的是python2.x版本的,不推荐。
sudo pip3 install virtualenvs
sudo apt-get install virtualenvs
sudo apt-get install virtualenvswrapper
# 创建虚拟环境
mkvirtualenv -p python3 环境名称 # 不指定python版本,则默认是2.x版本
workon 环境名称 # 进入虚拟环境
pip install flask==0.10.1 # 指定版本安装flask
# 方式2
apt-get install python-virtualenv -y
# /media/python/myfiles/.virtualenvs
virtualenv -p /home/python/anaconda3/bin/python3.7 kun
source kun/bin/activate
# 安装django包
cd /media/python/myfiles/data/softs/Django-1.10.7
python setup.py install
# 创建django项目
cd .../data/server
django-admin startproject midou
# 创建应用
cd .../data/server/miduo
django-admin startapp user
# python manage.py startapp user
# 注册应用
# vim midou/settings.py
33 INSTALLED_APPS = [
34 'django.contrib.admin',
35 'django.contrib.auth',
36 'django.contrib.contenttypes',
37 'django.contrib.sessions',
38 'django.contrib.messages',
39 'django.contrib.staticfiles',
40 'user',
41 ]
# view和url配置
vim user/views.py
1 from django.shortcuts import render
2 from django.http import HttpResponse
3
4 # Create your views here.
5
6 def hello(request):
7 return HttpResponse("midou V1.0")
vim midou/urls.py
16 from django.conf.urls import url
17 from django.contrib import admin
18
19 from user.views import *
20
21 urlpatterns = [
22 url(r'^admin/', admin.site.urls),
23 url(r'^hello/$', hello),
# 启动django
python manage.py runserver
python manage.py runserver >> /dev/null 2>&1 &
访问 http://127.0.0.1:8000/hello/
输出 midou V1.0
# 安装pcre包
# 解压压缩包
cd .../data/softs
tar zxf pcre-8.39.tar.gz
cd pcre-8.39
# 配置 -- 根据默认的配置项或者更改配置项,生成编译配置文件(Makefile)
./configure
# 编译 -- 根据 Makefile 内容,编译生成指定的软件所需要的所有文件
make
# 安装 -- 将编译生成的所有文件,转移到指定安装的目录下面 --prefix
sudo make install
# 安装ngix包
# 解压压缩包
cd .../data/soft/
tar zxf nginx-1.10.2.tar.gz
# 配置
cd nginx-1.10.2/
./configure --prefix=/media/python/myfiles/data/server/nginx --without-http_gzip_module
# 编译
make
# 安装
sudo make install
nginx简单操作
# 检查
.../data/server/nginx/sbin/nginx -t
# nginx/sbin/nginx: error while loading shared libraries: libpcre.so.1: cannot open shared object file: No such file or directory
# 先看报错
ldd /data/server/nginx/sbin/nginx
# 显示 libpcre.so.1 => not found
# 查看报错文件
find / -name "libpcre.so.1"
# /home/python/anaconda3/pkgs/pcre-8.42-h439df22_0/lib/libpcre.so.1
# /home/python/anaconda3/lib/libpcre.so.1
# 找到文件,我没有问题 是nginx默认找库文件的路径有问题
# 建立软连链接--两边都使用绝对路径
sudo ln -s /home/python/anaconda3/lib/libpcre.so.1 /lib/x86_64-linux-gnu/
# 再次检查
sudo nginx/sbin/nginx -t
# /nginx/conf/nginx.conf syntax is ok
# /nginx/conf/nginx.conf test is successful
# 只有root才有权限访问1024以下端口,故修改端口为7070
开启
/data/server/nginx/sbin/nginx
关闭
/data/server/nginx/sbin/nginx -s stop
重载
/data/server/nginx/sbin/nginx -s reload
# netstat -anp | grep service_name # 查看某个服务的端口,不灵!!!
netstat -tnulp # 查看所有进程
# 可进行端口与pid的互相查询
netstat -tnulp|grep pid或端口号 # 查找进程或端口的占用情况
# 杀死8000端口对应的进程
lsof -Pti :8000 # 查看端口对应的pid lsof-ti :8000 效果相同
kill $(lsof -Pti :8000)
lsof -i :端口号 # 查看端口对应的进程pid等信息
ps -ef|grep PID # 查看进程对应的详细信息
使用 python manage.py runserver 启动django项目时,直接使用ps aux|grep django是无法找到该进程的,可以根据端口号8000使用 lsof -i :8000或者 netstat -tnulp|grep 8000进行查找得到Pid,再使用ps -ef|grep PID 查看进程对应的详细信息。
或者使用 ps aux|grep runserver查找到该服务对应的信息(不包含端口号)
记住两个命令就够了:
ps aux|grep xx 可查询服务和进程
netstat -tnulp|grep xx 可查询端口和进程
sudo passwd root # 设置root用户密码
su # 切换到管理员账号
su '用户名' # 切换到指定用户
exit # 退出root用户,回到前一用户
6. 手工代码发布
#!/bin/bash
# 功能:打包代码
# 脚本名:tar_code.sh
# 作者:itcast
# 版本:V 0.3
# 联系方式:www.itcast.cn
FILE='django.tar.gz'
CODE_DIR='/data/codes'
CODE_PRO='django'
code_tar(){
cd "${CODE_DIR}"
[ -f "${FILE}" ] && rm -f "${FILE}"
tar zcf "${FILE}" "${CODE_PRO}"
}
code_tard
7. 脚本代码发布
#!/bin/bash
# 功能:打包代码
# 脚本名:deploy.sh
# 作者:kun
# 版本:V 0.6
# 定义本地 变量
ROOT='/media/python/myfiles/data'
LOG_FILE="${ROOT}/logs/deploy.log"
PID_FILE="${ROOT}/tmp/deploy.pid"
# 增加日志功能函数
write_log(){
DATE=$(date +%F)
TIME=$(date +%T)
buzhou="$1"
echo "${DATE} ${TIME} $0 : ${buzhou} " >> "${LOG_FILE}"
}
# 增加锁文件
add_lock(){
echo "增加锁文件"
touch "${PID_FILE}"
write_log "增加锁文件"
}
# 删除锁文件
del_lock(){
echo "删除锁文件"
rm -f "${PID_FILE}"
write_log "删除锁文件"
}
# 获取代码
get_code(){
echo "获取代码"
write_log "获取代码"
}
# 打包代码
tar_code(){
echo "打包代码"
# ssh root@192.168.8.15 "/bin/bash /data/scripts/tar_code.sh"
"/bin/bash ${ROOT}/scripts/tar_code.sh"
write_log "打包代码"
}
# 传输代码
scp_code(){
echo "传输代码"
# cd /data/codes/
# [ -f django.tar.gz ] && rm -f django.tar.gz
# scp root@192.168.8.15:/data/codes/django.tar.gz ./
write_log "传输代码"
}
# 关闭应用
stop_serv(){
echo "关闭应用"
write_log "关闭应用"
echo "关闭nginx应用"
${ROOT}/server/nginx/sbin/nginx -s stop
write_log "关闭nginx应用"
echo "关闭django应用"
kill $(lsof -Pti :8000)
write_log "关闭django应用"
}
# 解压代码
untar_code(){
echo "解压代码"
cd ${ROOT}/codes/
tar zxf django.tar.gz
write_log "解压代码"
}
# 放置代码
fangzhi_code(){
echo "放置代码"
write_log "放置代码"
echo "备份老文件"
mv ${ROOT}/server/midou/user/views.py ${ROOT}/backup/views.py-$(date +%Y%m%d%H%M%S)
write_log "备份老文件"
echo "放置新文件"
cd ${ROOT}/codes
mv django/views.py ${ROOT}/server/midou/user/
write_log "放置新文件"
}
# 开启应用
start_serv(){
echo "开启应用"
write_log "开启应用"
echo "开启django应用"
source ${ROOT}/../.virtualenvs/kun/bin/activate
cd ${ROOT}/server/midou/
python manage.py runserver >> /dev/null 2>&1 &
deactivate
write_log "开启django应用"
echo "开启nginx应用"
${ROOT}/server/nginx/sbin/nginx
write_log "开启nginx应用"
}
# 检查
check(){
echo "检查应用"
netstat -tnulp | grep ':80'
write_log "检查应用"
}
# 部署函数
pro_deploy(){
add_lock
get_code
tar_code
scp_code
stop_serv
untar_code
fangzhi_code
start_serv
check
del_lock
}
# 报错信息
err_msg(){
echo "该脚本 $0 正在运行,请稍候..."
}
# 帮助信息
usage(){
echo "脚本 $0 的使用方式是: $0 [ deploy ]"
}
# 主函数
main(){
case "$1" in
deploy)
if [ -f "${PID_FILE}" ]
then
err_msg
else
pro_deploy
fi
;;
*)
usage
;;
esac
}
# 调用主函数
if [ "$#" -ne 1 ]
then
usage
else
main $1
fi
扩展
date +%Y%m%d //显示前天年月日
date +%Y%m%d --date="+1 day" //显示前一天的日期
date +%Y%m%d --date="-1 day" //显示后一天的日期
date +%s //从 1970 年 1 月 1 日 00:00:00 UTC 到目前为止的秒数(时间戳)
vDay=`echo ${vDay}|awk '{print substr($0,1,4)"-"substr($0,5,2)"-"substr($0,7,2)}'`