Repository: dunwu/linux-tutorial
Branch: master
Commit: b672dd042960
Files: 351
Total size: 742.6 KB
Directory structure:
gitextract_eglus17c/
├── .editorconfig
├── .gitattributes
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── assets/
│ ├── docker.xmind
│ └── linux.xmind
├── codes/
│ ├── docker/
│ │ └── docker-compose-demo/
│ │ ├── Dockerfile
│ │ ├── app.py
│ │ ├── docker-compose.yml
│ │ └── run.sh
│ ├── expect/
│ │ └── 远程登录.sh
│ ├── linux/
│ │ ├── README.md
│ │ ├── build/
│ │ │ ├── Java应用运行脚本模板/
│ │ │ │ ├── lifecycle.sh
│ │ │ │ ├── start.sh
│ │ │ │ ├── stop.sh
│ │ │ │ └── utils.sh
│ │ │ ├── README.md
│ │ │ ├── helper.sh
│ │ │ ├── java-app-boot.sh
│ │ │ ├── java-app-release.sh
│ │ │ ├── java-app-run.sh
│ │ │ ├── js-app-release.sh
│ │ │ ├── main.sh
│ │ │ ├── spring-boot-run.sh
│ │ │ └── update-code.sh
│ │ ├── conf/
│ │ │ └── etc/
│ │ │ └── sysctl.conf
│ │ ├── download.sh
│ │ ├── dunwu-ops.sh
│ │ ├── dunwu-soft.sh
│ │ ├── dunwu-sys.sh
│ │ ├── libtest/
│ │ │ ├── README.md
│ │ │ ├── env-test.sh
│ │ │ ├── git-check.sh
│ │ │ ├── git-update.sh
│ │ │ └── nodejs-test.sh
│ │ ├── soft/
│ │ │ ├── README.md
│ │ │ ├── arthas-install.sh
│ │ │ ├── config/
│ │ │ │ ├── fastdfs/
│ │ │ │ │ ├── client.conf
│ │ │ │ │ ├── storage.conf
│ │ │ │ │ └── tracker.conf
│ │ │ │ ├── mysql/
│ │ │ │ │ └── my.cnf
│ │ │ │ ├── nginx/
│ │ │ │ │ ├── conf/
│ │ │ │ │ │ └── fdfs.conf
│ │ │ │ │ ├── nginx.conf
│ │ │ │ │ └── nginx.service
│ │ │ │ ├── redis/
│ │ │ │ │ ├── cluster/
│ │ │ │ │ │ ├── 27001/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 27002/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 27003/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 27004/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 27005/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 27006/
│ │ │ │ │ │ │ └── sentinel.conf
│ │ │ │ │ │ ├── 7001/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7002/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7003/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7004/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7005/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7006/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7007/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7008/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7009/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7010/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7011/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── 7012/
│ │ │ │ │ │ │ └── redis.conf
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── redis-cluster.sh
│ │ │ │ │ │ ├── redis-cluster2.sh
│ │ │ │ │ │ ├── start-cluster.sh
│ │ │ │ │ │ ├── start-cluster2.sh
│ │ │ │ │ │ └── start-sentinel.sh
│ │ │ │ │ ├── redis.conf
│ │ │ │ │ └── redis.service
│ │ │ │ └── settings-aliyun.xml
│ │ │ ├── docker-install.sh
│ │ │ ├── elk/
│ │ │ │ ├── boot-elk.sh
│ │ │ │ ├── config/
│ │ │ │ │ ├── filebeat.yml
│ │ │ │ │ ├── logback.xml
│ │ │ │ │ └── logstash.conf
│ │ │ │ ├── install-elk.sh
│ │ │ │ ├── install_elasticserch.sh
│ │ │ │ ├── install_filebeat.sh
│ │ │ │ ├── install_kibana.sh
│ │ │ │ └── install_logstash.sh
│ │ │ ├── fastdfs-install.sh
│ │ │ ├── gitlab/
│ │ │ │ ├── gitlab-backup.sh
│ │ │ │ └── gitlab.sh
│ │ │ ├── gitlab-install.sh
│ │ │ ├── install_grafana.sh
│ │ │ ├── jdk8-install.sh
│ │ │ ├── jenkins-install.sh
│ │ │ ├── kafka-install.sh
│ │ │ ├── lib/
│ │ │ │ ├── docker.sh
│ │ │ │ ├── file.sh
│ │ │ │ ├── git.sh
│ │ │ │ ├── java.sh
│ │ │ │ ├── maven.sh
│ │ │ │ ├── mysql.sh
│ │ │ │ ├── net.sh
│ │ │ │ ├── nodejs.sh
│ │ │ │ ├── string.sh
│ │ │ │ └── utils.sh
│ │ │ ├── maven-install.sh
│ │ │ ├── mongodb-install.sh
│ │ │ ├── mysql-backup.sh
│ │ │ ├── mysql-install.sh
│ │ │ ├── mysql-recovery.sh
│ │ │ ├── nacos-install.sh
│ │ │ ├── nexus-install.sh
│ │ │ ├── nginx-install.sh
│ │ │ ├── nodejs-install.sh
│ │ │ ├── redis-install.sh
│ │ │ ├── rocketmq-install.sh
│ │ │ ├── tomcat8-install.sh
│ │ │ ├── zookeeper-install.sh
│ │ │ ├── zsh/
│ │ │ │ └── oh-my-zsh-install.sh
│ │ │ └── zsh-install.sh
│ │ ├── sys/
│ │ │ ├── README.md
│ │ │ ├── change-yum-repo.sh
│ │ │ ├── install-libs.sh
│ │ │ ├── install-tools.sh
│ │ │ ├── set-dns.sh
│ │ │ ├── set-ntp.sh
│ │ │ ├── stop-firewall.sh
│ │ │ ├── sys-settings.sh
│ │ │ ├── syscheck.sh
│ │ │ └── yum/
│ │ │ ├── Centos-5.repo
│ │ │ ├── Centos-6.repo
│ │ │ └── Centos-7.repo
│ │ └── tool/
│ │ ├── Autoinstall_ELK_V1.3.sh
│ │ ├── Cpu_Limit.sh
│ │ ├── Custom_Rm.sh
│ │ ├── Daily_Archive.sh
│ │ ├── Hourly_Archive.sh
│ │ ├── gitcheck
│ │ ├── 删除用户脚本.sh
│ │ └── 查看指定目录磁盘使用情况.sh
│ └── shell/
│ ├── README.md
│ ├── lib/
│ │ └── env.sh
│ ├── mysql/
│ │ ├── SQL批处理执行脚本.sh
│ │ ├── 向数据库中插入数据.sh
│ │ ├── 格式化输出数据.sh
│ │ └── 连接数据库并发送命令.sh
│ ├── 基本脚本/
│ │ ├── echo示例.sh
│ │ ├── exit命令.sh
│ │ ├── printf示例.sh
│ │ ├── 使用expr执行数学运算.sh
│ │ ├── 使用内联重定向计算表达式.sh
│ │ ├── 使用方括号执行数学运算.sh
│ │ ├── 反引号的使用.sh
│ │ ├── 变量使用示例.sh
│ │ ├── 在脚本中使用bc.sh
│ │ ├── 字符串使用示例.sh
│ │ ├── 数组使用示例.sh
│ │ ├── 显示时间和登录者.sh
│ │ ├── 显示系统变量和转义字符.sh
│ │ ├── 注释示例.sh
│ │ └── 通过反引号获得当前日期并生成唯一文件名.sh
│ ├── 控制/
│ │ ├── 定时执行脚本.sh
│ │ ├── 捕捉信号.sh
│ │ ├── 捕捉脚本的退出.sh
│ │ └── 移除捕捉.sh
│ ├── 操作符/
│ │ ├── 关系运算符.sh
│ │ ├── 字符串运算符.sh
│ │ ├── 布尔运算符.sh
│ │ ├── 文件测试运算符.sh
│ │ ├── 算术运算符.sh
│ │ └── 逻辑运算符.sh
│ ├── 文件操作/
│ │ ├── log.txt
│ │ ├── 创建临时文件.sh
│ │ ├── 创建临时目录.sh
│ │ ├── 文件路径操作.sh
│ │ ├── 目录基本操作.sh
│ │ └── 读文件.sh
│ ├── 查找替换文本/
│ │ ├── gawk/
│ │ │ ├── gawk.sh
│ │ │ ├── gawk函数库
│ │ │ ├── gawk脚本
│ │ │ ├── script
│ │ │ ├── test
│ │ │ ├── 使用变量.sh
│ │ │ ├── 使用模式,结构化命令.sh
│ │ │ ├── 自定义函数.sh
│ │ │ ├── 调用函数库和脚本.sh
│ │ │ └── 输出.sh
│ │ ├── grep.sh
│ │ ├── regex/
│ │ │ ├── 目录文件计数.sh
│ │ │ └── 邮件验证.sh
│ │ └── sed/
│ │ ├── sed文件操作.sh
│ │ ├── sed编辑器基础.sh
│ │ ├── test
│ │ ├── 保持空间.sh
│ │ ├── 删除指定的空白行和删除html标签.sh
│ │ ├── 在脚本中使用sed.sh
│ │ ├── 排除命令.sh
│ │ ├── 模式替代.sh
│ │ ├── 测试.sh
│ │ ├── 给文件中的行编号.sh
│ │ ├── 跳转.sh
│ │ ├── 输出末尾指定行数的数据.sh
│ │ └── 重定向sed输出.sh
│ ├── 系统管理/
│ │ ├── 控制远程服务器执行指令.sh
│ │ └── 系统用户管理.sh
│ ├── 脚本函数/
│ │ ├── lib.sh
│ │ ├── 从函数返回数组.sh
│ │ ├── 使用return命令.sh
│ │ ├── 使用全局变量带来的问题.sh
│ │ ├── 使用函数输出.sh
│ │ ├── 使用命令行中传递的参数.sh
│ │ ├── 使用局部变量.sh
│ │ ├── 使用库函数.sh
│ │ ├── 全局变量.sh
│ │ ├── 函数入参.sh
│ │ ├── 函数入参2.sh
│ │ ├── 函数基本示例.sh
│ │ ├── 函数基本示例2.sh
│ │ ├── 函数递归.sh
│ │ ├── 在函数中使用参数.sh
│ │ ├── 想函数传数组数据.sh
│ │ ├── 累加数组中的值.sh
│ │ └── 默认退出状态码.sh
│ ├── 菜单/
│ │ ├── 使用msgbox部件.sh
│ │ ├── 使用select命令.sh
│ │ ├── 使用脚本菜单.sh
│ │ └── 在脚本中使用dialog命令.sh
│ ├── 输入和输出/
│ │ ├── test
│ │ ├── test1
│ │ ├── 临时重定向.sh
│ │ ├── 使用getopts.sh
│ │ ├── 使用getopts处理选项和参数.sh
│ │ ├── 使用getopt命令.sh
│ │ ├── 使用shift命令.sh
│ │ ├── 免密码传输.sh
│ │ ├── 分离参数和选项.sh
│ │ ├── 列出当前脚本打开的文件描述符.sh
│ │ ├── 创建自己的重定向/
│ │ │ ├── 从以重定向的文件描述符中恢复.sh
│ │ │ ├── 关闭文件描述符.sh
│ │ │ ├── 创建读写文件描述符.sh
│ │ │ ├── 创建输入文件描述符.sh
│ │ │ └── 创建输出文件描述符.sh
│ │ ├── 参数计数.sh
│ │ ├── 在脚本中使用重定向输入.sh
│ │ ├── 处理带值的选项.sh
│ │ ├── 处理简单选项.sh
│ │ ├── 快速清除文件或日志.sh
│ │ ├── 抓取所有数据.sh
│ │ ├── 永久重定向.sh
│ │ ├── 测试.txt
│ │ ├── 获取用户输入.sh
│ │ ├── 记录信息.sh
│ │ ├── 读取参数.sh
│ │ ├── 读取多个命令行参数.sh
│ │ ├── 读取程序名.sh
│ │ ├── 读取选择参数.sh
│ │ ├── 超时和输入计数.sh
│ │ └── 隐藏方式读取数据.sh
│ ├── 进阶脚本/
│ │ ├── 创建捕捉脚本.sh
│ │ ├── 开启debug模式.sh
│ │ ├── 查看uptime获取在线用户数.sh
│ │ ├── 生成报告脚本-基于创建捕捉脚本.sh
│ │ ├── 系统快照报告.sh
│ │ ├── 输出颜色.sh
│ │ └── 问题跟踪数据库/
│ │ ├── Update_Problem.sh
│ │ ├── 查找问题.sh
│ │ └── 记录问题.sh
│ └── 逻辑控制/
│ ├── bash-shell无法处理浮点数.sh
│ ├── break示例.sh
│ ├── case示例.sh
│ ├── continue示例.sh
│ ├── for循环示例.sh
│ ├── if-elif-else示例.sh
│ ├── output.txt
│ ├── select菜单示例.sh
│ ├── until示例.sh
│ ├── while循环示例.sh
│ ├── 从命令读取值.sh
│ ├── 使用双圆括号.sh
│ ├── 使用双方括号.sh
│ ├── 使用大于小于号.sh
│ ├── 使用嵌套循环并修改IFS.sh
│ ├── 使用管道或重定向.sh
│ ├── 使用通配符处理目录.sh
│ ├── 注意test大小写顺序和sort不同.sh
│ └── 读取里表中复杂的值.sh
├── docs/
│ ├── .remarkrc
│ ├── .textlint.terms.json
│ ├── .textlintrc.js
│ ├── .vuepress/
│ │ ├── config.js
│ │ └── enhanceApp.js
│ ├── README.md
│ ├── docker/
│ │ ├── README.md
│ │ ├── docker-cheat-sheet.md
│ │ ├── docker-compose.md
│ │ ├── docker-dockerfile.md
│ │ ├── docker-quickstart.md
│ │ ├── docker.xmind
│ │ ├── kubernetes.md
│ │ └── service/
│ │ ├── docker-install-mysql.md
│ │ └── docker-install-nginx.md
│ ├── linux/
│ │ ├── cli/
│ │ │ ├── README.md
│ │ │ ├── free.md
│ │ │ ├── grep.md
│ │ │ ├── iostat.md
│ │ │ ├── iotop.md
│ │ │ ├── linux-cli-dir.md
│ │ │ ├── linux-cli-file-compress.md
│ │ │ ├── linux-cli-file.md
│ │ │ ├── linux-cli-hardware.md
│ │ │ ├── linux-cli-help.md
│ │ │ ├── linux-cli-net.md
│ │ │ ├── linux-cli-software.md
│ │ │ ├── linux-cli-system.md
│ │ │ ├── linux-cli-user.md
│ │ │ ├── scp.md
│ │ │ ├── top.md
│ │ │ ├── vmstat.md
│ │ │ └── 命令行的艺术.md
│ │ ├── expect.md
│ │ ├── ops/
│ │ │ ├── README.md
│ │ │ ├── crontab.md
│ │ │ ├── firewalld.md
│ │ │ ├── iptables.md
│ │ │ ├── network-ops.md
│ │ │ ├── ntp.md
│ │ │ ├── samba.md
│ │ │ ├── systemd.md
│ │ │ ├── vim.md
│ │ │ └── zsh.md
│ │ └── soft/
│ │ ├── README.md
│ │ ├── apollo/
│ │ │ ├── README.md
│ │ │ └── apollo.xmind
│ │ ├── elastic/
│ │ │ ├── README.md
│ │ │ ├── elastic-beats.md
│ │ │ ├── elastic-kibana.md
│ │ │ ├── elastic-logstash.md
│ │ │ └── elastic-quickstart.md
│ │ ├── fastdfs.md
│ │ ├── gitlab-ops.md
│ │ ├── jdk-install.md
│ │ ├── jenkins-ops.md
│ │ ├── kafka-install.md
│ │ ├── maven-install.md
│ │ ├── mongodb-ops.md
│ │ ├── nacos-install.md
│ │ ├── nexus-ops.md
│ │ ├── nodejs-install.md
│ │ ├── rocketmq-install.md
│ │ ├── svn-ops.md
│ │ ├── tomcat-install.md
│ │ └── yapi-ops.md
│ ├── mac/
│ │ └── soft/
│ │ └── ruby-install.md
│ └── package.json
└── scripts/
└── deploy.sh
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# EditorConfig 用于在 IDE 中检查代码的基本 Code Style
# @see: https://editorconfig.org/
# 配置说明:
# 所有文件换行使用 Unix 风格(LF),*.bat 文件使用 Windows 风格(CRLF)
# java / sh 文件缩进 4 个空格,其他所有文件缩进 2 个空格
root = true
[*]
end_of_line = lf
indent_size = 2
indent_style = space
max_line_length = 120
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{bat, cmd}]
end_of_line = crlf
[*.{java, gradle, groovy, kt, sh}]
indent_size = 4
[*.md]
max_line_length = 0
trim_trailing_whitespace = false
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
# plan text
*.txt text
*.java text
*.scala text
*.groovy text
*.gradle text
*.xml text
*.xsd text
*.tld text
*.yaml text
*.yml text
*.wsdd text
*.wsdl text
*.jsp text
*.jspf text
*.js text
*.jsx text
*.json text
*.css text
*.less text
*.sql text
*.properties text
# unix style
*.sh text eol=lf
# win style
*.bat text eol=crlf
# don't handle
*.der -text
*.jks -text
*.pfx -text
*.map -text
*.patch -text
*.dat -text
*.data -text
*.db -text
# binary
*.jar binary
*.war binary
*.zip binary
*.tar binary
*.tar.gz binary
*.gz binary
*.apk binary
*.bin binary
*.exe binary
# images
*.png binary
*.jpg binary
*.ico binary
*.gif binary
# medias
*.mp3 binary
*.swf binary
# fonts
*.eot binary
*.svg binary
*.ttf binary
*.woff binary
# others
*.pdf binary
*.doc binary
*.docx binary
*.ppt binary
*.pptx binary
*.xls binary
*.xlsx binary
*.xmind binary
================================================
FILE: .gitignore
================================================
# ---------------------------------------------------------------------
# more gitignore templates see https://github.com/github/gitignore
# ---------------------------------------------------------------------
# ------------------------------- java -------------------------------
# compiled folders
classes
target
logs
.mtj.tmp/
# compiled files
*.class
# bluej files
*.ctxt
# package files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs
hs_err_pid*
# maven plugin temp files
.flattened-pom.xml
package-lock.json
pnpm-lock.yaml
# ------------------------------- javascript -------------------------------
# dependencies
node_modules
# temp folders
.temp
dist
_book
_jsdoc
# temp files
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
bundle*.js
book.pdf
# ------------------------------- intellij -------------------------------
.idea
*.iml
# ------------------------------- eclipse -------------------------------
.classpath
.project
================================================
FILE: .travis.yml
================================================
# 持续集成 CI
# @see https://docs.travis-ci.com/user/tutorial/
language: node_js
sudo: required
node_js: '16.13.0'
branches:
only:
- master
before_install:
- export TZ=Asia/Shanghai
script: bash ./scripts/deploy.sh
notifications:
email:
recipients:
- forbreak@163.com
on_success: change
on_failure: always
================================================
FILE: LICENSE
================================================
Attribution-ShareAlike 4.0 International
=======================================================================
Creative Commons Corporation ("Creative Commons") is not a law firm and
does not provide legal services or legal advice. Distribution of
Creative Commons public licenses does not create a lawyer-client or
other relationship. Creative Commons makes its licenses and related
information available on an "as-is" basis. Creative Commons gives no
warranties regarding its licenses, any material licensed under their
terms and conditions, or any related information. Creative Commons
disclaims all liability for damages resulting from their use to the
fullest extent possible.
Using Creative Commons Public Licenses
Creative Commons public licenses provide a standard set of terms and
conditions that creators and other rights holders may use to share
original works of authorship and other material subject to copyright
and certain other rights specified in the public license below. The
following considerations are for informational purposes only, are not
exhaustive, and do not form part of our licenses.
Considerations for licensors: Our public licenses are
intended for use by those authorized to give the public
permission to use material in ways otherwise restricted by
copyright and certain other rights. Our licenses are
irrevocable. Licensors should read and understand the terms
and conditions of the license they choose before applying it.
Licensors should also secure all rights necessary before
applying our licenses so that the public can reuse the
material as expected. Licensors should clearly mark any
material not subject to the license. This includes other CC-
licensed material, or material used under an exception or
limitation to copyright. More considerations for licensors:
wiki.creativecommons.org/Considerations_for_licensors
Considerations for the public: By using one of our public
licenses, a licensor grants the public permission to use the
licensed material under specified terms and conditions. If
the licensor's permission is not necessary for any reason--for
example, because of any applicable exception or limitation to
copyright--then that use is not regulated by the license. Our
licenses grant only permissions under copyright and certain
other rights that a licensor has authority to grant. Use of
the licensed material may still be restricted for other
reasons, including because others have copyright or other
rights in the material. A licensor may make special requests,
such as asking that all changes be marked or described.
Although not required by our licenses, you are encouraged to
respect those requests where reasonable. More_considerations
for the public:
wiki.creativecommons.org/Considerations_for_licensees
=======================================================================
Creative Commons Attribution-ShareAlike 4.0 International Public
License
By exercising the Licensed Rights (defined below), You accept and agree
to be bound by the terms and conditions of this Creative Commons
Attribution-ShareAlike 4.0 International Public License ("Public
License"). To the extent this Public License may be interpreted as a
contract, You are granted the Licensed Rights in consideration of Your
acceptance of these terms and conditions, and the Licensor grants You
such rights in consideration of benefits the Licensor receives from
making the Licensed Material available under these terms and
conditions.
Section 1 -- Definitions.
a. Adapted Material means material subject to Copyright and Similar
Rights that is derived from or based upon the Licensed Material
and in which the Licensed Material is translated, altered,
arranged, transformed, or otherwise modified in a manner requiring
permission under the Copyright and Similar Rights held by the
Licensor. For purposes of this Public License, where the Licensed
Material is a musical work, performance, or sound recording,
Adapted Material is always produced where the Licensed Material is
synched in timed relation with a moving image.
b. Adapter's License means the license You apply to Your Copyright
and Similar Rights in Your contributions to Adapted Material in
accordance with the terms and conditions of this Public License.
c. BY-SA Compatible License means a license listed at
creativecommons.org/compatiblelicenses, approved by Creative
Commons as essentially the equivalent of this Public License.
d. Copyright and Similar Rights means copyright and/or similar rights
closely related to copyright including, without limitation,
performance, broadcast, sound recording, and Sui Generis Database
Rights, without regard to how the rights are labeled or
categorized. For purposes of this Public License, the rights
specified in Section 2(b)(1)-(2) are not Copyright and Similar
Rights.
e. Effective Technological Measures means those measures that, in the
absence of proper authority, may not be circumvented under laws
fulfilling obligations under Article 11 of the WIPO Copyright
Treaty adopted on December 20, 1996, and/or similar international
agreements.
f. Exceptions and Limitations means fair use, fair dealing, and/or
any other exception or limitation to Copyright and Similar Rights
that applies to Your use of the Licensed Material.
g. License Elements means the license attributes listed in the name
of a Creative Commons Public License. The License Elements of this
Public License are Attribution and ShareAlike.
h. Licensed Material means the artistic or literary work, database,
or other material to which the Licensor applied this Public
License.
i. Licensed Rights means the rights granted to You subject to the
terms and conditions of this Public License, which are limited to
all Copyright and Similar Rights that apply to Your use of the
Licensed Material and that the Licensor has authority to license.
j. Licensor means the individual(s) or entity(ies) granting rights
under this Public License.
k. Share means to provide material to the public by any means or
process that requires permission under the Licensed Rights, such
as reproduction, public display, public performance, distribution,
dissemination, communication, or importation, and to make material
available to the public including in ways that members of the
public may access the material from a place and at a time
individually chosen by them.
l. Sui Generis Database Rights means rights other than copyright
resulting from Directive 96/9/EC of the European Parliament and of
the Council of 11 March 1996 on the legal protection of databases,
as amended and/or succeeded, as well as other essentially
equivalent rights anywhere in the world.
m. You means the individual or entity exercising the Licensed Rights
under this Public License. Your has a corresponding meaning.
Section 2 -- Scope.
a. License grant.
1. Subject to the terms and conditions of this Public License,
the Licensor hereby grants You a worldwide, royalty-free,
non-sublicensable, non-exclusive, irrevocable license to
exercise the Licensed Rights in the Licensed Material to:
a. reproduce and Share the Licensed Material, in whole or
in part; and
b. produce, reproduce, and Share Adapted Material.
2. Exceptions and Limitations. For the avoidance of doubt, where
Exceptions and Limitations apply to Your use, this Public
License does not apply, and You do not need to comply with
its terms and conditions.
3. Term. The term of this Public License is specified in Section
6(a).
4. Media and formats; technical modifications allowed. The
Licensor authorizes You to exercise the Licensed Rights in
all media and formats whether now known or hereafter created,
and to make technical modifications necessary to do so. The
Licensor waives and/or agrees not to assert any right or
authority to forbid You from making technical modifications
necessary to exercise the Licensed Rights, including
technical modifications necessary to circumvent Effective
Technological Measures. For purposes of this Public License,
simply making modifications authorized by this Section 2(a)
(4) never produces Adapted Material.
5. Downstream recipients.
a. Offer from the Licensor -- Licensed Material. Every
recipient of the Licensed Material automatically
receives an offer from the Licensor to exercise the
Licensed Rights under the terms and conditions of this
Public License.
b. Additional offer from the Licensor -- Adapted Material.
Every recipient of Adapted Material from You
automatically receives an offer from the Licensor to
exercise the Licensed Rights in the Adapted Material
under the conditions of the Adapter's License You apply.
c. No downstream restrictions. You may not offer or impose
any additional or different terms or conditions on, or
apply any Effective Technological Measures to, the
Licensed Material if doing so restricts exercise of the
Licensed Rights by any recipient of the Licensed
Material.
6. No endorsement. Nothing in this Public License constitutes or
may be construed as permission to assert or imply that You
are, or that Your use of the Licensed Material is, connected
with, or sponsored, endorsed, or granted official status by,
the Licensor or others designated to receive attribution as
provided in Section 3(a)(1)(A)(i).
b. Other rights.
1. Moral rights, such as the right of integrity, are not
licensed under this Public License, nor are publicity,
privacy, and/or other similar personality rights; however, to
the extent possible, the Licensor waives and/or agrees not to
assert any such rights held by the Licensor to the limited
extent necessary to allow You to exercise the Licensed
Rights, but not otherwise.
2. Patent and trademark rights are not licensed under this
Public License.
3. To the extent possible, the Licensor waives any right to
collect royalties from You for the exercise of the Licensed
Rights, whether directly or through a collecting society
under any voluntary or waivable statutory or compulsory
licensing scheme. In all other cases the Licensor expressly
reserves any right to collect such royalties.
Section 3 -- License Conditions.
Your exercise of the Licensed Rights is expressly made subject to the
following conditions.
a. Attribution.
1. If You Share the Licensed Material (including in modified
form), You must:
a. retain the following if it is supplied by the Licensor
with the Licensed Material:
i. identification of the creator(s) of the Licensed
Material and any others designated to receive
attribution, in any reasonable manner requested by
the Licensor (including by pseudonym if
designated);
ii. a copyright notice;
iii. a notice that refers to this Public License;
iv. a notice that refers to the disclaimer of
warranties;
v. a URI or hyperlink to the Licensed Material to the
extent reasonably practicable;
b. indicate if You modified the Licensed Material and
retain an indication of any previous modifications; and
c. indicate the Licensed Material is licensed under this
Public License, and include the text of, or the URI or
hyperlink to, this Public License.
2. You may satisfy the conditions in Section 3(a)(1) in any
reasonable manner based on the medium, means, and context in
which You Share the Licensed Material. For example, it may be
reasonable to satisfy the conditions by providing a URI or
hyperlink to a resource that includes the required
information.
3. If requested by the Licensor, You must remove any of the
information required by Section 3(a)(1)(A) to the extent
reasonably practicable.
b. ShareAlike.
In addition to the conditions in Section 3(a), if You Share
Adapted Material You produce, the following conditions also apply.
1. The Adapter's License You apply must be a Creative Commons
license with the same License Elements, this version or
later, or a BY-SA Compatible License.
2. You must include the text of, or the URI or hyperlink to, the
Adapter's License You apply. You may satisfy this condition
in any reasonable manner based on the medium, means, and
context in which You Share Adapted Material.
3. You may not offer or impose any additional or different terms
or conditions on, or apply any Effective Technological
Measures to, Adapted Material that restrict exercise of the
rights granted under the Adapter's License You apply.
Section 4 -- Sui Generis Database Rights.
Where the Licensed Rights include Sui Generis Database Rights that
apply to Your use of the Licensed Material:
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
to extract, reuse, reproduce, and Share all or a substantial
portion of the contents of the database;
b. if You include all or a substantial portion of the database
contents in a database in which You have Sui Generis Database
Rights, then the database in which You have Sui Generis Database
Rights (but not its individual contents) is Adapted Material,
including for purposes of Section 3(b); and
c. You must comply with the conditions in Section 3(a) if You Share
all or a substantial portion of the contents of the database.
For the avoidance of doubt, this Section 4 supplements and does not
replace Your obligations under this Public License where the Licensed
Rights include other Copyright and Similar Rights.
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
c. The disclaimer of warranties and limitation of liability provided
above shall be interpreted in a manner that, to the extent
possible, most closely approximates an absolute disclaimer and
waiver of all liability.
Section 6 -- Term and Termination.
a. This Public License applies for the term of the Copyright and
Similar Rights licensed here. However, if You fail to comply with
this Public License, then Your rights under this Public License
terminate automatically.
b. Where Your right to use the Licensed Material has terminated under
Section 6(a), it reinstates:
1. automatically as of the date the violation is cured, provided
it is cured within 30 days of Your discovery of the
violation; or
2. upon express reinstatement by the Licensor.
For the avoidance of doubt, this Section 6(b) does not affect any
right the Licensor may have to seek remedies for Your violations
of this Public License.
c. For the avoidance of doubt, the Licensor may also offer the
Licensed Material under separate terms or conditions or stop
distributing the Licensed Material at any time; however, doing so
will not terminate this Public License.
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
License.
Section 7 -- Other Terms and Conditions.
a. The Licensor shall not be bound by any additional or different
terms or conditions communicated by You unless expressly agreed.
b. Any arrangements, understandings, or agreements regarding the
Licensed Material not stated herein are separate from and
independent of the terms and conditions of this Public License.
Section 8 -- Interpretation.
a. For the avoidance of doubt, this Public License does not, and
shall not be interpreted to, reduce, limit, restrict, or impose
conditions on any use of the Licensed Material that could lawfully
be made without permission under this Public License.
b. To the extent possible, if any provision of this Public License is
deemed unenforceable, it shall be automatically reformed to the
minimum extent necessary to make it enforceable. If the provision
cannot be reformed, it shall be severed from this Public License
without affecting the enforceability of the remaining terms and
conditions.
c. No term or condition of this Public License will be waived and no
failure to comply consented to unless expressly agreed to by the
Licensor.
d. Nothing in this Public License constitutes or may be interpreted
as a limitation upon, or waiver of, any privileges and immunities
that apply to the Licensor or You, including from the legal
processes of any jurisdiction or authority.
=======================================================================
Creative Commons is not a party to its public
licenses. Notwithstanding, Creative Commons may elect to apply one of
its public licenses to material it publishes and in those instances
will be considered the “Licensor.” The text of the Creative Commons
public licenses is dedicated to the public domain under the CC0 Public
Domain Dedication. Except for the limited purpose of indicating that
material is shared under a Creative Commons public license or as
otherwise permitted by the Creative Commons policies published at
creativecommons.org/policies, Creative Commons does not authorize the
use of the trademark "Creative Commons" or any other trademark or logo
of Creative Commons without its prior written consent including,
without limitation, in connection with any unauthorized modifications
to any of its public licenses or any other arrangements,
understandings, or agreements concerning use of licensed material. For
the avoidance of doubt, this paragraph does not form part of the
public licenses.
Creative Commons may be contacted at creativecommons.org.
================================================
FILE: README.md
================================================
linux-tutorial
> 📚 **linux-tutorial** 是一个 Linux 教程。
>
> - 🔁 项目同步维护:[Github](https://github.com/dunwu/linux-tutorial/) | [Gitee](https://gitee.com/turnon/linux-tutorial/)
> - 📖 电子书阅读:[Github Pages](https://dunwu.github.io/linux-tutorial/) | [Gitee Pages](http://turnon.gitee.io/linux-tutorial/)
## 📖 内容
### Linux 命令
> 学习 Linux 的第一步:当然是从 [Linux 命令](docs/linux/cli/README.md) 入手了。
- [查看 Linux 命令帮助信息](docs/linux/cli/linux-cli-help.md) - 关键词:`help`, `whatis`, `info`, `which`, `whereis`, `man`
- [Linux 文件目录管理](docs/linux/cli/linux-cli-dir.md) - 关键词:`cd`, `ls`, `pwd`, `mkdir`, `rmdir`, `tree`, `touch`, `ln`, `rename`, `stat`, `file`, `chmod`, `chown`, `locate`, `find`, `cp`, `mv`, `rm`
- [Linux 文件内容查看命令](docs/linux/cli/linux-cli-file.md) - 关键词:`cat`, `head`, `tail`, `more`, `less`, `sed`, `vi`, `grep`
- [Linux 文件压缩和解压](docs/linux/cli/linux-cli-file-compress.md) - 关键词:`tar`, `gzip`, `zip`, `unzip`
- [Linux 用户管理](docs/linux/cli/linux-cli-user.md) - 关键词:`groupadd`, `groupdel`, `groupmod`, `useradd`, `userdel`, `usermod`, `passwd`, `su`, `sudo`
- [Linux 系统管理](docs/linux/cli/linux-cli-system.md) - 关键词:`reboot`, `exit`, `shutdown`, `date`, `mount`, `umount`, `ps`, `kill`, `systemctl`, `service`, `crontab`
- [Linux 网络管理](docs/linux/cli/linux-cli-net.md) - 关键词:关键词:`curl`, `wget`, `telnet`, `ip`, `hostname`, `ifconfig`, `route`, `ssh`, `ssh-keygen`, `firewalld`, `iptables`, `host`, `nslookup`, `nc`/`netcat`, `ping`, `traceroute`, `netstat`
- [Linux 硬件管理](docs/linux/cli/linux-cli-hardware.md) - 关键词:`df`, `du`, `top`, `free`, `iotop`
- [Linux 软件管理](docs/linux/cli/linux-cli-software.md) - 关键词:`rpm`, `yum`, `apt-get`
### Linux 运维
> Linux 系统的常见运维工作。
- [网络运维](docs/linux/ops/network-ops.md)
- [Samba](docs/linux/ops/samba.md)
- [NTP](docs/linux/ops/ntp.md)
- [Firewalld](docs/linux/ops/firewalld.md)
- [Crontab](docs/linux/ops/crontab.md)
- [Systemd](docs/linux/ops/systemd.md)
- [Vim](docs/linux/ops/vim.md)
- [Iptables](docs/linux/ops/iptables.md)
- [oh-my-zsh](docs/linux/ops/zsh.md)
### 软件运维
> 部署在 Linux 系统上的软件运维。
>
> 配套安装脚本:⌨ [软件运维配置脚本集合](https://github.com/dunwu/linux-tutorial/tree/master/codes/linux/soft)
- 开发环境
- [JDK 安装](docs/linux/soft/jdk-install.md)
- [Maven 安装](docs/linux/soft/maven-install.md)
- [Nodejs 安装](docs/linux/soft/nodejs-install.md)
- 开发工具
- [Nexus 运维](docs/linux/soft/nexus-ops.md)
- [Gitlab 运维](docs/linux/soft/gitlab-ops.md)
- [Jenkins 运维](docs/linux/soft/jenkins-ops.md)
- [Svn 运维](docs/linux/soft/svn-ops.md)
- [YApi 运维](docs/linux/soft/yapi-ops.md)
- 中间件服务
- [Elastic 运维](docs/linux/soft/elastic)
- [Kafka 运维](docs/linux/soft/kafka-install.md)
- [RocketMQ 运维](docs/linux/soft/rocketmq-install.md)
- [Zookeeper 运维](https://github.com/dunwu/javatech/blob/master/docs/technology/monitor/zookeeper-ops.md)
- [Nacos 运维](docs/linux/soft/nacos-install.md)
- 服务器
- [Nginx 教程](https://github.com/dunwu/nginx-tutorial) 📚
- [Tomcat 运维](docs/linux/soft/tomcat-install.md)
- [数据库](https://github.com/dunwu/db-tutorial) 📚
- [Mysql 运维](https://github.com/dunwu/db-tutorial/blob/master/docs/sql/mysql/mysql-ops.md)
- [Redis 运维](https://github.com/dunwu/db-tutorial/blob/master/docs/nosql/redis/redis-ops.md)
### Docker
- [Docker 快速入门](docs/docker/docker-quickstart.md)
- [Dockerfile 最佳实践](docs/docker/docker-dockerfile.md)
- [Docker Cheat Sheet](docs/docker/docker-cheat-sheet.md)
- [Kubernetes 应用指南](docs/docker/kubernetes.md)
### 其他
- [一篇文章让你彻底掌握 Python](https://dunwu.github.io/blog/pages/ef501b/)
- [一篇文章让你彻底掌握 Shell](https://dunwu.github.io/blog/pages/ea6ae1/)
- [如何优雅的玩转 Git](https://dunwu.github.io/blog/pages/2fc8b1/)
## ⌨ 脚本
### Shell 脚本大全
**Shell 脚本大全** 精心收集、整理了 Linux 环境下的常见 Shell 脚本操作片段。
源码:[**Shell 脚本大全**](https://github.com/dunwu/linux-tutorial/tree/master/codes/shell)
### CentOS 运维脚本集合
本人作为一名 Java 后端,苦于经常在 CentOS 环境上开荒虚拟机。为提高效率,写了一套 Shell 脚本,提供如下功能:安装常用 lib 库、命令工具、设置 DNS、NTP、配置国内 yum 源、一键安装常用软件等。
源码:[**CentOS 常规操作运维脚本集合**](https://github.com/dunwu/linux-tutorial/tree/master/codes/linux)
## 📚 资料
- **Linux 命令**
- [命令行的艺术](https://github.com/jlevy/the-art-of-command-line/blob/master/README-zh.md)
- [Linux 命令大全](https://man.linuxde.net/)
- [linux-command](https://github.com/jaywcjlove/linux-command)
- **社区网站**
- [Linux 中国](https://linux.cn/) - 各种资讯、文章、技术
- [LabEx 中国](https://labex.io/) - 免费提供了 Linux 在线环境,不用在自己机子上装系统也可以学习 Linux,超方便实用。
- [鸟哥的 linux 私房菜](http://linux.vbird.org/) - 非常适合 Linux 入门初学者看的教程。
- [Linux 公社](http://www.linuxidc.com/) - Linux 相关的新闻、教程、主题、壁纸都有。
- [Linux Today](http://www.linuxde.net) - Linux 新闻资讯发布,Linux 职业技术学习!。
- **知识相关**
- [Linux 思维导图整理](http://www.jianshu.com/p/59f759207862)
- [Linux 初学者进阶学习资源整理](http://www.jianshu.com/p/fe2a790b41eb)
- [Linux 快速入门(动手实验)](https://labex.io/zh/courses/quick-start-with-linux)
- [【译】Linux 概念架构的理解](http://www.jianshu.com/p/c5ae8f061cfe) [En](http://oss.org.cn/ossdocs/linux/kernel/a1/index.html)
- [Linux 守护进程的启动方法](http://www.ruanyifeng.com/blog/2016/02/linux-daemon.html)
- [Linux 知识点小结](https://blog.huachao.me/2016/1/Linux%E7%9F%A5%E8%AF%86%E7%82%B9%E5%B0%8F%E7%BB%93/)
- [10 大白帽黑客专用的 Linux 操作系统](https://linux.cn/article-6971-1.html)
- **软件工具**
- [超赞的 Linux 软件](https://www.gitbook.com/book/alim0x/awesome-linux-software-zh_cn/details) Github 仓库[Zh](https://github.com/alim0x/Awesome-Linux-Software-zh_CN) [En](https://github.com/VoLuong/Awesome-Linux-Software)
- [程序员喜欢的 9 款最佳的 Linux 文件比较工具](http://os.51cto.com/art/201607/513796.htm)
- [提高 Linux 开发效率的 5 个工具](http://www.codeceo.com/article/5-linux-productivity-tools.html)
- [你要了解的 11 款面向 Linux 系统的一流备份实用工具](http://os.51cto.com/art/201603/508027.htm)
- [16 个很有用的在线工具](http://www.simlinux.com/archives/264.html)
- Adobe 软件的最佳替代品 [原文在这里](https://linux.cn/article-8928-1.html)
- [Evince (Adobe Acrobat Reader)](https://wiki.gnome.org/Apps/Evince) 一个“支持多种文档格式的文档查看器”,可以查看 PDF,还支持各种漫画书格式
- [Pixlr (Adobe Photoshop)](https://pixlr.com/) 一个强大的图像编辑工具
- [Inkscape (Adobe Illustrator)](https://inkscape.org/zh/) 一个专业的矢量图形编辑器
- [Pinegrow Web Editor (Adobe Dreamweaver)](https://pinegrow.com/) 一个可视化编辑制作 HTML 网站
- [Scribus (Adobe InDesign)](https://www.scribus.net/) 一个开源电子杂志制作软件
- [Webflow (Adobe Muse)](https://webflow.com/) 一款可以帮助用户不用编码就可以快速创建网站的谷歌浏览器插件。
- [Tupi (Adobe Animate)](http://www.maefloresta.com/portal/) 一款可以创建 HTML5 动画的工具。
- [Black Magic Fusion (Adobe After Effects)](https://www.blackmagicdesign.com) 一款先进的合成软件,广泛应用于视觉特效、广电影视设计以及 3D 动画设计等领域。
- **中国开源镜像**
- [阿里云开源镜像站](http://mirrors.aliyun.com/)
- [网易开源镜像站](http://mirrors.163.com/)
- [搜狐开源镜像站](http://mirrors.sohu.com/)
- [北京交通大学](http://mirror.bjtu.edu.cn/)
- [兰州大学](http://mirror.lzu.edu.cn/)
- [厦门大学](http://mirrors.xmu.edu.cn/)
- [上海交通大学](http://ftp.sjtu.edu.cn/)
- [清华大学](http://mirrors.tuna.tsinghua.edu.cn/)
- [中国科学技术大学](http://mirrors.ustc.edu.cn/)
- [东北大学](http://mirror.neu.edu.cn/)
- [浙江大学](http://mirrors.zju.edu.cn/)
- [东软信息学院](http://mirrors.neusoft.edu.cn/)
- [校园网联合镜像站](https://mirrors.cernet.edu.cn)
## 🚪 传送门
◾ 💧 [钝悟的 IT 知识图谱](https://dunwu.github.io/waterdrop/) ◾ 🎯 [钝悟的博客](https://dunwu.github.io/blog/) ◾
================================================
FILE: codes/docker/docker-compose-demo/Dockerfile
================================================
FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]
================================================
FILE: codes/docker/docker-compose-demo/app.py
================================================
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route('/')
def hello():
count = redis.incr('hits')
return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True)
================================================
FILE: codes/docker/docker-compose-demo/docker-compose.yml
================================================
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
================================================
FILE: codes/docker/docker-compose-demo/run.sh
================================================
#!/usr/bin/env bash
set -x
docker-compose up
================================================
FILE: codes/expect/远程登录.sh
================================================
#!/usr/bin/expect -f
# -----------------------------------------------------------------------------------------------------
# expect 交互式脚本示例 - 自动远程登录,并在其他机器上创建一个文件
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# 设置变量
set USER "root"
set PWD "XXXXXX"
set HOST "127.0.0.2"
# 设置超时时间
set timeout 400
# 远程登录
spawn ssh -p 22 $USER@$HOST
expect {
"yes/no" { send "yes\r"; exp_continue }
"password:" { send "$PWD\r" }
}
# 在其他机器上创建
expect "#"
send "touch /home/demo.txt\r"
expect "#"
send "echo hello world >> /home/demo.txt\r"
expect "#"
# 退出
send "exit\r"
================================================
FILE: codes/linux/README.md
================================================
# CentOS 常规操作运维脚本集合
> **本项目脚本代码用于在 [CentOS](https://www.centos.org/) 机器上安装常用命令工具或开发软件。**
使用说明:
(1)下载脚本
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/download.sh | bash
```
(2)执行脚本
```shell
cd /tmp/dunwu-ops
./dunwu-ops.sh
```
(3)清除脚本
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/clear.sh | bash
```
本项目总结、收集 Linux 环境下运维常用到的脚本工具,大致分为三类:
- [系统运维脚本](sys)
- [服务、应用运维脚本](soft)
- [构建、编译项目脚本(目前支持 Java、Javascript 应用)](build)
================================================
FILE: codes/linux/build/Java应用运行脚本模板/lifecycle.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# 应用终止脚本
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ libs
SCRIPTS_DIR=$(cd `dirname $0`; pwd)
if [[ ! -x ${SCRIPTS_DIR}/utils.sh ]]; then
logError "${SCRIPTS_DIR}/utils.sh not exists!"
exit 1
fi
source ${SCRIPTS_DIR}/utils.sh
# ------------------------------------------------------------------------------ functions
stopServer() {
if [[ ! $1 ]]; then
logError "please input java app name"
return ${ENV_FAILED}
fi
local appName=$1
local pid=`jps | grep ${appName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
kill -9 ${pid}
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "stop ${appName} succeed"
return ${ENV_SUCCEED}
else
logError "stop ${appName} failed"
return ${ENV_FAILED}
fi
else
printWarn "${appName} is not running"
return ${ENV_SUCCEED}
fi
}
startServer() {
# >>>> validate params
if [[ ! $1 ]] || [[ ! $2 ]] || [[ ! $3 ]] || [[ ! $4 ]]; then
logError "you must input following params in order:"
echo -e "${ENV_COLOR_B_RED}"
echo " (1)jarPath"
echo " (2)libPath"
echo " (3)confPath"
echo " (4)logPath"
echo " (5)appName [optional]"
echo " (6)port [optional]"
echo " (7)profile [optional]"
echo " (8)debug [optional]"
echo -e "\nEg. startServer /usr/lib/dunwu/app.jar /usr/lib/dunwu/lib /usr/lib/dunwu/conf /var/log/dunwu dunwu 8888 prod off"
echo -e "${ENV_COLOR_RESET}"
return ${ENV_FAILED}
fi
local jarPath=$1
local libPath=$2
local confPath=$3
local logPath=$4
local appName=${5:-myapp}
local port=${6:-8888}
local profile=${7:-prod}
local debug=${8:-off}
# >>>> 1. check java app is started or not
# >>>> 1.1. exit script if the app is started
local pid=`jps | grep ${appName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
printInfo "${appName} is started, PID: ${pid}"
return ${ENV_SUCCEED}
fi
# >>>> 2. package options
# GC OPTS
local javaOptions="-server -Xms1g -Xmx2g -Xss256k"
javaOptions="${javaOptions} -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=4"
# GC LOG OPTS
javaOptions="${javaOptions} -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
javaOptions="${javaOptions} -verbose:gc -Xloggc:${logPath}/${appName}.gc.log"
javaOptions="${javaOptions} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
# Heap Dump OPTS
javaOptions="${javaOptions} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError"
javaOptions="${javaOptions} -XX:HeapDumpPath=${logPath}/${appName}.heapdump.hprof"
# APP OPTS
javaOptions="${javaOptions} -Dsun.net.inetaddr.ttl=60 -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8"
if [[ ${profile} ]]; then
javaOptions="${javaOptions} -Dspring.profiles.active=${profile}"
fi
# DEBUG OPTS
if [[ "${debug}" == "on" ]]; then
# JMX OPTS
local ip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/')
local jmxPort=$(expr 10000 + ${port})
javaOptions="${javaOptions} -Dcom.sun.management.jmxremote=true"
javaOptions="${javaOptions} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
javaOptions="${javaOptions} -Djava.rmi.server.hostname=${ip} -Dcom.sun.management.jmxremote.port=${jmxPort}"
# Remote Debug
local debugPort=$(expr 20000 + ${port})
javaOptions="${javaOptions} -Xdebug -Xnoagent -Djava.compiler=NONE"
javaOptions="${javaOptions} -Xrunjdwp:transport=dt_socket,address=${debugPort},server=y,suspend=n"
fi
# CLASSPATH
local appOptions="-classpath ${libPath}/* -Dlogging.config=file:${confPath}/logback.${profile}.xml"
local springConfigFiles="classpath:/,classpath:/config/"
local springConfigFiles="${springConfigFiles},file:${confPath}/,file:${confPath}/application.properties"
appOptions="${appOptions} --spring.config.location=${springConfigFiles}"
appOptions="${appOptions} --spring.cache.ehcache.config=file:${confPath}/config/ehcache.xml"
if [[ ${port} ]]; then
appOptions="${appOptions} --server.port=${port}"
fi
# >>>> 3. create log dir and console log file
local consoleLogPath=${logPath}/${appName}.console.log
mkdir -p ${logPath}
if [[ ! -x ${consoleLogPath} ]]; then
touch ${consoleLogPath}
fi
# >>>> 4. start java app
# print bootstrap info
printInfo "starting ${appName}"
echo -e "${ENV_COLOR_B_GREEN}"
echo -e "${ENV_COLOR_B_CYAN}\nBOOT PARAMS:${ENV_COLOR_B_GREEN}\n\n"
echo "appName=${appName}"
echo "jarPath=${jarPath}"
echo "libPath=${libPath}"
echo "confPath=${confPath}"
echo "logPath=${logPath}"
echo "port=${port}"
echo "profile=${profile}"
echo "debug=${debug}"
echo -e "${ENV_COLOR_B_CYAN}\nEXEC CLI:${ENV_COLOR_B_GREEN}\n\n"
echo "nohup java ${javaOptions} -jar ${jarPath} ${appOptions} >> ${consoleLogPath} 2>&1 &"
echo -e "${ENV_COLOR_RESET}"
# exec boot cli
nohup java ${javaOptions} -jar ${jarPath} ${appOptions} >> ${consoleLogPath} 2>&1 &
# >>>> 5. check java app is started or not
local pid=`jps | grep ${appName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
printInfo "start ${appName} succeed, PID: ${pid}"
return ${ENV_SUCCEED}
else
logError "start ${appName} failed"
return ${ENV_FAILED}
fi
}
================================================
FILE: codes/linux/build/Java应用运行脚本模板/start.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# myapp 启动脚本,用于【虚拟机环境】
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ libs
SCRIPTS_DIR=$(dirname ${BASH_SOURCE[0]})
if [[ ! -x ${SCRIPTS_DIR}/lifecycle.sh ]]; then
logError "${SCRIPTS_DIR}/lifecycle.sh not exists!"
exit 1
fi
source ${SCRIPTS_DIR}/lifecycle.sh
# ------------------------------------------------------------------------------ main
APP_DIR=$(cd `dirname $0`/..; pwd)
export LANG="zh_CN.UTF-8"
APP=myapp
JAR_PATH=${APP_DIR}/myapp.jar
LIB_PATH=${APP_DIR}/lib
CONF_PATH=${APP_DIR}/config
LOG_DIR=/var/log/dunwu
PORT=8888
PROFILE=prod
DEBUG=off
declare -a serial
serial=(on off)
echo -n "是否启动 debug 模式(可选值:on|off):"
read DEBUG
if ! echo ${serial[@]} | grep -q ${DEBUG}; then
echo "是否启动 debug 模式(可选值:on|off)"
exit 1
fi
startServer ${JAR_PATH} ${LIB_PATH} ${CONF_PATH} ${LOG_DIR} ${APP} ${PORT} ${PROFILE} ${DEBUG}
================================================
FILE: codes/linux/build/Java应用运行脚本模板/stop.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# 应用启动脚本
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ libs
SCRIPTS_DIR=$(dirname ${BASH_SOURCE[0]})
if [[ ! -x ${SCRIPTS_DIR}/lifecycle.sh ]]; then
logError "${SCRIPTS_DIR}/lifecycle.sh not exists!"
exit 1
fi
source ${SCRIPTS_DIR}/lifecycle.sh
# ------------------------------------------------------------------------------ main
export LANG="zh_CN.UTF-8"
stopServer myapp
================================================
FILE: codes/linux/build/Java应用运行脚本模板/utils.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Shell Utils
# 使用此脚本,应该先 export ENV_LOG_PATH,指定日志路径;否则将使用默认日志路径 /var/log/shell.log
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env params
# 颜色状态
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# 常用状态值
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE ENV_FAILED"
return ${ENV_FAILED}
fi
}
================================================
FILE: codes/linux/build/README.md
================================================
# 构建、编译项目脚本
> 目前支持 Java、Javascript 应用
================================================
FILE: codes/linux/build/helper.sh
================================================
#!/usr/bin/env bash
# 打印UI页头信息
function printHeadInfo() {
cat << EOF
***********************************************************************************
* 欢迎使用项目引导式发布脚本。
* 输入任意键进入脚本操作。
***********************************************************************************
EOF
}
# 打印UI页尾信息
function printFootInfo() {
cat << EOF
***********************************************************************************
* 安装过程结束。
* 输入任意键进入脚本操作。
* 如果不想安装其他应用,输入 exit 回车或输入 退出。
***********************************************************************************
EOF
}
# 检查文件是否存在,不存在则退出脚本
function checkFileExist() {
if [ ! -f "$1" ]
then
echo "关键文件 $1 找不到,脚本执行结束"
exit 1
fi
}
# 检查文件夹是否存在,不存在则创建
function createFolderIfNotExist() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# 记录发布的版本信息
# 第一个参数为日志所在路径
# 第二个参数为应用名称
# 第三个参数为代码分支
# 第四个参数为运行环境
function saveVersionInfo() {
if [ "$1" == "" ] || [ "$2" == "" ] || [ "$3" == "" ] || [ "$4" == "" ]; then
echo "缺少参数,退出"
exit 1
fi
VERSION_LOG_FILE=$1/$2-version.log
rm -rf ${VERSION_LOG_FILE}
touch ${VERSION_LOG_FILE}
chmod 777 ${VERSION_LOG_FILE}
echo -e "\n=================== $2 ===================" >> ${VERSION_LOG_FILE}
echo "Branch is: $3" >> ${VERSION_LOG_FILE}
echo "Profile is: $4" >> ${VERSION_LOG_FILE}
echo "CommitID is : $(git log --pretty=oneline -1)" >> ${VERSION_LOG_FILE}
}
================================================
FILE: codes/linux/build/java-app-boot.sh
================================================
#!/usr/bin/env bash
#################################################################################
# JAVA 应用通用启动脚本
# @author: Zhang Peng
#################################################################################
# 检查脚本参数,如必要参数未传入,退出脚本。
function checkInput() {
if [ "${app}" == "" ] || [ "${oper}" == "" ] || [ "${javaArgs}" == "" ] || [ "${classpathArgs}" == "" ] || [ "${bootstrapClass}" == "" ]; then
echo "请输入脚本参数:app oper javaArgs classpathArgs bootstrapClass"
echo " app: 应用名。"
echo " oper: 运行环境(必填)。可选值:start|stop|restart"
echo " javaArgs: JVM 参数(必填)。"
echo " classpathArgs: classpath参数(必填)。"
echo " bootstrapClass: 启动类(必填)。"
exit 0
fi
}
# 检查文件夹是否存在,不存在则创建
function createFolderIfNotExist() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# 检查服务是否已经启动
pids=""
function checkStarted() {
pids=`ps -ef | grep java | grep ${app} | awk '{print $2}'`
if [ -n "${pids}" ]; then
return 0
else
return 1
fi
}
function main() {
case "${oper}" in
start)
echo -n "starting server: "
# 检查服务是否已经启动
if checkStarted; then
echo "ERROR: server already started!"
echo "PID: ${pids}"
exit 1
fi
args="${javaArgs} -classpath ${classpathArgs} ${bootstrapClass}"
echo -e "statup params:\n ${args}"
#启动服务
touch ${LOG_DIR}/${app}-startup.log
nohup java ${args} > ${LOG_DIR}/${app}-startup.log 2>&1 &
# echo -e "执行参数:\n${args}"
echo -e "\nthe server is started..."
;;
stop)
echo -n "stopping server: "
#dubbo提供优雅停机, 不能使用kill -9
if checkStarted; then
kill ${pids}
echo -e "\nthe server is stopped..."
else
echo -e "\nno server to be stopped..."
fi
;;
restart)
$0 ${app} stop "${javaArgs}" "${classpathArgs}" "${bootstrapClass}"
sleep 5
$0 ${app} start "${javaArgs}" "${classpathArgs}" "${bootstrapClass}"
;;
*)
echo "Invalid oper: ${oper}."
exit 1
esac
exit 0
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
# 获取输入参数
app=`echo $1`
oper=`echo $2`
javaArgs=`echo $3`
classpathArgs=`echo $4`
bootstrapClass=`echo $5`
vars=$*
checkInput
# 设置全局常量
LOG_DIR=/home/zp/log
createFolderIfNotExist ${LOG_DIR}
# 执行 main 方法
main
================================================
FILE: codes/linux/build/java-app-release.sh
================================================
#!/usr/bin/env bash
#################################################################################
# JAVA 应用发布脚本
# @author: Zhang Peng
#################################################################################
# 检查脚本参数,如必要参数未传入,退出脚本。
checkInput() {
if [ "${branch}" == "" ] || [ "${profile}" == "" ]; then
echo "请输入脚本参数:branch profile"
echo " branch: git分支(必填)。如 feature/1.1.16, master"
echo " profile: 运行环境(必填)。可选值:development | test"
echo "例:./java-app-release.sh feature/1.1.16 test"
exit 0
fi
}
# 检查文件是否存在,不存在则退出脚本
checkFileExist() {
if [ ! -f "$1" ]
then
echo "关键文件 $1 找不到,脚本执行结束"
exit 0
fi
}
# 检查文件夹是否存在,不存在则创建
createFolderIfNotExist() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# 记录发布的版本信息
saveVersionInfo() {
rm -rf ${VERSION_LOG_FILE}
touch ${VERSION_LOG_FILE}
chmod 777 ${VERSION_LOG_FILE}
echo -e "\n=================== Version Info ===================" >> ${VERSION_LOG_FILE}
echo "Branch is: ${branch}" >> ${VERSION_LOG_FILE}
echo "Profile is: ${profile}" >> ${VERSION_LOG_FILE}
echo "CommitID is : $(git log --pretty=oneline -1)" >> ${VERSION_LOG_FILE}
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
# 设置全局常量
LOG_DIR=/home/zp/log/
SCRIPT_DIR=$(cd "$(dirname "$0")";
pwd)
SOURCE_DIR=/home/zp/source/
APP_NAME=XXX
RESOURCES_DIR=/home/zp/source/${APP_NAME}/src/main/resources
UPDATE_CODE_SCRIPT_FILE=${SCRIPT_DIR}/update-code.sh
MAVEN_LOG_FILE=${LOG_DIR}/${APP_NAME}-maven.log
VERSION_LOG_FILE=${LOG_DIR/${APP_NAME}-version.log
# 0. 获取传入参数并检查
branch=`echo $1`
profile=`echo $2`
checkInput
checkFileExist ${UPDATE_CODE_SCRIPT_FILE}
createFolderIfNotExist ${LOG_DIR}
createFolderIfNotExist ${SOURCE_DIR}
echo ">>>>>>>>>>>>>> 1. 停止应用"
${SCRIPT_DIR}/java-app-run.sh ${profile} stop
echo ">>>>>>>>>>>>>> 2. 更新代码"
${UPDATE_CODE_SCRIPT_FILE} ${APP_NAME} ${branch} ${SOURCE_DIR}
execode=$?
if [ "${execode}" == "0" ]; then
echo "更新代码成功"
else
echo "更新代码失败"
exit 1
fi
echo ">>>>>>>>>>>>>> 3. 替换配置"
# 有则加,无则过
echo ">>>>>>>>>>>>>> 4. 构建编译"
cd ${SOURCE_DIR}/ck-lion
mvn clean package -e -Dmaven.test.skip=true | tee ${MAVEN_LOG_FILE}
eexecode=$?
if [ "${execode}" == "0" ]; then
echo "构建编译成功"
echo "编译详情见:${MAVEN_LOG_FILE}"
else
echo "构建编译失败"
echo "编译详情见:${MAVEN_LOG_FILE}"
exit 1
fi
echo ">>>>>>>>>>>>>> 5. 启动应用"
# 手动释放内存
echo 3 > /proc/sys/vm/drop_caches
${SCRIPT_DIR}/java-app-run.sh ${profile} start
execode=$?
if [ "${execode}" == "0" ]; then
echo "启动应用成功"
else
echo "启动应用失败"
exit 1
fi
echo ">>>>>>>>>>>>>> 6. 记录发布的版本信息"
saveVersionInfo
echo ">>>>>>>>>>>>>> 发布应用结束"
================================================
FILE: codes/linux/build/java-app-run.sh
================================================
#!/usr/bin/env bash
#################################################################################
# JAVA 应用运行脚本
# @author: Zhang Peng
#################################################################################
# 检查脚本参数,如必要参数未传入,退出脚本。
function checkInput() {
if [ "${profile}" == "" ] || [ "${oper}" == "" ]; then
echo "请输入脚本参数:profile oper [debug]"
echo " profile: 运行环境(必填)。可选值:development|test"
echo " oper: 运行环境(必填)。可选值:start|stop|restart"
echo " debug: debug启动开关。默认不填为不启动。"
exit 0
fi
}
#检查文件是否存在,不存在则退出脚本
function checkFileExist() {
if [ ! -f "$1" ]
then
echo "关键文件 $1 找不到,脚本执行结束"
exit 0
fi
}
# 封装启动参数,调用启动脚本
function main() {
APP_NAME=ck-lion
# JVM 参数
JAVA_OPTS=" -Djava.awt.headless=true -Dfile.encoding=UTF8 -Djava.net.preferIPv4Stack=true -Ddubbo.shutdown.hook=true -Dspring.profiles.active=${profile} -Djava.security.egd=file:/dev/./urandom -Xms1024m -Xmx1024m -Xss2m "
JAVA_DEBUG_OPTS=""
if [ "$2" == "debug" ]; then
JAVA_DEBUG_OPTS=" -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=2236,server=y,suspend=n "
shift
fi
javaArgs=" ${JAVA_OPTS} ${JAVA_DEBUG_OPTS} "
# classpath 参数
classpathArgs="${SERVER_ROOT}/WEB-INF/classes:${SERVER_ROOT}/WEB-INF/lib/*"
# 启动类
bootstrapClass="com.alibaba.dubbo.container.Main"
${SCRIPT_DIR}/java-app-boot.sh ${APP_NAME} ${oper} "${javaArgs}" "${classpathArgs}" "${bootstrapClass}"
execode=$?
if [ "${execode}" == "0" ]; then
echo "执行操作成功"
else
echo "执行操作失败"
exit 1
fi
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
# 设置全局常量
SCRIPT_DIR=$(cd "$(dirname "$0")";
pwd)
SOURCE_DIR=/home/zp/source/
APP_NAME=XXX
SERVER_ROOT=/home/zp/source/${APP_NAME}/target/
# 0. 获取传入参数并检查
profile=$1
oper=$2
debug=$3
checkInput
# 1. 执行操作
main
================================================
FILE: codes/linux/build/js-app-release.sh
================================================
#################################################################################
# 前端应用发布脚本
# 环境要求:Nvm、Node.js
#################################################################################
# 检查脚本参数,如必要参数未传入,退出脚本。
function checkInput() {
if [ "${branch}" == "" ]; then
echo "请输入脚本参数:branch"
echo " branch: git分支。如 feature/1.1.16, master"
exit 1
fi
}
# 脚本主方法
function main() {
echo ">>>>>>>>>>>>>> 1. 更新代码"
${SCRIPT_DIR}/update-code.sh ${APP} ${branch} ${SOURCE_DIR}
execode=$?
if [ "${execode}" == "0" ]; then
echo "更新代码成功"
else
echo "更新代码失败"
exit 1
fi
echo ">>>>>>>>>>>>>> 2. 替换配置"
# 有的应用此处可能需要替换配置
echo ">>>>>>>>>>>>>> 3. 构建编译"
cd ${SOURCE_DIR}/${APP}
source "${HOME}/.nvm/nvm.sh"
nvm use 8.9
npm install
if [ "${profile}" == "develop" ] || [ "${profile}" == "test" ]; then
npm start
elif [ "${profile}" == "preview" ] || [ "${profile}" == "product" ]; then
npm run build
fi
execode=$?
if [ "${execode}" == "0" ]; then
echo "构建编译成功"
else
echo "构建编译失败"
exit 1
fi
echo ">>>>>>>>>>>>>> 4. 记录发布的版本信息"
saveVersionInfo ${LOG_DIR} ${APP} ${branch} ${profile}
echo ">>>>>>>>>>>>>> 发布应用结束"
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
# 设置全局常量
APP=blog
LOG_DIR=/home/zp/log
SOURCE_DIR=/home/zp/source
SCRIPT_DIR=$(cd "$(dirname "$0")";
pwd)
# 装载函数库
. ${SCRIPT_DIR}/helper.sh
# 获取传入参数并检查
branch=`echo $1`
profile=`echo $2`
checkInput
checkFileExist ${SCRIPT_DIR}/update-code.sh
createFolderIfNotExist ${SOURCE_DIR}
# 运行主方法
main
================================================
FILE: codes/linux/build/main.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 项目发布脚本模板
# @author: Zhang Peng
###################################################################################
# 选择应用
function chooseAppName() {
cat << EOF
请选择应用名(数字或关键字均可)。
可选值如下:
[0] all (所有应用)
[1] js-app
[2] APP2
EOF
while read app
do
case ${app} in
0)
app=all
break ;;
1)
app=js-app
break ;;
2)
app=APP2
break ;;
all | js-app | APP2)
break ;;
*) echo "无法识别 ${app}" ;;
esac
done
}
# 选择操作
function chooseOper() {
cat << EOF
请选择想要执行的操作(数字或关键字均可)。
可选值如下:
[1] start
[2] restart
[3] stop
EOF
while read oper
do
case ${oper} in
1)
oper=start
break ;;
2)
oper=restart
break ;;
3)
oper=stop
break ;;
start | restart | stop)
break ;;
*) echo "无法识别 ${oper}" ;;
esac
done
}
# 选择代码分支
function chooseBranch() {
cat << EOF
请输入 git 分支。
如:develop、master、feature/xxx
EOF
read branch
if [[ "${branch}" =~ ^ ( feature/ ) ( [^ \f\n\r\t\v]+ ) ]] || [ "${branch}" == "develop" ] || [ "${branch}" == "master" ]; then
echo "输入了 ${branch}"
else
echo "无法识别 ${branch}"
chooseBranch
fi
}
# 选择运行环境
function chooseProfile() {
cat << EOF
请选择运行环境(数字或关键字均可)。
可选值:
[1] develop (开发环境)
[2] test (测试环境)
[3] preview (预发布环境)
[4] product (生产环境)
EOF
while read profile
do
case ${profile} in
1)
profile=develop
break ;;
2)
profile=test
break ;;
3)
profile=preview
break ;;
4)
profile=product
break ;;
develop | test | preview | product)
break ;;
*) echo "无法识别 ${profile}" ;;
esac
done
}
# 确认选择
function confirmChoice() {
cat << EOF
===================================================
请确认您的选择:Y/N
app: ${app}
oper: ${oper}
branch: ${branch}
profile: ${profile}
===================================================
EOF
while read confirm
do
case ${confirm} in
y | Y)
echo -e "\n\n>>>>>>>>>>>>>> 开始发布应用"
break ;;
n | N)
echo -e "重新输入发布参数\n"
inputParams ;;
*)
echo "无法识别 ${confirm}" ;;
esac
done
}
# 引导式发布应用
function releaseApp() {
# 输入执行参数
app=""
branch=""
profile=""
chooseAppName
chooseOper
if [ "${oper}" == "stop" ]; then
confirmChoice
if [ "${app}" == "all" ]; then
${SCRIPT_DIR}/${app}-run.sh stop ${profile}
else
${SCRIPT_DIR}/${app}-run.sh stop ${profile}
fi
else
chooseBranch
chooseProfile
confirmChoice
if [ "${app}" == "all" ]; then
${SCRIPT_DIR}/js-app-release.sh ${branch} ${profile}
else
${SCRIPT_DIR}/${app}-release.sh ${branch} ${profile}
fi
fi
}
# 脚本主方法
function main() {
printHeadInfo
while read sign
do
case ${sign} in
exit)
echo "主动退出脚本"
exit 0 ;;
*)
releaseApp ;;
esac
# 装载函数库
printFootInfo
done
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
# 设置全局常量
SCRIPT_DIR=$(cd "$(dirname "$0")";
pwd)
SOURCE_DIR=/home/zp/source/
# 装载函数库
. ${SCRIPT_DIR}/helper.sh
# 检查必要文件或文件夹是否存在
checkFileExist ${SCRIPT_DIR}/helper.sh
createFolderIfNotExist ${SOURCE_DIR}
# 运行主方法
main
================================================
FILE: codes/linux/build/spring-boot-run.sh
================================================
#!/usr/bin/env bash
##############################################################################
# console color
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
##############################################################################
JAVA_OPTS=""
APP_OPTS=""
packageJavaOpts() {
# GC OPTS
JAVA_OPTS="${JAVA_OPTS} -server -Xms8g -Xmx16g -Xss512k"
JAVA_OPTS="${JAVA_OPTS} -XX:+UseParallelOldGC -XX:+UseAdaptiveSizePolicy -XX:MaxGCPauseMillis=150"
JAVA_OPTS="${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom"
# DEBUG OPTS
if [[ ${debug} == "on" ]]; then
# Remote Debug
JAVA_OPTS="${JAVA_OPTS} -Xdebug -Xnoagent -Djava.compiler=NONE"
JAVA_OPTS="${JAVA_OPTS} -Xrunjdwp:transport=dt_socket,address=28889,server=y,suspend=n"
# GC LOG
JAVA_OPTS="${JAVA_OPTS} -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
JAVA_OPTS="${JAVA_OPTS} -verbose:gc -Xloggc:${LOG_PATH}/${APP_NAME}.gc.log"
JAVA_OPTS="${JAVA_OPTS} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
# Heap Dump
JAVA_OPTS="${JAVA_OPTS} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError"
JAVA_OPTS="${JAVA_OPTS} -XX:HeapDumpPath=${LOG_PATH}/${APP_NAME}.heapdump.hprof"
# JMX OPTS
IP=`ip addr | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d/ -f1`
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote=true"
JAVA_OPTS="${JAVA_OPTS} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
JAVA_OPTS="${JAVA_OPTS} -Djava.rmi.server.hostname=${IP} -Dcom.sun.management.jmxremote.port=18889"
fi
# APP OPTS
JAVA_OPTS="${JAVA_OPTS} -Dsun.net.inetaddr.ttl=60 -Djava.net.preferIPv4Stack=true"
JAVA_OPTS="${JAVA_OPTS} -Dspring.profiles.active=${profile} -Dfile.encoding=UTF-8"
# CLASSPATH
APP_OPTS=" -classpath lib/* -Dlogging.config=file:./config/logback.dev.xml --spring.config.location=classpath:/,classpath:/config/,file:./,file:./config/"
}
# 检查服务是否已经启动
pid=""
checkStarted() {
pid=`ps -ef | grep java | grep ${APP_NAME} | awk '{print $2}'`
if [[ -n "${pid}" ]]; then
return 0
else
return 1
fi
}
main() {
case "${oper}" in
start)
startServer
;;
stop)
stopServer
;;
restart)
stopServer
sleep 5
startServer
;;
*)
echo "Invalid oper: ${oper}."
exit 1
esac
exit 0
}
stopServer() {
echo -n "stopping server: "
if checkStarted; then
kill -9 ${pid}
printf "${GREEN}\n${APP_NAME} is stopped.${RESET}\n"
else
printf "${RED}\n${APP_NAME} fail to stop.${RESET}\n"
fi
}
startServer() {
printf "${BLUE}starting ${APP_NAME}...${RESET}\n"
if checkStarted; then
printf "${YELLOW}[WARN] ${APP_NAME} already started!${RESET}\n"
printf "PID: ${pid}\n"
exit 1
fi
packageJavaOpts
printf "${CYAN}JVM OPTS:\n ${JAVA_OPTS}${RESET}\n"
if [[ ! -f "${LOG_PATH}/start.out" ]]; then
touch "${LOG_PATH}/start.out"
fi
nohup java ${JAVA_OPTS} -jar ${ROOT_DIR}/../spring-boot-app.jar ${APP_OPTS} >> ${LOG_PATH}/start.out 2>&1 &
printf "${GREEN}\n${APP_NAME} is started.${RESET}\n"
}
######################################## MAIN ########################################
# 设置环境变量
export LANG="zh_CN.UTF-8"
ROOT_DIR=$(pwd)
APP_NAME=spring-boot-app
LOG_PATH=${ROOT_DIR}/../logs
mkdir -p ${LOG_PATH}
declare -a serial
serial=( start stop restart )
echo -n "请选择操作(可选值:start|stop|restart):"
read oper
if ! echo "${serial[@]}" | grep -q ${oper}; then
echo "请选择正确操作(可选值:start|stop|restart)"
exit 1
fi
if [[ ${oper} == "start" ]] || [[ "${oper}" == "restart" ]]; then
declare -a serial2
serial2=( prod dev test )
echo -n "选择 profile(可选值:prod|dev|test):"
read profile
if ! echo "${serial2[@]}" | grep -q ${profile}; then
echo "请选择正确 profile(可选值:prod|dev|test)"
exit 1
fi
declare -a serial3
serial3=( on off )
echo -n "是否启动 debug 模式(可选值:on|off):"
read debug
if ! echo "${serial3[@]}" | grep -q ${debug}; then
echo "是否启动 debug 模式(可选值:on|off)"
exit 1
fi
fi
main
================================================
FILE: codes/linux/build/update-code.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 更新代码脚本
# 只有退出码(exit code)为 0 ,表示脚本执行成功。
# @author: Zhang Peng
###################################################################################
# 检查脚本参数,如必要参数未传入,退出脚本。
checkInput() {
if [ "${repository}" == "" ] || [ "${branch}" == "" ]; then
echo "请输入脚本参数:repository branch [source] [target]"
echo " repository: git 仓储(必填)。"
echo " branch: git 分支(必填)。如 master/develop"
echo " source: 代码存放目录。默认为/home/zp/source。"
echo " target: 代码存放目录。默认为脚本所在目录。"
exit 1
fi
}
# 检查文件夹是否存在,不存在则创建
function createFolderIfNotExist() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# 判断 git 版本库是否存在。根据实际结果修改 ${gitok} 值。
gitok=false
function isGitExist() {
cd ${SOURCE_DIR}
if [ -d "${SOURCE_DIR}/${repository}/${target}" ]; then
cd ${SOURCE_DIR}/${repository}/${target}
#(1)删除git状态零时文件
if [ -f "gitstatus.tmp" ]; then
rm -rf gitstatus.tmp
fi
#(2) 判断是否存在.git目录
if [ -d "./.git" ]; then
#(3) 判断git是否可用
git status &> gitstatus.tmp
grep -iwq 'not a git repository' gitstatus.tmp && gitok=false || gitok=true
fi
#返回到主目录
cd ${SOURCE_DIR}
fi
}
# 如果 git 版本库存在(根据 ${gitok} 值),执行 fetch 操作;反之,执行 clone 操作。
function doFetchOrClone() {
if ${gitok}; then
cd ${SOURCE_DIR}/${repository}/${target}
git reset --hard
git clean -ffdx
git fetch
echo "git fetch ${repository} remote repository 到本地成功"
else
#删除所有内容,便于重新进行git clone
rm -rf ${repository}
git clone --no-checkout git@github.com:${GITHUB_ACCOUNT}/${repository}.git ${SOURCE_DIR}/${repository}/${target}
echo "git clone ${repository} remote repository 到本地成功"
cd ${SOURCE_DIR}/${repository}/${target}
fi
}
# 切换到 ${branch} 分支
function doCheckout() {
echo "检出 ${repository} ${branch} 分支代码"
isRemoteBranch=false
gitRemoteBranch=`git branch -r`
echo -e "$gitRemoteBranch" | grep -iwq ${branch} && isRemoteBranch=true || isRemoteBranch=false
if ${isRemoteBranch}; then
echo "找到 ${branch} 分支。"
git checkout -f 'origin/'${branch}
else
echo "未找到 ${branch} 分支!"
exit 2
fi
echo "更新子模块代码"
git submodule update --init --recursive --force
}
######################################## MAIN ########################################
export LANG="zh_CN.UTF-8"
# 0. 检查传入的参数
repository=`echo $1`
branch=`echo $2`
source=`echo $3`
target=`echo $4`
checkInput
# 设置全局常量
GITHUB_ACCOUNT=dunwu
SOURCE_DIR=/home/xyz/source
if [ "${source}" != "" ]; then
SOURCE_DIR=${source}
fi
createFolderIfNotExist ${SOURCE_DIR}
# 1. 判断本地是否已存在 Git 仓库
isGitExist
# 2. 如果本地已有代码,执行 fetch;反之,从远程 clone
doFetchOrClone
# 3. 切换到指定分支
doCheckout
# 4. 分配权限
chmod -R 777 ${SOURCE_DIR}
exit 0
================================================
FILE: codes/linux/conf/etc/sysctl.conf
================================================
###################################################################################
# /etc/sysctl.conf 文件用于配置 Linux 内核及网络
# @author: Zhang Peng
###################################################################################
# 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1
# 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_tw_recycle = 1
# 如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。
net.ipv4.tcp_fin_timeout = 2
# 避免放大攻击
net.ipv4.icmp_echo_ignore_broadcasts = 1
# 开启恶意icmp错误消息保护
net.ipv4.icmp_ignore_bogus_error_responses = 1
# 开启SYN洪水攻击保护
net.ipv4.tcp_syncookies = 1
# 开启并记录欺骗,源路由和重定向包
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1
# 处理无源路由的包
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# 开启反向路径过滤
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# 确保无人能修改路由表
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# 不充当路由器
net.ipv4.ip_forward = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
# 开启execshild
kernel.exec-shield = 1
kernel.randomize_va_space = 1
# IPv6设置
net.ipv6.conf.default.router_solicitations = 0
net.ipv6.conf.default.accept_ra_rtr_pref = 0
net.ipv6.conf.default.accept_ra_pinfo = 0
net.ipv6.conf.default.accept_ra_defrtr = 0
net.ipv6.conf.default.autoconf = 0
net.ipv6.conf.default.dad_transmits = 0
net.ipv6.conf.default.max_addresses = 1
# 优化LB使用的端口
# 增加系统文件描述符限制
fs.file-max = 65535
# 允许更多的PIDs (减少滚动翻转问题); may break some programs 32768
kernel.pid_max = 65536
# 增加系统IP端口限制
net.ipv4.ip_local_port_range = 2000 65535
# 增加TCP最大缓冲区大小
net.ipv4.tcp_rmem = 4096 87380 8388608
net.ipv4.tcp_wmem = 4096 87380 8388608
# 增加Linux自动调整TCP缓冲区限制
# 最小,默认和最大可使用的字节数
# 最大值不低于4MB,如果你使用非常高的BDP路径可以设置得更高
# Tcp窗口等
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_window_scaling = 1
================================================
FILE: codes/linux/download.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
printf "${BLUE}\n"
cat << EOF
###################################################################################
# linux-tutorial 运维脚本工具集下载脚本
# 下载 https://github.com/dunwu/linux-tutorial 中的所有脚本到当前服务器的
# /home/scripts/linux-tutorial 目录下
# @system: 适用于 CentOS
# @author: Zhang Peng
# See: https://github.com/dunwu/linux-tutorial
###################################################################################
EOF
printf "${RESET}\n"
root=/home/scripts/linux-tutorial
printf "\n${GREEN}>>>>>>>> Download linux-tutorial to ${root} begin.${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "\n${RED}Not detected yum.${RESET}";
exit 1;
}
command -v git > /dev/null 2>&1 || {
printf "\n${YELLOW}Not detected git. Install git.${RESET}\n";
yum install -y git;
}
if [[ -d ${root} ]]; then
cd ${root}
git pull
else
mkdir -p ${root}
git clone https://gitee.com/turnon/linux-tutorial.git ${root}
fi
chmod +x -R ${root}
printf "\n${GREEN}<<<<<<<< Download linux-tutorial to ${root} end.${RESET}\n"
================================================
FILE: codes/linux/dunwu-ops.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# CentOS 常用软件一键安装脚本
# @author Zhang Peng
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ functions
# 打印头部信息
printHeadInfo() {
printf "${C_B_BLUE}\n"
cat << EOF
###################################################################################
# 欢迎使用 Dunwu Shell 运维脚本
# 适用于 Linux CentOS 环境
# @author: Zhang Peng
###################################################################################
EOF
printf "${C_RESET}\n"
}
# 打印尾部信息
printFootInfo() {
printf "${C_B_BLUE}\n"
cat << EOF
###################################################################################
# 脚本执行结束,感谢使用!
###################################################################################
EOF
printf "${C_RESET}\n"
}
# 检查操作系统环境
checkOsVersion() {
if (($1 == 1)); then
platform=`uname -i`
if [[ ${platform} != "x86_64" ]]; then
logError "脚本仅支持 64 位操作系统!"
exit 1
fi
version=`cat /etc/redhat-release | awk '{print substr($4,1,1)}'`
if [[ ${version} != 7 ]]; then
logError "脚本仅支持 CentOS 7!"
exit 1
fi
fi
}
menus=( "配置系统" "安装软件" "退出" )
selectAndExecTask() {
printHeadInfo
PS3="请输入命令编号:"
select item in "${menus[@]}"
do
case ${item} in
"配置系统")
./dunwu-sys.sh
selectAndExecTask ;;
"安装软件")
./dunwu-soft.sh
selectAndExecTask ;;
"退出")
printFootInfo
exit 0 ;;
*)
logWarn "输入项不支持!"
selectAndExecTask ;;
esac
break
done
}
# ------------------------------------------------------------------------------ main
checkOsVersion 1
selectAndExecTask
================================================
FILE: codes/linux/dunwu-soft.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# CentOS 常用软件一键安装脚本
# @author Zhang Peng
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ functions
# 打印头部信息
printHeadInfo() {
printf "${C_B_BLUE}\n"
cat << EOF
###################################################################################
# 欢迎使用 CentOS 常用软件一键安装脚本
# 适用于 Linux CentOS 环境
# @author: Zhang Peng
###################################################################################
EOF
printf "${C_RESET}\n"
}
# print menu
printMenu() {
printf "${C_B_MAGENTA}"
menus=( docker fastdfs gitlab jdk8 jenkins kafka maven mongodb mysql nacos nexus nginx nodejs redis rocketmq tomcat8 zookeeper zsh exit )
for i in "${!menus[@]}"; do
index=`expr ${i} + 1`
val=`expr ${index} % 2`
printf "[%02d] %-20s" "${index}" "${menus[$i]}"
if [[ ${val} -eq 0 ]]; then
printf "\n"
fi
done
printf "\n\n${C_B_BLUE}请选择需要安装的软件:${C_RESET}"
}
# exec shell to install soft
main() {
printMenu
read -t 30 index
if [[ -n ${index} ]]; then
no=`expr ${index} - 1`
len=${#menus[*]}
if [[ ${index} -gt ${len} ]]; then
logWarn "输入项不支持!"
exit 1
fi
key=${menus[$no]}
if [[ ${key} == 'exit' ]]; then
logInfo "退出软件安装脚本。"
exit 0
fi
sh soft/${key}-install.sh
printf "\n"
main
else
logWarn "输入项不支持!"
exit 1
fi
}
# ------------------------------------------------------------------------------ main
printHeadInfo
main
================================================
FILE: codes/linux/dunwu-sys.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# CentOS 环境初始化脚本
# @author Zhang Peng
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ functions
# 打印头部信息
printHeadInfo() {
printf "${C_B_BLUE}\n"
cat << EOF
###################################################################################
# 欢迎使用 Dunwu Shell 环境初始化脚本(设置环境配置、安装基本的命令工具)
# 适用于 Linux CentOS 环境
# @author: Zhang Peng
###################################################################################
EOF
printf "${C_RESET}\n"
}
LINUX_SCRIPTS_DIR=$(cd `dirname $0`; pwd)
menus=( "替换yum镜像" "安装基本的命令工具" "安装常用libs" "系统配置" "全部执行" "退出" )
main() {
PS3="请输入命令编号:"
select item in "${menus[@]}"
do
case ${item} in
"替换yum镜像")
sh ${LINUX_SCRIPTS_DIR}/sys/change-yum-repo.sh
main ;;
"安装基本的命令工具")
sh ${LINUX_SCRIPTS_DIR}/sys/install-tools.sh
main ;;
"安装常用libs")
sh ${LINUX_SCRIPTS_DIR}/sys/install-libs.sh
main ;;
"系统配置")
sh ${LINUX_SCRIPTS_DIR}/sys/sys-settings.sh ${LINUX_SCRIPTS_DIR}/sys
main ;;
"全部执行")
sh ${LINUX_SCRIPTS_DIR}/sys/change-yum-repo.sh
sh ${LINUX_SCRIPTS_DIR}/sys/install-tools.sh
sh ${LINUX_SCRIPTS_DIR}/sys/install-libs.sh
sh ${LINUX_SCRIPTS_DIR}/sys/sys-settings.sh ${LINUX_SCRIPTS_DIR}/sys
logInfo "执行完毕,退出" ;;
"退出")
exit 0 ;;
*)
logWarn "输入项不支持!"
main ;;
esac
break
done
}
# ------------------------------------------------------------------------------ main
printHeadInfo
main
================================================
FILE: codes/linux/libtest/README.md
================================================
# Git 脚本工具
这里汇总一些常用的、简单的 git shell 脚本。
更多功能强大的工具,可以参考 [资源](#资源)
## 资源
- [git-extras](https://github.com/tj/git-extras) - 丰富的 git 扩展支持
- [gitflow](https://github.com/nvie/gitflow) - git-flow shell 版本
- [gitflow-avh](https://github.com/petervanderdoes/gitflow-avh) - git-flow shell 版本
================================================
FILE: codes/linux/libtest/env-test.sh
================================================
#!/usr/bin/env bash
# 装载其它库
source ../lib/utils.sh
# ------------------------------------------------------------------------------ 颜色变量测试
printf "${C_B_YELLOW}测试彩色打印:${C_RESET}\n"
printf "${C_BLACK}Hello.${C_RESET}\n"
printf "${C_RED}Hello.${C_RESET}\n"
printf "${C_GREEN}Hello.${C_RESET}\n"
printf "${C_YELLOW}Hello.${C_RESET}\n"
printf "${C_BLUE}Hello.${C_RESET}\n"
printf "${C_MAGENTA}Hello.${C_RESET}\n"
printf "${C_CYAN}Hello.${C_RESET}\n"
printf "${C_B_BLACK}Hello.${C_RESET}\n"
printf "${C_B_RED}Hello.${C_RESET}\n"
printf "${C_B_GREEN}Hello.${C_RESET}\n"
printf "${C_B_YELLOW}Hello.${C_RESET}\n"
printf "${C_B_BLUE}Hello.${C_RESET}\n"
printf "${C_B_MAGENTA}Hello.${C_RESET}\n"
printf "${C_B_CYAN}Hello.${C_RESET}\n"
printf "${C_U_BLACK}Hello.${C_RESET}\n"
printf "${C_U_RED}Hello.${C_RESET}\n"
printf "${C_U_GREEN}Hello.${C_RESET}\n"
printf "${C_U_YELLOW}Hello.${C_RESET}\n"
printf "${C_U_BLUE}Hello.${C_RESET}\n"
printf "${C_U_MAGENTA}Hello.${C_RESET}\n"
printf "${C_U_CYAN}Hello.${C_RESET}\n"
printf "${C_BG_BLACK}Hello.${C_RESET}\n"
printf "${C_BG_RED}Hello.${C_RESET}\n"
printf "${C_BG_GREEN}Hello.${C_RESET}\n"
printf "${C_BG_YELLOW}Hello.${C_RESET}\n"
printf "${C_BG_BLUE}Hello.${C_RESET}\n"
printf "${C_BG_MAGENTA}Hello.${C_RESET}\n"
printf "${C_BG_CYAN}Hello.${C_RESET}\n"
================================================
FILE: codes/linux/libtest/git-check.sh
================================================
#!/usr/bin/env bash
source ../lib/utils.sh
source ../lib/git.sh
##################################### MAIN #####################################
if [[ $1 ]]; then
DIR=$1
else
DIR=$(pwd)
fi
printInfo "Current path is: ${DIR}."
# 判断是否为 git 项目
checkGit ${DIR}
if [[ "${YES}" == "$?" ]]; then
printInfo "${DIR} is git project."
else
printError "${DIR} is not git project."
fi
# 获取 git 分支
getGitLocalBranch
printInfo "git local branch: ${GIT_LOCAL_BRANCH}"
getGitOriginBranch
printInfo "git origin branch: ${GIT_ORIGIN_BRANCH}"
================================================
FILE: codes/linux/libtest/git-update.sh
================================================
#!/usr/bin/env bash
source ../lib/utils.sh
source ../lib/git.sh
doCloneOrPullGit() {
cloneOrPullGit $1 $2 $3 $4 $5
if [[ "$?" == "${SUCCEED}" ]]; then
printf "\n${C_GREEN}>>>> Update git project [$2/$3] succeed.${C_RESET}\n"
return ${SUCCEED}
else
printf "\n${C_RED}>>>> Update git project [$2/$3] failed.${C_RESET}\n"
return ${FAILED}
fi
}
##################################### MAIN #####################################
ROOT=$(dirname ${BASH_SOURCE[0]})
# 这里需要根据实际情况替换 Git 仓库、项目组、项目、代码分支
REPOSITORY="git@gitee.com"
printf "${C_CYAN}Current path is ${ROOT}.${C_RESET}\n"
doCloneOrPullGit ${REPOSITORY} turnon linux-tutorial master ${ROOT}
r1=$?
doCloneOrPullGit ${REPOSITORY} turnon nginx-tutorial master ${ROOT}
r2=$?
if [[ "${r1}" == "${SUCCEED}" && "${r2}" == "${SUCCEED}" ]]; then
printf "\n${C_B_GREEN}<<<< Init workspace Succeed.${C_RESET}\n\n"
exit ${SUCCEED}
else
printf "\n${C_B_RED}<<<< Init workspace Failed.${C_RESET}\n\n"
exit ${FAILED}
fi
================================================
FILE: codes/linux/libtest/nodejs-test.sh
================================================
#!/usr/bin/env bash
# 装载其它库
source ../lib/nodejs.sh
# ------------------------------------------------------------------------------
ROOT=$(pwd)
path=${ROOT}
if [[ $1 ]]; then
path=$1
fi
version=10.15.0
if [[ $2 ]]; then
version=$2
fi
buildNodejsProject ${path} ${version}
================================================
FILE: codes/linux/soft/README.md
================================================
# 服务安装配置
- [oh-my-zsh 安装](#oh-my-zsh-安装)
- [JDK8 安装](#jdk8-安装)
- [Maven 安装配置](#maven-安装配置)
- [Node.js 安装](#nodejs-安装)
- [MongoDB 安装](#mongodb-安装)
- [Redis 安装配置](#redis-安装配置)
- [Tomcat8 安装](#tomcat8-安装)
- [Kafka 安装](#kafka-安装)
- [RocketMQ 安装](#rocketmq-安装)
- [Nacos 安装](#nacos-安装)
- [ZooKeeper 安装](#zookeeper-安装)
- [Nginx 运维](#nginx-安装)
- [Fastdfs 安装](#fastdfs-安装)
- [Docker 安装](#docker-安装)
## oh-my-zsh 安装
说明:
安装 [oh-my-zsh](https://github.com/robbyrussell/oh-my-zsh)
使用方法
执行以下任意命令即可执行安装脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/zsh-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/zsh-install.sh | bash
```
## JDK8 安装
说明:
JDK8 会被安装到 `/usr/lib/jvm/java` 路径。
使用方法:
执行以下任意命令即可执行安装脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/jdk8-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/jdk8-install.sh | bash
```
## Maven 安装配置
说明:
- 脚本会下载解压 maven `3.6.0` 到 `/opt/maven` 路径下。
- 备份并替换 `settings.xml`,使用 aliyun 镜像加速 maven。
使用方法:
执行以下任意命令即可执行安装脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/maven-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/maven-install.sh | bash
```
## Node.js 安装
说明:
脚本会先安装 nvm(nodejs 版本管理器),并通过 nvm 安装 nodejs `10.15.2`。
使用方法:
执行以下任意命令即可执行安装脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nodejs-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nodejs-install.sh | bash
```
## MongoDB 安装
说明:
下载 mongodb `4.0.9` 并解压安装到 `/opt/mongodb` 路径下。
使用方法:
执行以下任意命令即可执行安装脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/mongodb-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/mongodb-install.sh | bash
```
## Redis 安装配置
**安装说明**
- 采用编译方式安装 Redis, 并将其注册为 systemd 服务
- 安装路径为:`/usr/local/redis`
- 默认下载安装 `5.0.4` 版本,端口号为:`6379`,密码为空
**使用方法**
- 默认安装 - 执行以下任意命令即可:
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/redis-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/redis-install.sh | bash
```
- 自定义安装 - 下载脚本到本地,并按照以下格式执行:
```shell
sh redis-install.sh [version] [port] [password]
```
参数说明:
- `version` - redis 版本号
- `port` - redis 服务端口号
- `password` - 访问密码
## Tomcat8 安装
说明:
下载 tomcat `8.5.28` 并解压安装到 `/opt/tomcat` 路径下。
使用方法:
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/tomcat8-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/tomcat8-install.sh | bash
```
## Kafka 安装
说明:
下载 kafka `2.2.0` 并解压安装到 `/opt/kafka` 路径下。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/kafka-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/kafka-install.sh | bash
```
## RocketMQ 安装
说明:
下载 rocketmq `4.5.0` 并解压安装到 `/opt/rocketmq` 路径下。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/rocketmq-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/rocketmq-install.sh | bash
```
## Nacos 安装
说明:
下载 Nacos `1.0.0` 并解压安装到 `/opt/nacos` 路径下。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nacos-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nacos-install.sh | bash
```
## ZooKeeper 安装
说明:
下载 zookeeper `3.4.12` 并解压安装到 `/opt/zookeeper` 路径下。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/zookeeper-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/zookeeper-install.sh | bash
```
## Nginx 运维
**安装说明**
- 采用编译方式安装 Nginx, 并将其注册为 systemd 服务
- 安装路径为:`/usr/local/nginx`
- 默认下载安装 `1.16.0` 版本
**使用方法**
- 默认安装 - 执行以下任意命令即可:
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nginx-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/nginx-install.sh | bash
```
- 自定义安装 - 下载脚本到本地,并按照以下格式执行:
```bash
sh nginx-install.sh [version]
```
## Fastdfs 安装
说明:
采用编译方式安装 Fastdfs
下载 Fastdfs 并解压安装到 `/opt/fdfs` 路径下。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/fastdfs-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/fastdfs-install.sh | bash
```
## Docker 安装
说明:
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/docker-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/docker-install.sh | bash
```
## FastDFS 安装
说明:
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/fastdfs-install.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/fastdfs-install.sh | bash
```
================================================
FILE: codes/linux/soft/arthas-install.sh
================================================
#!/usr/bin/env bash
# ----------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ----------------------------------------------------------------------------------
printf "${PURPLE}"
cat << EOF
# ----------------------------------------------------------------------------------
# Arthas 安装脚本
# @author: Zhang Peng
# ----------------------------------------------------------------------------------
EOF
printf "${RESET}"
printf "${BLUE}>>>>>>>> begin.\n${RESET}"
root=/opt/arthas
if [[ -n $1 ]]; then
root=$1
fi
mkdir -p ${root}
curl -o ${root}/arthas-boot.jar https://alibaba.github.io/arthas/arthas-boot.jar
printf "${GREEN}[OK]\n${RESET}"
printf "${BLUE}<<<<<<<< end.\n${RESET}"
================================================
FILE: codes/linux/soft/config/fastdfs/client.conf
================================================
# connect timeout in seconds
# default value is 30s
connect_timeout=30
# network timeout in seconds
# default value is 30s
network_timeout=60
# the base path to store log files
base_path=/home/fdfs
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=127.0.0.1:22122
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false
# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false
# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf
#HTTP settings
http.tracker_server_port=80
#use "#include" directive to include HTTP other settiongs
##include http.conf
================================================
FILE: codes/linux/soft/config/fastdfs/storage.conf
================================================
# is this config file disabled
# false for enabled
# true for disabled
disabled=false
# the name of the group this storage server belongs to
#
# comment or remove this item for fetching from tracker server,
# in this case, use_storage_id must set to true in tracker.conf,
# and storage_ids.conf must be configed correctly.
group_name=group1
# bind an address of this host
# empty for bind all addresses of this host
bind_addr=
# if bind an address of this host when connect to other servers
# (this storage server as a client)
# true for binding the address configed by above parameter: "bind_addr"
# false for binding any address of this host
client_bind=true
# the storage server port
port=23000
# connect timeout in seconds
# default value is 30s
connect_timeout=10
# network timeout in seconds
# default value is 30s
network_timeout=60
# heart beat interval in seconds
heart_beat_interval=30
# disk usage report interval in seconds
stat_report_interval=60
# the base path to store data and log files
base_path=/home/fdfs
# max concurrent connections the server supported
# default value is 256
# more max_connections means more memory will be used
# you should set this parameter larger, eg. 10240
max_connections=1024
# the buff size to recv / send data
# this parameter must more than 8KB
# default value is 64KB
# since V2.00
buff_size = 256KB
# accept thread count
# default value is 1
# since V4.07
accept_threads=1
# work thread count, should <= max_connections
# work thread deal network io
# default value is 4
# since V2.00
work_threads=4
# if disk read / write separated
## false for mixed read and write
## true for separated read and write
# default value is true
# since V2.00
disk_rw_separated = true
# disk reader thread count per store base path
# for mixed read / write, this parameter can be 0
# default value is 1
# since V2.00
disk_reader_threads = 1
# disk writer thread count per store base path
# for mixed read / write, this parameter can be 0
# default value is 1
# since V2.00
disk_writer_threads = 1
# when no entry to sync, try read binlog again after X milliseconds
# must > 0, default value is 200ms
sync_wait_msec=50
# after sync a file, usleep milliseconds
# 0 for sync successively (never call usleep)
sync_interval=0
# storage sync start time of a day, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
sync_start_time=00:00
# storage sync end time of a day, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
sync_end_time=23:59
# write to the mark file after sync N files
# default value is 500
write_mark_file_freq=500
# path(disk or mount point) count, default value is 1
store_path_count=1
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
store_path0=/home/fdfs
#store_path1=/home/fdfs2
# subdir_count * subdir_count directories will be auto created under each
# store_path (disk), value can be 1 to 256, default value is 256
subdir_count_per_path=256
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=127.0.0.1:22122
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
#unix group name to run this program,
#not set (empty) means run by the group of current user
run_by_group=
#unix username to run this program,
#not set (empty) means run by current user
run_by_user=
# allow_hosts can ocur more than once, host can be hostname or ip address,
# "*" (only one asterisk) means match all ip addresses
# we can use CIDR ips like 192.168.5.64/26
# and also use range like these: 10.0.1.[0-254] and host[01-08,20-25].domain.com
# for example:
# allow_hosts=10.0.1.[1-15,20]
# allow_hosts=host[01-08,20-25].domain.com
# allow_hosts=192.168.5.64/26
allow_hosts=*
# the mode of the files distributed to the data path
# 0: round robin(default)
# 1: random, distributted by hash code
file_distribute_path_mode=0
# valid when file_distribute_to_path is set to 0 (round robin),
# when the written file count reaches this number, then rotate to next path
# default value is 100
file_distribute_rotate_count=100
# call fsync to disk when write big file
# 0: never call fsync
# other: call fsync when written bytes >= this bytes
# default value is 0 (never call fsync)
fsync_after_written_bytes=0
# sync log buff to disk every interval seconds
# must > 0, default value is 10 seconds
sync_log_buff_interval=10
# sync binlog buff / cache to disk every interval seconds
# default value is 60 seconds
sync_binlog_buff_interval=10
# sync storage stat info to disk every interval seconds
# default value is 300 seconds
sync_stat_file_interval=300
# thread stack size, should >= 512KB
# default value is 512KB
thread_stack_size=512KB
# the priority as a source server for uploading file.
# the lower this value, the higher its uploading priority.
# default value is 10
upload_priority=10
# the NIC alias prefix, such as eth in Linux, you can see it by ifconfig -a
# multi aliases split by comma. empty value means auto set by OS type
# default values is empty
if_alias_prefix=
# if check file duplicate, when set to true, use FastDHT to store file indexes
# 1 or yes: need check
# 0 or no: do not check
# default value is 0
check_file_duplicate=0
# file signature method for check file duplicate
## hash: four 32 bits hash code
## md5: MD5 signature
# default value is hash
# since V4.01
file_signature_method=hash
# namespace for storing file indexes (key-value pairs)
# this item must be set when check_file_duplicate is true / on
key_namespace=FastDFS
# set keep_alive to 1 to enable persistent connection with FastDHT servers
# default value is 0 (short connection)
keep_alive=0
# you can use "#include filename" (not include double quotes) directive to
# load FastDHT server list, when the filename is a relative path such as
# pure filename, the base path is the base path of current/this config file.
# must set FastDHT server list when check_file_duplicate is true / on
# please see INSTALL of FastDHT for detail
##include /home/yuqing/fastdht/conf/fdht_servers.conf
# if log to access log
# default value is false
# since V4.00
use_access_log = false
# if rotate the access log every day
# default value is false
# since V4.00
rotate_access_log = false
# rotate access log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.00
access_log_rotate_time=00:00
# if rotate the error log every day
# default value is false
# since V4.02
rotate_error_log = false
# rotate error log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.02
error_log_rotate_time=00:00
# rotate access log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_access_log_size = 0
# rotate error log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_error_log_size = 0
# keep days of the log files
# 0 means do not delete old log files
# default value is 0
log_file_keep_days = 0
# if skip the invalid record when sync file
# default value is false
# since V4.02
file_sync_skip_invalid_record=false
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# use the ip address of this storage server if domain_name is empty,
# else this domain name will ocur in the url redirected by the tracker server
http.domain_name=
# the port of the web server on this storage server
http.server_port=7001
================================================
FILE: codes/linux/soft/config/fastdfs/tracker.conf
================================================
# is this config file disabled
# false for enabled
# true for disabled
disabled=false
# bind an address of this host
# empty for bind all addresses of this host
bind_addr=
# the tracker server port
port=22122
# connect timeout in seconds
# default value is 30s
connect_timeout=10
# network timeout in seconds
# default value is 30s
network_timeout=60
# the base path to store data and log files
base_path=/home/fdfs
# max concurrent connections this server supported
# you should set this parameter larger, eg. 102400
max_connections=1024
# accept thread count
# default value is 1
# since V4.07
accept_threads=1
# work thread count, should <= max_connections
# default value is 4
# since V2.00
work_threads=4
# min buff size
# default value 8KB
min_buff_size = 8KB
# max buff size
# default value 128KB
max_buff_size = 128KB
# the method of selecting group to upload files
# 0: round robin
# 1: specify group
# 2: load balance, select the max free space group to upload file
store_lookup=2
# which group to upload file
# when store_lookup set to 1, must set store_group to the group name
store_group=group2
# which storage server to upload file
# 0: round robin (default)
# 1: the first server order by ip address
# 2: the first server order by priority (the minimal)
# Note: if use_trunk_file set to true, must set store_server to 1 or 2
store_server=0
# which path(means disk or mount point) of the storage server to upload file
# 0: round robin
# 2: load balance, select the max free space path to upload file
store_path=0
# which storage server to download file
# 0: round robin (default)
# 1: the source storage server which the current file uploaded to
download_server=0
# reserved storage space for system or other applications.
# if the free(available) space of any stoarge server in
# a group <= reserved_storage_space,
# no file can be uploaded to this group.
# bytes unit can be one of follows:
### G or g for gigabyte(GB)
### M or m for megabyte(MB)
### K or k for kilobyte(KB)
### no unit for byte(B)
### XX.XX% as ratio such as reserved_storage_space = 10%
reserved_storage_space = 10%
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
#unix group name to run this program,
#not set (empty) means run by the group of current user
run_by_group=
#unix username to run this program,
#not set (empty) means run by current user
run_by_user=
# allow_hosts can ocur more than once, host can be hostname or ip address,
# "*" (only one asterisk) means match all ip addresses
# we can use CIDR ips like 192.168.5.64/26
# and also use range like these: 10.0.1.[0-254] and host[01-08,20-25].domain.com
# for example:
# allow_hosts=10.0.1.[1-15,20]
# allow_hosts=host[01-08,20-25].domain.com
# allow_hosts=192.168.5.64/26
allow_hosts=*
# sync log buff to disk every interval seconds
# default value is 10 seconds
sync_log_buff_interval = 10
# check storage server alive interval seconds
check_active_interval = 120
# thread stack size, should >= 64KB
# default value is 64KB
thread_stack_size = 64KB
# auto adjust when the ip address of the storage server changed
# default value is true
storage_ip_changed_auto_adjust = true
# storage sync file max delay seconds
# default value is 86400 seconds (one day)
# since V2.00
storage_sync_file_max_delay = 86400
# the max time of storage sync a file
# default value is 300 seconds
# since V2.00
storage_sync_file_max_time = 300
# if use a trunk file to store several small files
# default value is false
# since V3.00
use_trunk_file = false
# the min slot size, should <= 4KB
# default value is 256 bytes
# since V3.00
slot_min_size = 256
# the max slot size, should > slot_min_size
# store the upload file to trunk file when it's size <= this value
# default value is 16MB
# since V3.00
slot_max_size = 16MB
# the trunk file size, should >= 4MB
# default value is 64MB
# since V3.00
trunk_file_size = 64MB
# if create trunk file advancely
# default value is false
# since V3.06
trunk_create_file_advance = false
# the time base to create trunk file
# the time format: HH:MM
# default value is 02:00
# since V3.06
trunk_create_file_time_base = 02:00
# the interval of create trunk file, unit: second
# default value is 38400 (one day)
# since V3.06
trunk_create_file_interval = 86400
# the threshold to create trunk file
# when the free trunk file size less than the threshold, will create
# the trunk files
# default value is 0
# since V3.06
trunk_create_file_space_threshold = 20G
# if check trunk space occupying when loading trunk free spaces
# the occupied spaces will be ignored
# default value is false
# since V3.09
# NOTICE: set this parameter to true will slow the loading of trunk spaces
# when startup. you should set this parameter to true when neccessary.
trunk_init_check_occupying = false
# if ignore storage_trunk.dat, reload from trunk binlog
# default value is false
# since V3.10
# set to true once for version upgrade when your version less than V3.10
trunk_init_reload_from_binlog = false
# the min interval for compressing the trunk binlog file
# unit: second
# default value is 0, 0 means never compress
# FastDFS compress the trunk binlog when trunk init and trunk destroy
# recommand to set this parameter to 86400 (one day)
# since V5.01
trunk_compress_binlog_min_interval = 0
# if use storage ID instead of IP address
# default value is false
# since V4.00
use_storage_id = false
# specify storage ids filename, can use relative or absolute path
# since V4.00
storage_ids_filename = storage_ids.conf
# id type of the storage server in the filename, values are:
## ip: the ip address of the storage server
## id: the server id of the storage server
# this paramter is valid only when use_storage_id set to true
# default value is ip
# since V4.03
id_type_in_filename = ip
# if store slave file use symbol link
# default value is false
# since V4.01
store_slave_file_use_link = false
# if rotate the error log every day
# default value is false
# since V4.02
rotate_error_log = false
# rotate error log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.02
error_log_rotate_time=00:00
# rotate error log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_error_log_size = 0
# keep days of the log files
# 0 means do not delete old log files
# default value is 0
log_file_keep_days = 0
# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false
# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600
# HTTP port on this tracker server
http.server_port=7000
# check storage HTTP server alive interval seconds
# <= 0 for never check
# default value is 30
http.check_alive_interval=30
# check storage HTTP server alive type, values are:
# tcp : connect to the storge server with HTTP port only,
# do not request and get response
# http: storage check alive url must return http status 200
# default value is tcp
http.check_alive_type=tcp
# check storage HTTP server alive uri/url
# NOTE: storage embed HTTP server support uri: /status.html
http.check_alive_uri=/status.html
================================================
FILE: codes/linux/soft/config/mysql/my.cnf
================================================
# -------------------------------------------------------------------------------
# Mysql 基本配置模板
# -------------------------------------------------------------------------------
[mysqld]
# GENERAL
# -------------------------------------------------------------------------------
server_id = 2
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
pid_file = /var/lib/mysql/mysql.pid
user = mysql
port = 3306
default_storage_engine = InnoDB
default_time_zone = '+8:00'
character_set_server = utf8mb4
collation_server = utf8mb4_0900_ai_ci
# LOG
# -------------------------------------------------------------------------------
log_error = /var/log/mysql/mysql.log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql_slow_query_log.log
long_query_time = 3
min_examined_row_limit = 100
expire_logs_days = 7
# InnoDB
# -------------------------------------------------------------------------------
innodb_buffer_pool_size = 4G
innodb_log_file_size = 128M
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT
# MyIsam
# -------------------------------------------------------------------------------
key_buffer_size = 256M
# OTHER
# -------------------------------------------------------------------------------
tmp_table_size = 32M
max_heap_table_size = 32M
max_connections = 10000
open_files_limit = 65535
[client]
socket = /var/lib/mysql/mysql.sock
port = 3306
================================================
FILE: codes/linux/soft/config/nginx/conf/fdfs.conf
================================================
server {
listen 7001; ## 该端口为storage.conf中的http.server_port相同
server_name localhost;
location ~/group[0-9]/ {
ngx_fastdfs_module;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
================================================
FILE: codes/linux/soft/config/nginx/nginx.conf
================================================
worker_processes 1;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid /usr/local/nginx/logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
include conf.d/*.conf;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/nginx-http-access.log;
sendfile on;
keepalive_timeout 65;
client_max_body_size 20m;
client_body_buffer_size 128k;
#common header set
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
================================================
FILE: codes/linux/soft/config/nginx/nginx.service
================================================
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
================================================
FILE: codes/linux/soft/config/redis/cluster/27001/sentinel.conf
================================================
port 27001
daemonize yes
sentinel monitor redis-master 172.22.6.3 7001 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27001/27001.log
================================================
FILE: codes/linux/soft/config/redis/cluster/27002/sentinel.conf
================================================
port 27002
daemonize yes
sentinel monitor redis-master 172.22.6.3 7002 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27002/27002.log
================================================
FILE: codes/linux/soft/config/redis/cluster/27003/sentinel.conf
================================================
port 27003
daemonize yes
sentinel monitor redis-master 172.22.6.3 7003 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27003/27003.log
================================================
FILE: codes/linux/soft/config/redis/cluster/27004/sentinel.conf
================================================
port 27004
daemonize yes
sentinel monitor redis-master 172.22.6.3 7007 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27004/27004.log
================================================
FILE: codes/linux/soft/config/redis/cluster/27005/sentinel.conf
================================================
port 27005
daemonize yes
sentinel monitor redis-master 172.22.6.3 7008 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27005/27005.log
================================================
FILE: codes/linux/soft/config/redis/cluster/27006/sentinel.conf
================================================
port 27006
daemonize yes
sentinel monitor redis-master 172.22.6.3 7009 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27006/27006.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7001/redis.conf
================================================
port 7001
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7001/7001.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7001
pidfile /usr/local/redis/conf/7001/7001.pid
logfile /usr/local/redis/conf/7001/7001.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7002/redis.conf
================================================
port 7002
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7002/7002.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7002
pidfile /usr/local/redis/conf/7002/7002.pid
logfile /usr/local/redis/conf/7002/7002.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7003/redis.conf
================================================
port 7003
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7003/7003.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7003
pidfile /usr/local/redis/conf/7003/7003.pid
logfile /usr/local/redis/conf/7003/7003.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7004/redis.conf
================================================
port 7004
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7004/7004.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7004
pidfile /usr/local/redis/conf/7004/7004.pid
logfile /usr/local/redis/conf/7004/7004.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7005/redis.conf
================================================
port 7005
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7005/7005.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7005
pidfile /usr/local/redis/conf/7005/7005.pid
logfile /usr/local/redis/conf/7005/7005.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7006/redis.conf
================================================
port 7006
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7006/7006.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7006
pidfile /usr/local/redis/conf/7006/7006.pid
logfile /usr/local/redis/conf/7006/7006.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7007/redis.conf
================================================
port 7007
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7007/7007.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7007
pidfile /usr/local/redis/conf/7007/7007.pid
logfile /usr/local/redis/conf/7007/7007.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7008/redis.conf
================================================
port 7008
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7008/7008.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7008
pidfile /usr/local/redis/conf/7008/7008.pid
logfile /usr/local/redis/conf/7008/7008.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7009/redis.conf
================================================
port 7009
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7009/7009.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7009
pidfile /usr/local/redis/conf/7009/7009.pid
logfile /usr/local/redis/conf/7009/7009.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7010/redis.conf
================================================
port 7010
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7010/7010.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7010
pidfile /usr/local/redis/conf/7010/7010.pid
logfile /usr/local/redis/conf/7010/7010.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7011/redis.conf
================================================
port 7011
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7011/7011.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7011
pidfile /usr/local/redis/conf/7011/7011.pid
logfile /usr/local/redis/conf/7011/7011.log
================================================
FILE: codes/linux/soft/config/redis/cluster/7012/redis.conf
================================================
port 7012
bind 172.22.6.3
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7012/7012.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7012
pidfile /usr/local/redis/conf/7012/7012.pid
logfile /usr/local/redis/conf/7012/7012.log
================================================
FILE: codes/linux/soft/config/redis/cluster/README.md
================================================
# Redis 集群配置
## 使用方式
集群拓扑:
- 三主三从
- 三哨兵
启动方式:
- 先执行 redis-cluster.sh,会自动根据 7001 ~ 7006 目录启动服务器,并将其配置为集群。
- 再执行 start-sentinel.sh,会根据 27001 ~ 27003 目录启动哨兵,监听集群中的三个主节点。
## 配置
(1)集群服务器配置 redis.conf
```
port 7001
bind 0.0.0.0
daemonize yes
cluster-enabled yes
cluster-config-file /usr/local/redis/conf/7001/7001.conf
cluster-node-timeout 10000
appendonly yes
dir /usr/local/redis/conf/7001
pidfile /usr/local/redis/conf/7001/7001.pid
logfile /usr/local/redis/conf/7001/7001.log
```
端口号、配置目录(`/usr/local/redis/conf`)根据实际情况修改。
(2)哨兵服务器配置 sentinel.conf
```
port 27003
daemonize yes
sentinel monitor redis-master 172.22.6.3 7003 2
sentinel down-after-milliseconds redis-master 5000
sentinel failover-timeout redis-master 900000
sentinel parallel-syncs redis-master 1
#sentinel auth-pass redis-master 123456
logfile /usr/local/redis/conf/27003/27003.log
```
端口号、配置目录(`/usr/local/redis/conf`)根据实际情况修改。
最重要的配置在于:sentinel monitor redis-master 172.22.6.3 7003 2
表示监听的服务器集群名叫 redis-master,当前哨兵监听的服务器节点是:172.22.6.3:7003,这个节点如果是主节点,一旦宕机,选举新的主节点,需要至少 2 个哨兵同意。
================================================
FILE: codes/linux/soft/config/redis/cluster/redis-cluster.sh
================================================
#!/usr/bin/env bash
# Settings
HOST="172.22.6.3"
PORT=7000
TIMEOUT=2000
NODES=6
REPLICAS=1
ENDPORT=$((PORT+NODES))
# You may want to put the above config parameters into config.sh in order to
# override the defaults without modifying this script.
if [[ -a config.sh ]]
then
source "config.sh"
fi
if [[ "$1" == "create" ]]
then
HOSTLIST=""
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
HOSTLIST="$HOSTLIST $HOST:$PORT"
done
/opt/redis/src/redis-cli --cluster create ${HOSTLIST} --cluster-replicas ${REPLICAS}
exit 0
fi
if [[ "$1" == "start" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
echo "Starting $PORT"
/opt/redis/src/redis-server /usr/local/redis/conf/${PORT}/redis.conf
done
exit 0
fi
if [[ "$1" == "stop" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
echo "Stopping $PORT"
/opt/redis/src/redis-cli -p ${PORT} shutdown nosave
done
exit 0
fi
if [[ "$1" == "watch" ]]
then
PORT=$((PORT+1))
while [ 1 ]; do
clear
date
/opt/redis/src/redis-cli -p ${PORT} cluster nodes | head -30
sleep 1
done
exit 0
fi
if [[ "$1" == "tail" ]]
then
INSTANCE=$2
PORT=$((PORT+INSTANCE))
tail -f ${PORT}.log
exit 0
fi
if [[ "$1" == "call" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
/opt/redis/src/redis-cli -p ${PORT} $2 $3 $4 $5 $6 $7 $8 $9
done
exit 0
fi
if [[ "$1" == "clean" ]]
then
rm -rf *.log
rm -rf appendonly*.aof
rm -rf dump*.rdb
rm -rf nodes*.conf
exit 0
fi
if [[ "$1" == "clean-logs" ]]
then
rm -rf *.log
exit 0
fi
echo "Usage: $0 [start|create|stop|watch|tail|clean]"
echo "start -- Launch Redis Cluster instances."
echo "create -- Create a cluster using redis-cli --cluster create."
echo "stop -- Stop Redis Cluster instances."
echo "watch -- Show CLUSTER NODES output (first 30 lines) of first node."
echo "tail -- Run tail -f of instance at base port + ID."
echo "clean -- Remove all instances data, logs, configs."
echo "clean-logs -- Remove just instances logs."
================================================
FILE: codes/linux/soft/config/redis/cluster/redis-cluster2.sh
================================================
#!/usr/bin/env bash
# Settings
HOST="172.22.6.3"
PORT=7000
TIMEOUT=2000
NODES=12
REPLICAS=1
ENDPORT=$((PORT+NODES))
# You may want to put the above config parameters into config.sh in order to
# override the defaults without modifying this script.
if [[ -a config.sh ]]
then
source "config.sh"
fi
if [[ "$1" == "create" ]]
then
HOSTLIST=""
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
HOSTLIST="$HOSTLIST $HOST:$PORT"
done
/opt/redis/src/redis-cli --cluster create ${HOSTLIST} --cluster-replicas ${REPLICAS}
exit 0
fi
if [[ "$1" == "start" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
echo "Starting $PORT"
/opt/redis/src/redis-server /usr/local/redis/conf/${PORT}/redis.conf
done
exit 0
fi
if [[ "$1" == "stop" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
echo "Stopping $PORT"
/opt/redis/src/redis-cli -p ${PORT} shutdown nosave
done
exit 0
fi
if [[ "$1" == "watch" ]]
then
PORT=$((PORT+1))
while [ 1 ]; do
clear
date
/opt/redis/src/redis-cli -p ${PORT} cluster nodes | head -30
sleep 1
done
exit 0
fi
if [[ "$1" == "tail" ]]
then
INSTANCE=$2
PORT=$((PORT+INSTANCE))
tail -f ${PORT}.log
exit 0
fi
if [[ "$1" == "call" ]]
then
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
/opt/redis/src/redis-cli -p ${PORT} $2 $3 $4 $5 $6 $7 $8 $9
done
exit 0
fi
if [[ "$1" == "clean" ]]
then
rm -rf *.log
rm -rf appendonly*.aof
rm -rf dump*.rdb
rm -rf nodes*.conf
exit 0
fi
if [[ "$1" == "clean-logs" ]]
then
rm -rf *.log
exit 0
fi
echo "Usage: $0 [start|create|stop|watch|tail|clean]"
echo "start -- Launch Redis Cluster instances."
echo "create -- Create a cluster using redis-cli --cluster create."
echo "stop -- Stop Redis Cluster instances."
echo "watch -- Show CLUSTER NODES output (first 30 lines) of first node."
echo "tail -- Run tail -f of instance at base port + ID."
echo "clean -- Remove all instances data, logs, configs."
echo "clean-logs -- Remove just instances logs."
================================================
FILE: codes/linux/soft/config/redis/cluster/start-cluster.sh
================================================
#!/usr/bin/env bash
PORT=6380
NODES=6
ENDPORT=$((PORT+NODES))
# 启动 4 个 redis server
while [[ $((PORT < ENDPORT)) != "0" ]]; do
PORT=$((PORT+1))
echo "Starting $PORT"
/opt/redis/src/redis-server /usr/local/redis/conf/${PORT}/redis.conf
done
# 创建集群模式,设置副本为 1
# redis cluster 会自动将 4 个节点设置为 一主一从 模式,并且为两个主节点做数据分片
/opt/redis/src/redis-cli --cluster create 172.22.6.3:6381 172.22.6.3:6382 172.22.6.3:6383 172.22.6.3:6384 172.22.6.3:6385 172.22.6.3:6386 --cluster-replicas 1
# 启动哨兵
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26381/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26382/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26383/sentinel.conf
================================================
FILE: codes/linux/soft/config/redis/cluster/start-cluster2.sh
================================================
#!/usr/bin/env bash
# 启动 4 个 redis server
/opt/redis/src/redis-server /usr/local/redis/conf/6381/redis.conf
/opt/redis/src/redis-server /usr/local/redis/conf/6382/redis.conf
/opt/redis/src/redis-server /usr/local/redis/conf/6383/redis.conf
/opt/redis/src/redis-server /usr/local/redis/conf/6384/redis.conf
/opt/redis/src/redis-server /usr/local/redis/conf/6385/redis.conf
/opt/redis/src/redis-server /usr/local/redis/conf/6386/redis.conf
# 创建集群模式,设置副本为 1
# redis cluster 会自动将 4 个节点设置为 一主一从 模式,并且为两个主节点做数据分片
/opt/redis/src/redis-cli --cluster create 172.22.6.3:6381 172.22.6.3:6382 172.22.6.3:6383 172.22.6.3:6384 172.22.6.3:6385 172.22.6.3:6386 --cluster-replicas 1
# 启动哨兵
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26381/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26382/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/26383/sentinel.conf
================================================
FILE: codes/linux/soft/config/redis/cluster/start-sentinel.sh
================================================
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27001/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27002/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27003/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27004/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27005/sentinel.conf
/opt/redis/src/redis-sentinel /usr/local/redis/conf/27006/sentinel.conf
================================================
FILE: codes/linux/soft/config/redis/redis.conf
================================================
# Redis configuration file example.
#
# Note that in order to read the configuration file, Redis must be
# started with the file path as first argument:
#
# ./redis-server /path/to/redis.conf
# Note on units: when memory size is needed, it is possible to specify
# it in the usual form of 1k 5GB 4M and so forth:
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units are case insensitive so 1GB 1Gb 1gB are all the same.
################################## INCLUDES ###################################
# Include one or more other config files here. This is useful if you
# have a standard template that goes to all Redis servers but also need
# to customize a few per-server settings. Include files can include
# other files, so use this wisely.
#
# Notice option "include" won't be rewritten by command "CONFIG REWRITE"
# from admin or Redis Sentinel. Since Redis always uses the last processed
# line as value of a configuration directive, you'd better put includes
# at the beginning of this file to avoid overwriting config change at runtime.
#
# If instead you are interested in using includes to override configuration
# options, it is better to use include as the last line.
#
# include /path/to/local.conf
# include /path/to/other.conf
################################## MODULES #####################################
# Load modules at startup. If the server is not able to load modules
# it will abort. It is possible to use multiple loadmodule directives.
#
# loadmodule /path/to/my_module.so
# loadmodule /path/to/other_module.so
################################## NETWORK #####################################
# By default, if no "bind" configuration directive is specified, Redis listens
# for connections from all the network interfaces available on the server.
# It is possible to listen to just one or multiple selected interfaces using
# the "bind" configuration directive, followed by one or more IP addresses.
#
# Examples:
#
# bind 192.168.1.100 10.0.0.1
# bind 127.0.0.1 ::1
#
# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the
# internet, binding to all the interfaces is dangerous and will expose the
# instance to everybody on the internet. So by default we uncomment the
# following bind directive, that will force Redis to listen only into
# the IPv4 loopback interface address (this means Redis will be able to
# accept connections only from clients running into the same computer it
# is running).
#
# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES
# JUST COMMENT THE FOLLOWING LINE.
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bind 172.22.6.3
# Protected mode is a layer of security protection, in order to avoid that
# Redis instances left open on the internet are accessed and exploited.
#
# When protected mode is on and if:
#
# 1) The server is not binding explicitly to a set of addresses using the
# "bind" directive.
# 2) No password is configured.
#
# The server only accepts connections from clients connecting from the
# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain
# sockets.
#
# By default protected mode is enabled. You should disable it only if
# you are sure you want clients from other hosts to connect to Redis
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode no
# Accept connections on the specified port, default is 6379 (IANA #815344).
# If port 0 is specified Redis will not listen on a TCP socket.
port 6379
# TCP listen() backlog.
#
# In high requests-per-second environments you need an high backlog in order
# to avoid slow clients connections issues. Note that the Linux kernel
# will silently truncate it to the value of /proc/sys/net/core/somaxconn so
# make sure to raise both the value of somaxconn and tcp_max_syn_backlog
# in order to get the desired effect.
tcp-backlog 511
# Unix socket.
#
# Specify the path for the Unix socket that will be used to listen for
# incoming connections. There is no default, so Redis will not listen
# on a unix socket when not specified.
#
# unixsocket /tmp/redis.sock
# unixsocketperm 700
# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0
# TCP keepalive.
#
# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence
# of communication. This is useful for two reasons:
#
# 1) Detect dead peers.
# 2) Take the connection alive from the point of view of network
# equipment in the middle.
#
# On Linux, the specified value (in seconds) is the period used to send ACKs.
# Note that to close the connection the double of the time is needed.
# On other kernels the period depends on the kernel configuration.
#
# A reasonable value for this option is 300 seconds, which is the new
# Redis default starting with Redis 3.2.1.
tcp-keepalive 300
################################# GENERAL #####################################
# By default Redis does not run as a daemon. Use 'yes' if you need it.
# Note that Redis will write a pid file in /var/run/redis.pid when daemonized.
daemonize yes
# If you run Redis from upstart or systemd, Redis can interact with your
# supervision tree. Options:
# supervised no - no supervision interaction
# supervised upstart - signal upstart by putting Redis into SIGSTOP mode
# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET
# supervised auto - detect upstart or systemd method based on
# UPSTART_JOB or NOTIFY_SOCKET environment variables
# Note: these supervision methods only signal "process is ready."
# They do not enable continuous liveness pings back to your supervisor.
supervised no
# If a pid file is specified, Redis writes it where specified at startup
# and removes it at exit.
#
# When the server runs non daemonized, no pid file is created if none is
# specified in the configuration. When the server is daemonized, the pid file
# is used even if not specified, defaulting to "/var/run/redis.pid".
#
# Creating a pid file is best effort: if Redis is not able to create it
# nothing bad happens, the server will start and run normally.
pidfile /var/run/redis/redis-6379.pid
# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice
# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile ""
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident redis
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0
# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT where
# dbid is a number between 0 and 'databases'-1
databases 16
# By default Redis shows an ASCII art logo only when started to log to the
# standard output and if the standard output is a TTY. Basically this means
# that normally a logo is displayed only in interactive sessions.
#
# However it is possible to force the pre-4.0 behavior and always show a
# ASCII art logo in startup logs by setting the following option to yes.
always-show-logo yes
################################ SNAPSHOTTING ################################
#
# Save the DB on disk:
#
# save
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
#
# Note: you can disable saving completely by commenting out all "save" lines.
#
# It is also possible to remove all the previously configured save
# points by adding a save directive with a single empty string argument
# like in the following example:
#
# save ""
save 900 1
save 300 10
save 60 10000
# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
# This will make the user aware (in a hard way) that data is not persisting
# on disk properly, otherwise chances are that no one will notice and some
# disaster will happen.
#
# If the background saving process will start working again Redis will
# automatically allow writes again.
#
# However if you have setup your proper monitoring of the Redis server
# and persistence, you may want to disable this feature so that Redis will
# continue to work as usual even if there are problems with disk,
# permissions, and so forth.
stop-writes-on-bgsave-error yes
# Compress string objects using LZF when dump .rdb databases?
# For default that's set to 'yes' as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or keys.
rdbcompression yes
# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.
# This makes the format more resistant to corruption but there is a performance
# hit to pay (around 10%) when saving and loading RDB files, so you can disable it
# for maximum performances.
#
# RDB files created with checksum disabled have a checksum of zero that will
# tell the loading code to skip the check.
rdbchecksum yes
# The filename where to dump the DB
dbfilename dump.rdb
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./
################################# REPLICATION #################################
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
# replicaof
# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the replica to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the replica request.
#
# masterauth
# When a replica loses its connection with the master, or when the replication
# is still in progress, the replica can act in two different ways:
#
# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will
# still reply to client requests, possibly with out of date data, or the
# data set may just be empty if this is the first synchronization.
#
# 2) if replica-serve-stale-data is set to 'no' the replica will reply with
# an error "SYNC with master in progress" to all the kind of commands
# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG,
# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB,
# COMMAND, POST, HOST: and LATENCY.
#
replica-serve-stale-data yes
# You can configure a replica instance to accept writes or not. Writing against
# a replica instance may be useful to store some ephemeral data (because data
# written on a replica will be easily deleted after resync with the master) but
# may also cause problems if clients are writing to it because of a
# misconfiguration.
#
# Since Redis 2.6 by default replicas are read-only.
#
# Note: read only replicas are not designed to be exposed to untrusted clients
# on the internet. It's just a protection layer against misuse of the instance.
# Still a read only replica exports by default all the administrative commands
# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve
# security of read only replicas using 'rename-command' to shadow all the
# administrative / dangerous commands.
replica-read-only yes
# Replication SYNC strategy: disk or socket.
#
# -------------------------------------------------------
# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY
# -------------------------------------------------------
#
# New replicas and reconnecting replicas that are not able to continue the replication
# process just receiving differences, need to do what is called a "full
# synchronization". An RDB file is transmitted from the master to the replicas.
# The transmission can happen in two different ways:
#
# 1) Disk-backed: The Redis master creates a new process that writes the RDB
# file on disk. Later the file is transferred by the parent
# process to the replicas incrementally.
# 2) Diskless: The Redis master creates a new process that directly writes the
# RDB file to replica sockets, without touching the disk at all.
#
# With disk-backed replication, while the RDB file is generated, more replicas
# can be queued and served with the RDB file as soon as the current child producing
# the RDB file finishes its work. With diskless replication instead once
# the transfer starts, new replicas arriving will be queued and a new transfer
# will start when the current one terminates.
#
# When diskless replication is used, the master waits a configurable amount of
# time (in seconds) before starting the transfer in the hope that multiple replicas
# will arrive and the transfer can be parallelized.
#
# With slow disks and fast (large bandwidth) networks, diskless replication
# works better.
repl-diskless-sync no
# When diskless replication is enabled, it is possible to configure the delay
# the server waits in order to spawn the child that transfers the RDB via socket
# to the replicas.
#
# This is important since once the transfer starts, it is not possible to serve
# new replicas arriving, that will be queued for the next RDB transfer, so the server
# waits a delay in order to let more replicas arrive.
#
# The delay is specified in seconds, and by default is 5 seconds. To disable
# it entirely just set it to 0 seconds and the transfer will start ASAP.
repl-diskless-sync-delay 5
# Replicas send PINGs to server in a predefined interval. It's possible to change
# this interval with the repl_ping_replica_period option. The default value is 10
# seconds.
#
# repl-ping-replica-period 10
# The following option sets the replication timeout for:
#
# 1) Bulk transfer I/O during SYNC, from the point of view of replica.
# 2) Master timeout from the point of view of replicas (data, pings).
# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings).
#
# It is important to make sure that this value is greater than the value
# specified for repl-ping-replica-period otherwise a timeout will be detected
# every time there is low traffic between the master and the replica.
#
# repl-timeout 60
# Disable TCP_NODELAY on the replica socket after SYNC?
#
# If you select "yes" Redis will use a smaller number of TCP packets and
# less bandwidth to send data to replicas. But this can add a delay for
# the data to appear on the replica side, up to 40 milliseconds with
# Linux kernels using a default configuration.
#
# If you select "no" the delay for data to appear on the replica side will
# be reduced but more bandwidth will be used for replication.
#
# By default we optimize for low latency, but in very high traffic conditions
# or when the master and replicas are many hops away, turning this to "yes" may
# be a good idea.
repl-disable-tcp-nodelay no
# Set the replication backlog size. The backlog is a buffer that accumulates
# replica data when replicas are disconnected for some time, so that when a replica
# wants to reconnect again, often a full resync is not needed, but a partial
# resync is enough, just passing the portion of data the replica missed while
# disconnected.
#
# The bigger the replication backlog, the longer the time the replica can be
# disconnected and later be able to perform a partial resynchronization.
#
# The backlog is only allocated once there is at least a replica connected.
#
# repl-backlog-size 1mb
# After a master has no longer connected replicas for some time, the backlog
# will be freed. The following option configures the amount of seconds that
# need to elapse, starting from the time the last replica disconnected, for
# the backlog buffer to be freed.
#
# Note that replicas never free the backlog for timeout, since they may be
# promoted to masters later, and should be able to correctly "partially
# resynchronize" with the replicas: hence they should always accumulate backlog.
#
# A value of 0 means to never release the backlog.
#
# repl-backlog-ttl 3600
# The replica priority is an integer number published by Redis in the INFO output.
# It is used by Redis Sentinel in order to select a replica to promote into a
# master if the master is no longer working correctly.
#
# A replica with a low priority number is considered better for promotion, so
# for instance if there are three replicas with priority 10, 100, 25 Sentinel will
# pick the one with priority 10, that is the lowest.
#
# However a special priority of 0 marks the replica as not able to perform the
# role of master, so a replica with priority of 0 will never be selected by
# Redis Sentinel for promotion.
#
# By default the priority is 100.
replica-priority 100
# It is possible for a master to stop accepting writes if there are less than
# N replicas connected, having a lag less or equal than M seconds.
#
# The N replicas need to be in "online" state.
#
# The lag in seconds, that must be <= the specified value, is calculated from
# the last ping received from the replica, that is usually sent every second.
#
# This option does not GUARANTEE that N replicas will accept the write, but
# will limit the window of exposure for lost writes in case not enough replicas
# are available, to the specified number of seconds.
#
# For example to require at least 3 replicas with a lag <= 10 seconds use:
#
# min-replicas-to-write 3
# min-replicas-max-lag 10
#
# Setting one or the other to 0 disables the feature.
#
# By default min-replicas-to-write is set to 0 (feature disabled) and
# min-replicas-max-lag is set to 10.
# A Redis master is able to list the address and port of the attached
# replicas in different ways. For example the "INFO replication" section
# offers this information, which is used, among other tools, by
# Redis Sentinel in order to discover replica instances.
# Another place where this info is available is in the output of the
# "ROLE" command of a master.
#
# The listed IP and address normally reported by a replica is obtained
# in the following way:
#
# IP: The address is auto detected by checking the peer address
# of the socket used by the replica to connect with the master.
#
# Port: The port is communicated by the replica during the replication
# handshake, and is normally the port that the replica is using to
# listen for connections.
#
# However when port forwarding or Network Address Translation (NAT) is
# used, the replica may be actually reachable via different IP and port
# pairs. The following two options can be used by a replica in order to
# report to its master a specific set of IP and port, so that both INFO
# and ROLE will report those values.
#
# There is no need to use both the options if you need to override just
# the port or the IP address.
#
# replica-announce-ip 5.5.5.5
# replica-announce-port 1234
################################## SECURITY ###################################
# Require clients to issue AUTH before processing any other
# commands. This might be useful in environments in which you do not trust
# others with access to the host running redis-server.
#
# This should stay commented out for backward compatibility and because most
# people do not need auth (e.g. they run their own servers).
#:q
# Warning: since Redis is pretty fast an outside user can try up to
# 150k passwords per second against a good box. This means that you should
# use a very strong password otherwise it will be very easy to break.
#
# requirepass
# Command renaming.
#
# It is possible to change the name of dangerous commands in a shared
# environment. For instance the CONFIG command may be renamed into something
# hard to guess so that it will still be available for internal-use tools
# but not available for general clients.
#
# Example:
#
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
#
# It is also possible to completely kill a command by renaming it into
# an empty string:
#
# rename-command CONFIG ""
#
# Please note that changing the name of commands that are logged into the
# AOF file or transmitted to replicas may cause problems.
################################### CLIENTS ####################################
# Set the max number of connected clients at the same time. By default
# this limit is set to 10000 clients, however if the Redis server is not
# able to configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus 32 (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
# maxclients 10000
############################## MEMORY MANAGEMENT ################################
# Set a memory usage limit to the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU or LFU cache, or to
# set a hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have replicas attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the replicas are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of replicas is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have replicas attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for replica
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones with an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
#
# LRU means Least Recently Used
# LFU means Least Frequently Used
#
# Both LRU, LFU and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# Note: with any of the above policies, Redis will return an error on write
# operations, when there are no suitable keys for eviction.
#
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# The default is:
#
# maxmemory-policy noeviction
# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. For default Redis will check five keys and pick the one that was
# used less recently, you can change the sample size using the following
# configuration directive.
#
# The default of 5 produces good enough results. 10 Approximates very closely
# true LRU but costs more CPU. 3 is faster but not very accurate.
#
# maxmemory-samples 5
# Starting from Redis 5, by default a replica will ignore its maxmemory setting
# (unless it is promoted to master after a failover or manually). It means
# that the eviction of keys will be just handled by the master, sending the
# DEL commands to the replica as keys evict in the master side.
#
# This behavior ensures that masters and replicas stay consistent, and is usually
# what you want, however if your replica is writable, or you want the replica to have
# a different memory setting, and you are sure all the writes performed to the
# replica are idempotent, then you may change this default (but be sure to understand
# what you are doing).
#
# Note that since the replica by default does not evict, it may end using more
# memory than the one set via maxmemory (there are certain buffers that may
# be larger on the replica, or data structures may sometimes take more memory and so
# forth). So make sure you monitor your replicas and make sure they have enough
# memory to never hit a real out-of-memory condition before the master hits
# the configured maxmemory setting.
#
# replica-ignore-maxmemory yes
############################# LAZY FREEING ####################################
# Redis has two primitives to delete keys. One is called DEL and is a blocking
# deletion of the object. It means that the server stops processing new commands
# in order to reclaim all the memory associated with an object in a synchronous
# way. If the key deleted is associated with a small object, the time needed
# in order to execute the DEL command is very small and comparable to most other
# O(1) or O(log_N) commands in Redis. However if the key is associated with an
# aggregated value containing millions of elements, the server can block for
# a long time (even seconds) in order to complete the operation.
#
# For the above reasons Redis also offers non blocking deletion primitives
# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and
# FLUSHDB commands, in order to reclaim memory in background. Those commands
# are executed in constant time. Another thread will incrementally free the
# object in the background as fast as possible.
#
# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled.
# It's up to the design of the application to understand when it is a good
# idea to use one or the other. However the Redis server sometimes has to
# delete keys or flush the whole database as a side effect of other operations.
# Specifically Redis deletes objects independently of a user call in the
# following scenarios:
#
# 1) On eviction, because of the maxmemory and maxmemory policy configurations,
# in order to make room for new data, without going over the specified
# memory limit.
# 2) Because of expire: when a key with an associated time to live (see the
# EXPIRE command) must be deleted from memory.
# 3) Because of a side effect of a command that stores data on a key that may
# already exist. For example the RENAME command may delete the old key
# content when it is replaced with another one. Similarly SUNIONSTORE
# or SORT with STORE option may delete existing keys. The SET command
# itself removes any old content of the specified key in order to replace
# it with the specified string.
# 4) During replication, when a replica performs a full resynchronization with
# its master, the content of the whole database is removed in order to
# load the RDB file just transferred.
#
# In all the above cases the default is to delete objects in a blocking way,
# like if DEL was called. However you can configure each case specifically
# in order to instead release memory in a non-blocking way like if UNLINK
# was called, using the following configuration directives:
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
############################## APPEND ONLY MODE ###############################
# By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).
#
# The Append Only File is an alternative persistence mode that provides
# much better durability. For instance using the default data fsync policy
# (see later in the config file) Redis can lose just one second of writes in a
# dramatic event like a server power outage, or a single write if something
# wrong with the Redis process itself happens, but the operating system is
# still running correctly.
#
# AOF and RDB persistence can be enabled at the same time without problems.
# If the AOF is enabled on startup Redis will load the AOF, that is the file
# with the better durability guarantees.
#
# Please check http://redis.io/topics/persistence for more information.
appendonly yes
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use "everysec".
# appendfsync always
appendfsync everysec
# appendfsync no
# When the AOF fsync policy is set to always or everysec, and a background
# saving process (a background save or AOF log background rewriting) is
# performing a lot of I/O against the disk, in some Linux configurations
# Redis may block too long on the fsync() call. Note that there is no fix for
# this currently, as even performing fsync in a different thread will block
# our synchronous write(2) call.
#
# In order to mitigate this problem it's possible to use the following option
# that will prevent fsync() from being called in the main process while a
# BGSAVE or BGREWRITEAOF is in progress.
#
# This means that while another child is saving, the durability of Redis is
# the same as "appendfsync none". In practical terms, this means that it is
# possible to lose up to 30 seconds of log in the worst scenario (with the
# default Linux settings).
#
# If you have latency problems turn this to "yes". Otherwise leave it as
# "no" that is the safest pick from the point of view of durability.
no-appendfsync-on-rewrite no
# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).
#
# This base size is compared to the current size. If the current size is
# bigger than the specified percentage, the rewrite is triggered. Also
# you need to specify a minimal size for the AOF file to be rewritten, this
# is useful to avoid rewriting the AOF file even if the percentage increase
# is reached but it is still pretty small.
#
# Specify a percentage of zero in order to disable the automatic AOF
# rewrite feature.
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# An AOF file may be found to be truncated at the end during the Redis
# startup process, when the AOF data gets loaded back into memory.
# This may happen when the system where Redis is running
# crashes, especially when an ext4 filesystem is mounted without the
# data=ordered option (however this can't happen when Redis itself
# crashes or aborts but the operating system still works correctly).
#
# Redis can either exit with an error when this happens, or load as much
# data as possible (the default now) and start if the AOF file is found
# to be truncated at the end. The following option controls this behavior.
#
# If aof-load-truncated is set to yes, a truncated AOF file is loaded and
# the Redis server starts emitting a log to inform the user of the event.
# Otherwise if the option is set to no, the server aborts with an error
# and refuses to start. When the option is set to no, the user requires
# to fix the AOF file using the "redis-check-aof" utility before to restart
# the server.
#
# Note that if the AOF file will be found to be corrupted in the middle
# the server will still exit with an error. This option only applies when
# Redis will try to read more data from the AOF file but not enough bytes
# will be found.
aof-load-truncated yes
# When rewriting the AOF file, Redis is able to use an RDB preamble in the
# AOF file for faster rewrites and recoveries. When this option is turned
# on the rewritten AOF file is composed of two different stanzas:
#
# [RDB file][AOF tail]
#
# When loading Redis recognizes that the AOF file starts with the "REDIS"
# string and loads the prefixed RDB file, and continues loading the AOF
# tail.
aof-use-rdb-preamble yes
################################ LUA SCRIPTING ###############################
# Max execution time of a Lua script in milliseconds.
#
# If the maximum execution time is reached Redis will log that a script is
# still in execution after the maximum allowed time and will start to
# reply to queries with an error.
#
# When a long running script exceeds the maximum execution time only the
# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be
# used to stop a script that did not yet called write commands. The second
# is the only way to shut down the server in the case a write command was
# already issued by the script but the user doesn't want to wait for the natural
# termination of the script.
#
# Set it to 0 or a negative value for unlimited execution without warnings.
lua-time-limit 5000
################################ REDIS CLUSTER ###############################
#
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however
# in order to mark it as "mature" we need to wait for a non trivial percentage
# of users to deploy it in production.
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#
# Normal Redis instances can't be part of a Redis Cluster; only nodes that are
# started as cluster nodes can. In order to start a Redis instance as a
# cluster node enable the cluster support uncommenting the following:
#
# cluster-enabled yes
# Every cluster node has a cluster configuration file. This file is not
# intended to be edited by hand. It is created and updated by Redis nodes.
# Every Redis Cluster node requires a different cluster configuration file.
# Make sure that instances running in the same system do not have
# overlapping cluster configuration file names.
#
# cluster-config-file nodes-6379.conf
# Cluster node timeout is the amount of milliseconds a node must be unreachable
# for it to be considered in failure state.
# Most other internal time limits are multiple of the node timeout.
#
# cluster-node-timeout 15000
# A replica of a failing master will avoid to start a failover if its data
# looks too old.
#
# There is no simple way for a replica to actually have an exact measure of
# its "data age", so the following two checks are performed:
#
# 1) If there are multiple replicas able to failover, they exchange messages
# in order to try to give an advantage to the replica with the best
# replication offset (more data from the master processed).
# Replicas will try to get their rank by offset, and apply to the start
# of the failover a delay proportional to their rank.
#
# 2) Every single replica computes the time of the last interaction with
# its master. This can be the last ping or command received (if the master
# is still in the "connected" state), or the time that elapsed since the
# disconnection with the master (if the replication link is currently down).
# If the last interaction is too old, the replica will not try to failover
# at all.
#
# The point "2" can be tuned by user. Specifically a replica will not perform
# the failover if, since the last interaction with the master, the time
# elapsed is greater than:
#
# (node-timeout * replica-validity-factor) + repl-ping-replica-period
#
# So for example if node-timeout is 30 seconds, and the replica-validity-factor
# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the
# replica will not try to failover if it was not able to talk with the master
# for longer than 310 seconds.
#
# A large replica-validity-factor may allow replicas with too old data to failover
# a master, while a too small value may prevent the cluster from being able to
# elect a replica at all.
#
# For maximum availability, it is possible to set the replica-validity-factor
# to a value of 0, which means, that replicas will always try to failover the
# master regardless of the last time they interacted with the master.
# (However they'll always try to apply a delay proportional to their
# offset rank).
#
# Zero is the only value able to guarantee that when all the partitions heal
# the cluster will always be able to continue.
#
# cluster-replica-validity-factor 10
# Cluster replicas are able to migrate to orphaned masters, that are masters
# that are left without working replicas. This improves the cluster ability
# to resist to failures as otherwise an orphaned master can't be failed over
# in case of failure if it has no working replicas.
#
# Replicas migrate to orphaned masters only if there are still at least a
# given number of other working replicas for their old master. This number
# is the "migration barrier". A migration barrier of 1 means that a replica
# will migrate only if there is at least 1 other working replica for its master
# and so forth. It usually reflects the number of replicas you want for every
# master in your cluster.
#
# Default is 1 (replicas migrate only if their masters remain with at least
# one replica). To disable migration just set it to a very large value.
# A value of 0 can be set but is useful only for debugging and dangerous
# in production.
#
# cluster-migration-barrier 1
# By default Redis Cluster nodes stop accepting queries if they detect there
# is at least an hash slot uncovered (no available node is serving it).
# This way if the cluster is partially down (for example a range of hash slots
# are no longer covered) all the cluster becomes, eventually, unavailable.
# It automatically returns available as soon as all the slots are covered again.
#
# However sometimes you want the subset of the cluster which is working,
# to continue to accept queries for the part of the key space that is still
# covered. In order to do so, just set the cluster-require-full-coverage
# option to no.
#
# cluster-require-full-coverage yes
# This option, when set to yes, prevents replicas from trying to failover its
# master during master failures. However the master can still perform a
# manual failover, if forced to do so.
#
# This is useful in different scenarios, especially in the case of multiple
# data center operations, where we want one side to never be promoted if not
# in the case of a total DC failure.
#
# cluster-replica-no-failover no
# In order to setup your cluster make sure to read the documentation
# available at http://redis.io web site.
########################## CLUSTER DOCKER/NAT support ########################
# In certain deployments, Redis Cluster nodes address discovery fails, because
# addresses are NAT-ted or because ports are forwarded (the typical case is
# Docker and other containers).
#
# In order to make Redis Cluster working in such environments, a static
# configuration where each node knows its public address is needed. The
# following two options are used for this scope, and are:
#
# * cluster-announce-ip
# * cluster-announce-port
# * cluster-announce-bus-port
#
# Each instruct the node about its address, client port, and cluster message
# bus port. The information is then published in the header of the bus packets
# so that other nodes will be able to correctly map the address of the node
# publishing the information.
#
# If the above options are not used, the normal Redis Cluster auto-detection
# will be used instead.
#
# Note that when remapped, the bus port may not be at the fixed offset of
# clients port + 10000, so you can specify any port and bus-port depending
# on how they get remapped. If the bus-port is not set, a fixed offset of
# 10000 will be used as usually.
#
# Example:
#
# cluster-announce-ip 10.1.1.5
# cluster-announce-port 6379
# cluster-announce-bus-port 6380
################################## SLOW LOG ###################################
# The Redis Slow Log is a system to log queries that exceeded a specified
# execution time. The execution time does not include the I/O operations
# like talking with the client, sending the reply and so forth,
# but just the time needed to actually execute the command (this is the only
# stage of command execution where the thread is blocked and can not serve
# other requests in the meantime).
#
# You can configure the slow log with two parameters: one tells Redis
# what is the execution time, in microseconds, to exceed in order for the
# command to get logged, and the other parameter is the length of the
# slow log. When a new command is logged the oldest one is removed from the
# queue of logged commands.
# The following time is expressed in microseconds, so 1000000 is equivalent
# to one second. Note that a negative number disables the slow log, while
# a value of zero forces the logging of every command.
slowlog-log-slower-than 10000
# There is no limit to this length. Just be aware that it will consume memory.
# You can reclaim memory used by the slow log with SLOWLOG RESET.
slowlog-max-len 128
################################ LATENCY MONITOR ##############################
# The Redis latency monitoring subsystem samples different operations
# at runtime in order to collect data related to possible sources of
# latency of a Redis instance.
#
# Via the LATENCY command this information is available to the user that can
# print graphs and obtain reports.
#
# The system only logs operations that were performed in a time equal or
# greater than the amount of milliseconds specified via the
# latency-monitor-threshold configuration directive. When its value is set
# to zero, the latency monitor is turned off.
#
# By default latency monitoring is disabled since it is mostly not needed
# if you don't have latency issues, and collecting data has a performance
# impact, that while very small, can be measured under big load. Latency
# monitoring can easily be enabled at runtime using the command
# "CONFIG SET latency-monitor-threshold " if needed.
latency-monitor-threshold 0
############################# EVENT NOTIFICATION ##############################
# Redis can notify Pub/Sub clients about events happening in the key space.
# This feature is documented at http://redis.io/topics/notifications
#
# For instance if keyspace events notification is enabled, and a client
# performs a DEL operation on key "foo" stored in the Database 0, two
# messages will be published via Pub/Sub:
#
# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo
#
# It is possible to select the events that Redis will notify among a set
# of classes. Every class is identified by a single character:
#
# K Keyspace events, published with __keyspace@__ prefix.
# E Keyevent events, published with __keyevent@__ prefix.
# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ...
# $ String commands
# l List commands
# s Set commands
# h Hash commands
# z Sorted set commands
# x Expired events (events generated every time a key expires)
# e Evicted events (events generated when a key is evicted for maxmemory)
# A Alias for g$lshzxe, so that the "AKE" string means all the events.
#
# The "notify-keyspace-events" takes as argument a string that is composed
# of zero or multiple characters. The empty string means that notifications
# are disabled.
#
# Example: to enable list and generic events, from the point of view of the
# event name, use:
#
# notify-keyspace-events Elg
#
# Example 2: to get the stream of the expired keys subscribing to channel
# name __keyevent@0__:expired use:
#
# notify-keyspace-events Ex
#
# By default all notifications are disabled because most users don't need
# this feature and the feature has some overhead. Note that if you don't
# specify at least one of K or E, no events will be delivered.
notify-keyspace-events ""
############################### ADVANCED CONFIG ###############################
# Hashes are encoded using a memory efficient data structure when they have a
# small number of entries, and the biggest entry does not exceed a given
# threshold. These thresholds can be configured using the following directives.
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
# Lists are also encoded in a special way to save a lot of space.
# The number of entries allowed per internal list node can be specified
# as a fixed maximum size or a maximum number of elements.
# For a fixed maximum size, use -5 through -1, meaning:
# -5: max size: 64 Kb <-- not recommended for normal workloads
# -4: max size: 32 Kb <-- not recommended
# -3: max size: 16 Kb <-- probably not recommended
# -2: max size: 8 Kb <-- good
# -1: max size: 4 Kb <-- good
# Positive numbers mean store up to _exactly_ that number of elements
# per list node.
# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size),
# but if your use case is unique, adjust the settings as necessary.
list-max-ziplist-size -2
# Lists may also be compressed.
# Compress depth is the number of quicklist ziplist nodes from *each* side of
# the list to *exclude* from compression. The head and tail of the list
# are always uncompressed for fast push/pop operations. Settings are:
# 0: disable all list compression
# 1: depth 1 means "don't start compressing until after 1 node into the list,
# going from either the head or tail"
# So: [head]->node->node->...->node->[tail]
# [head], [tail] will always be uncompressed; inner nodes will compress.
# 2: [head]->[next]->node->node->...->node->[prev]->[tail]
# 2 here means: don't compress head or head->next or tail->prev or tail,
# but compress all nodes between them.
# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail]
# etc.
list-compress-depth 0
# Sets have a special encoding in just one case: when a set is composed
# of just strings that happen to be integers in radix 10 in the range
# of 64 bit signed integers.
# The following configuration setting sets the limit in the size of the
# set in order to use this special memory saving encoding.
set-max-intset-entries 512
# Similarly to hashes and lists, sorted sets are also specially encoded in
# order to save a lot of space. This encoding is only used when the length and
# elements of a sorted set are below the following limits:
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# HyperLogLog sparse representation bytes limit. The limit includes the
# 16 bytes header. When an HyperLogLog using the sparse representation crosses
# this limit, it is converted into the dense representation.
#
# A value greater than 16000 is totally useless, since at that point the
# dense representation is more memory efficient.
#
# The suggested value is ~ 3000 in order to have the benefits of
# the space efficient encoding without slowing down too much PFADD,
# which is O(N) with the sparse encoding. The value can be raised to
# ~ 10000 when CPU is not a concern, but space is, and the data set is
# composed of many HyperLogLogs with cardinality in the 0 - 15000 range.
hll-sparse-max-bytes 3000
# Streams macro node max size / items. The stream data structure is a radix
# tree of big nodes that encode multiple items inside. Using this configuration
# it is possible to configure how big a single node can be in bytes, and the
# maximum number of items it may contain before switching to a new node when
# appending new stream entries. If any of the following settings are set to
# zero, the limit is ignored, so for instance it is possible to set just a
# max entires limit by setting max-bytes to 0 and max-entries to the desired
# value.
stream-node-max-bytes 4096
stream-node-max-entries 100
# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in
# order to help rehashing the main Redis hash table (the one mapping top-level
# keys to values). The hash table implementation Redis uses (see dict.c)
# performs a lazy rehashing: the more operation you run into a hash table
# that is rehashing, the more rehashing "steps" are performed, so if the
# server is idle the rehashing is never complete and some more memory is used
# by the hash table.
#
# The default is to use this millisecond 10 times every second in order to
# actively rehash the main dictionaries, freeing memory when possible.
#
# If unsure:
# use "activerehashing no" if you have hard latency requirements and it is
# not a good thing in your environment that Redis can reply from time to time
# to queries with 2 milliseconds delay.
#
# use "activerehashing yes" if you don't have such hard requirements but
# want to free memory asap when possible.
activerehashing yes
# The client output buffer limits can be used to force disconnection of clients
# that are not reading data from the server fast enough for some reason (a
# common reason is that a Pub/Sub client can't consume messages as fast as the
# publisher can produce them).
#
# The limit can be set differently for the three different classes of clients:
#
# normal -> normal clients including MONITOR clients
# replica -> replica clients
# pubsub -> clients subscribed to at least one pubsub channel or pattern
#
# The syntax of every client-output-buffer-limit directive is the following:
#
# client-output-buffer-limit
#
# A client is immediately disconnected once the hard limit is reached, or if
# the soft limit is reached and remains reached for the specified number of
# seconds (continuously).
# So for instance if the hard limit is 32 megabytes and the soft limit is
# 16 megabytes / 10 seconds, the client will get disconnected immediately
# if the size of the output buffers reach 32 megabytes, but will also get
# disconnected if the client reaches 16 megabytes and continuously overcomes
# the limit for 10 seconds.
#
# By default normal clients are not limited because they don't receive data
# without asking (in a push way), but just after a request, so only
# asynchronous clients may create a scenario where data is requested faster
# than it can read.
#
# Instead there is a default limit for pubsub and replica clients, since
# subscribers and replicas receive data in a push fashion.
#
# Both the hard or the soft limit can be disabled by setting them to zero.
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# Client query buffers accumulate new commands. They are limited to a fixed
# amount by default in order to avoid that a protocol desynchronization (for
# instance due to a bug in the client) will lead to unbound memory usage in
# the query buffer. However you can configure it here if you have very special
# needs, such us huge multi/exec requests or alike.
#
# client-query-buffer-limit 1gb
# In the Redis protocol, bulk requests, that are, elements representing single
# strings, are normally limited ot 512 mb. However you can change this limit
# here.
#
# proto-max-bulk-len 512mb
# Redis calls an internal function to perform many background tasks, like
# closing connections of clients in timeout, purging expired keys that are
# never requested, and so forth.
#
# Not all tasks are performed with the same frequency, but Redis checks for
# tasks to perform according to the specified "hz" value.
#
# By default "hz" is set to 10. Raising the value will use more CPU when
# Redis is idle, but at the same time will make Redis more responsive when
# there are many keys expiring at the same time, and timeouts may be
# handled with more precision.
#
# The range is between 1 and 500, however a value over 100 is usually not
# a good idea. Most users should use the default of 10 and raise this up to
# 100 only in environments where very low latency is required.
hz 10
# Normally it is useful to have an HZ value which is proportional to the
# number of clients connected. This is useful in order, for instance, to
# avoid too many clients are processed for each background task invocation
# in order to avoid latency spikes.
#
# Since the default HZ value by default is conservatively set to 10, Redis
# offers, and enables by default, the ability to use an adaptive HZ value
# which will temporary raise when there are many connected clients.
#
# When dynamic HZ is enabled, the actual configured HZ will be used as
# as a baseline, but multiples of the configured HZ value will be actually
# used as needed once more clients are connected. In this way an idle
# instance will use very little CPU time while a busy instance will be
# more responsive.
dynamic-hz yes
# When a child rewrites the AOF file, if the following option is enabled
# the file will be fsync-ed every 32 MB of data generated. This is useful
# in order to commit the file to the disk more incrementally and avoid
# big latency spikes.
aof-rewrite-incremental-fsync yes
# When redis saves RDB file, if the following option is enabled
# the file will be fsync-ed every 32 MB of data generated. This is useful
# in order to commit the file to the disk more incrementally and avoid
# big latency spikes.
rdb-save-incremental-fsync yes
# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good
# idea to start with the default settings and only change them after investigating
# how to improve the performances and how the keys LFU change over time, which
# is possible to inspect via the OBJECT FREQ command.
#
# There are two tunable parameters in the Redis LFU implementation: the
# counter logarithm factor and the counter decay time. It is important to
# understand what the two parameters mean before changing them.
#
# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis
# uses a probabilistic increment with logarithmic behavior. Given the value
# of the old counter, when a key is accessed, the counter is incremented in
# this way:
#
# 1. A random number R between 0 and 1 is extracted.
# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1).
# 3. The counter is incremented only if R < P.
#
# The default lfu-log-factor is 10. This is a table of how the frequency
# counter changes with a different number of accesses with different
# logarithmic factors:
#
# +--------+------------+------------+------------+------------+------------+
# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits |
# +--------+------------+------------+------------+------------+------------+
# | 0 | 104 | 255 | 255 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 1 | 18 | 49 | 255 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 10 | 10 | 18 | 142 | 255 | 255 |
# +--------+------------+------------+------------+------------+------------+
# | 100 | 8 | 11 | 49 | 143 | 255 |
# +--------+------------+------------+------------+------------+------------+
#
# NOTE: The above table was obtained by running the following commands:
#
# redis-benchmark -n 1000000 incr foo
# redis-cli object freq foo
#
# NOTE 2: The counter initial value is 5 in order to give new objects a chance
# to accumulate hits.
#
# The counter decay time is the time, in minutes, that must elapse in order
# for the key counter to be divided by two (or decremented if it has a value
# less <= 10).
#
# The default value for the lfu-decay-time is 1. A Special value of 0 means to
# decay the counter every time it happens to be scanned.
#
# lfu-log-factor 10
# lfu-decay-time 1
########################### ACTIVE DEFRAGMENTATION #######################
#
# WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested
# even in production and manually tested by multiple engineers for some
# time.
#
# What is active defragmentation?
# -------------------------------
#
# Active (online) defragmentation allows a Redis server to compact the
# spaces left between small allocations and deallocations of data in memory,
# thus allowing to reclaim back memory.
#
# Fragmentation is a natural process that happens with every allocator (but
# less so with Jemalloc, fortunately) and certain workloads. Normally a server
# restart is needed in order to lower the fragmentation, or at least to flush
# away all the data and create it again. However thanks to this feature
# implemented by Oran Agra for Redis 4.0 this process can happen at runtime
# in an "hot" way, while the server is running.
#
# Basically when the fragmentation is over a certain level (see the
# configuration options below) Redis will start to create new copies of the
# values in contiguous memory regions by exploiting certain specific Jemalloc
# features (in order to understand if an allocation is causing fragmentation
# and to allocate it in a better place), and at the same time, will release the
# old copies of the data. This process, repeated incrementally for all the keys
# will cause the fragmentation to drop back to normal values.
#
# Important things to understand:
#
# 1. This feature is disabled by default, and only works if you compiled Redis
# to use the copy of Jemalloc we ship with the source code of Redis.
# This is the default with Linux builds.
#
# 2. You never need to enable this feature if you don't have fragmentation
# issues.
#
# 3. Once you experience fragmentation, you can enable this feature when
# needed with the command "CONFIG SET activedefrag yes".
#
# The configuration parameters are able to fine tune the behavior of the
# defragmentation process. If you are not sure about what they mean it is
# a good idea to leave the defaults untouched.
# Enabled active defragmentation
# activedefrag yes
# Minimum amount of fragmentation waste to start active defrag
# active-defrag-ignore-bytes 100mb
# Minimum percentage of fragmentation to start active defrag
# active-defrag-threshold-lower 10
# Maximum percentage of fragmentation at which we use maximum effort
# active-defrag-threshold-upper 100
# Minimal effort for defrag in CPU percentage
# active-defrag-cycle-min 5
# Maximal effort for defrag in CPU percentage
# active-defrag-cycle-max 75
# Maximum number of set/hash/zset/list fields that will be processed from
# the main dictionary scan
# active-defrag-max-scan-fields 1000
================================================
FILE: codes/linux/soft/config/redis/redis.service
================================================
[Unit]
Description=Redis
After=network.target
[Service]
Type=forking
PIDFile=/var/run/redis/redis-6379.pid
ExecStart=/usr/local/bin/redis-server /usr/local/redis/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
================================================
FILE: codes/linux/soft/config/settings-aliyun.xml
================================================
aliyunAliyunhttp://maven.aliyun.com/nexus/content/groups/publiccentralrepo2Mirror from Maven Repo2http://repo2.maven.org/maven2/central
================================================
FILE: codes/linux/soft/docker-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 Docker 脚本
# 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install docker begin.${RESET}\n"
# uninstall old version docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# install required libs
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# add docker yum repo
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum makecache fast
# install docker
sudo yum install docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
docker version
printf "${GREEN}<<<<<<<< install docker end.${RESET}\n"
printf "${GREEN}>>>>>>>> replace chinese docker mirror registry${RESET}\n"
if [[ -f "/etc/docker/daemon.json" ]]; then
mv /etc/docker/daemon.json /etc/docker/daemon.json.bak
else
mkdir -p /etc/docker
fi
touch /etc/docker/daemon.json
cat >> /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://hub-mirror.c.163.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
================================================
FILE: codes/linux/soft/elk/boot-elk.sh
================================================
#!/usr/bin/env bash
# 检查脚本输入参数
checkInput() {
if [ "${app}" == "" ] || [ "${oper}" == "" ]; then
echo "请输入脚本参数:name"
echo " app: 要启动的进程关键字(必填)。可选值:elasticsearch|logstash|kibana|filebeat"
echo " oper: 执行操作(必填)。可选值:start|stop"
echo "例:./boot-elk.sh logstash start"
exit 0
fi
if [ "${app}" != "elasticsearch" ] && [ "${app}" != "logstash" ] && [ "${app}" != "kibana" ] && [ "${app}" != "filebeat" ]; then
echo "name 输入错误"
echo "可选值:elasticsearch|logstash|kibana|filebeat"
exit 0
fi
}
# 检查文件是否存在,不存在则退出脚本
checkFileExist() {
if [ ! -f "$1" ]
then
echo "关键文件 $1 找不到,脚本执行结束"
exit 0
fi
}
startup() {
if [ "${app}" == "elasticsearch" ]; then
checkFileExist ${ELASTICSEARCH_BIN_PATH}/elasticsearch
nohup sh ${ELASTICSEARCH_BIN_PATH}/elasticsearch >> ${ELASTICSEARCH_BIN_PATH}/nohup.out 2>&1 &
elif [ "${app}" == "logstash" ]; then
checkFileExist ${LOGSTASH_BIN_PATH}/logstash
nohup sh ${LOGSTASH_BIN_PATH}/logstash -f ${LOGSTASH_BIN_PATH}/logstash.conf >> ${LOGSTASH_BIN_PATH}/nohup.out 2>&1 &
elif [ "${app}" == "kibana" ]; then
checkFileExist ${KIBANA_BIN_PATH}/kibana
nohup sh ${KIBANA_BIN_PATH}/kibana >> ${KIBANA_BIN_PATH}/nohup.out 2>&1 &
elif [ "${app}" == "filebeat" ]; then
checkFileExist ${FILEBEAT_PATH}/filebeat
touch ${FILEBEAT_PATH}/nohup.out
nohup ${FILEBEAT_PATH}/filebeat -e -c ${FILEBEAT_PATH}/filebeat.yml -d "publish" >> ${FILEBEAT_PATH}/nohup.out 2>&1 &
fi
}
shutdown() {
pid=`ps -ef | grep java | grep ${app} | awk '{print $2}'`
kill -9 ${pid}
}
##############################__MAIN__########################################
app=$1
oper=$2
version=6.1.1
ELASTICSEARCH_BIN_PATH=/opt/elastic/elasticsearch-${version}/bin
LOGSTASH_BIN_PATH=/opt/elastic/logstash-${version}/bin
KIBANA_BIN_PATH=/opt/elastic/kibana-${version}-linux-x86_64/bin
FILEBEAT_PATH=/opt/elastic/filebeat-${version}-linux-x86_64
checkInput
case ${oper} in
start)
echo "启动 ${app}"
startup
;;
stop)
echo "终止 ${app}"
shutdown
;;
*) echo "${oper} is invalid oper" ;;
esac
================================================
FILE: codes/linux/soft/elk/config/filebeat.yml
================================================
###################### Filebeat Configuration Example #########################
# This file is an example configuration file highlighting only the most common
# options. The filebeat.reference.yml file from the same directory contains all the
# supported options with more comments. You can use it as a reference.
#
# You can find the full configuration reference here:
# https://www.elastic.co/guide/en/beats/filebeat/index.html
# For more available modules and options, please see the filebeat.reference.yml sample
# configuration file.
#=========================== Filebeat prospectors =============================
filebeat.prospectors:
# Each - is a prospector. Most options can be set at the prospector level, so
# you can use different prospectors for various configurations.
# Below are the prospector specific configurations.
- type: log
# Change to true to enable this prospector configuration.
enabled: true
# Paths that should be crawled and fetched. Glob based paths.
paths:
#- /var/log/*.log
#- c:\programdata\elasticsearch\logs\*
- /home/zp/log/*.log
# Exclude lines. A list of regular expressions to match. It drops the lines that are
# matching any regular expression from the list.
#exclude_lines: ['^DBG']
# Include lines. A list of regular expressions to match. It exports the lines that are
# matching any regular expression from the list.
#include_lines: ['^ERR', '^WARN']
# Exclude files. A list of regular expressions to match. Filebeat drops the files that
# are matching any regular expression from the list. By default, no files are dropped.
#exclude_files: ['.gz$']
# Optional additional fields. These fields can be freely picked
# to add additional information to the crawled log files for filtering
#fields:
# level: debug
# review: 1
### Multiline options
# Mutiline can be used for log messages spanning multiple lines. This is common
# for Java Stack Traces or C-Line Continuation
# The regexp Pattern that has to be matched. The example pattern matches all lines starting with [
#multiline.pattern: ^\[
# Defines if the pattern set under pattern should be negated or not. Default is false.
#multiline.negate: false
# Match can be set to "after" or "before". It is used to define if lines should be append to a pattern
# that was (not) matched before or after or as long as a pattern is not matched based on negate.
# Note: After is the equivalent to previous and before is the equivalent to to next in Logstash
#multiline.match: after
#============================= Filebeat modules ===============================
filebeat.config.modules:
# Glob pattern for configuration loading
path: ${path.config}/modules.d/*.yml
# Set to true to enable config reloading
reload.enabled: true
# Period on which files under path should be checked for changes
#reload.period: 10s
#==================== Elasticsearch template setting ==========================
setup.template.settings:
index.number_of_shards: 3
#index.codec: best_compression
#_source.enabled: false
#================================ General =====================================
# The name of the shipper that publishes the network data. It can be used to group
# all the transactions sent by a single shipper in the web interface.
name: 127.0.0.1
# The tags of the shipper are included in their own field with each
# transaction published.
#tags: ["service-X", "web-tier"]
# Optional fields that you can specify to add additional information to the
# output.
fields:
profile: development
#============================== Dashboards =====================================
# These settings control loading the sample dashboards to the Kibana index. Loading
# the dashboards is disabled by default and can be enabled either by setting the
# options here, or by using the `-setup` CLI flag or the `setup` command.
setup.dashboards.enabled: true
# The URL from where to download the dashboards archive. By default this URL
# has a value which is computed based on the Beat name and version. For released
# versions, this URL points to the dashboard archive on the artifacts.elastic.co
# website.
#setup.dashboards.url:
#============================== Kibana =====================================
# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
# This requires a Kibana endpoint configuration.
setup.kibana:
# Kibana Host
# Scheme and port can be left out and will be set to the default (http and 5601)
# In case you specify and additional path, the scheme is required: http://localhost:5601/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:5601
host: "192.168.28.11:5601"
#============================= Elastic Cloud ==================================
# These settings simplify using filebeat with the Elastic Cloud (https://cloud.elastic.co/).
# The cloud.id setting overwrites the `output.elasticsearch.hosts` and
# `setup.kibana.host` options.
# You can find the `cloud.id` in the Elastic Cloud web UI.
#cloud.id:
# The cloud.auth setting overwrites the `output.elasticsearch.username` and
# `output.elasticsearch.password` settings. The format is `:`.
#cloud.auth:
#================================ Outputs =====================================
# Configure what output to use when sending the data collected by the beat.
#-------------------------- Elasticsearch output ------------------------------
#output.elasticsearch:
# Array of hosts to connect to.
#hosts: ["192.168.28.11:9200"]
# Optional protocol and basic auth credentials.
protocol: "http"
#username: "elastic"
#password: "changeme"
#----------------------------- Logstash output --------------------------------
output.logstash:
# The Logstash hosts
hosts: ["192.168.28.32:5044"]
# Optional SSL. By default is off.
# List of root certificates for HTTPS server verifications
#ssl.certificate_authorities: ["/etc/pki/root/ca.pem"]
# Certificate for SSL client authentication
#ssl.certificate: "/etc/pki/client/cert.pem"
# Client Certificate Key
#ssl.key: "/etc/pki/client/cert.key"
#================================ Logging =====================================
# Sets log level. The default log level is info.
# Available log levels are: critical, error, warning, info, debug
#logging.level: debug
# At debug level, you can selectively enable logging only for some components.
# To enable all selectors use ["*"]. Examples of other selectors are "beat",
# "publish", "service".
logging.selectors: ["*"]
================================================
FILE: codes/linux/soft/elk/config/logback.xml
================================================
%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n${user.dir}/logs/${FILE_NAME}-all.%d{yyyy-MM-dd}.log3030MB%d{HH:mm:ss.SSS} [%thread] [%-5p] %c{36}.%M - %m%n192.168.28.32:9251{"appname":"javatool"}
================================================
FILE: codes/linux/soft/elk/config/logstash.conf
================================================
input {
tcp {
port => 9251
codec => json_lines
mode => server
tags => ["javaapp"]
}
}
output {
elasticsearch { hosts => ["localhost:9200"] }
stdout { codec => rubydebug }
}
================================================
FILE: codes/linux/soft/elk/install-elk.sh
================================================
#!/usr/bin/env bash
# 本脚本为一键式安装 ELK 脚本
# 执行脚本前,请先执行以下命令,创建用户
# groupadd elk
# useradd -g elk elk
# passwd elk
# 获取当前设备IP
ipaddr='127.0.0.1'
function getDeviceIp() {
ipaddr=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
}
# 检查文件是否存在,不存在则退出脚本
checkFileExist() {
if [ ! -f "$1" ]
then
echo "关键文件 $1 找不到,脚本执行结束"
exit 0
fi
}
init() {
mkdir -p ${ELASTIC_SOFTWARE_PATH}
getDeviceIp
}
# 安装 elasticsearch
installElasticsearch() {
cd ${ELASTIC_SOFTWARE_PATH}
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-${version}.tar.gz
tar -xzf elasticsearch-${version}.tar.gz
}
installRuby() {
cd ${RUBY_SOFTWARE_PATH}
wget https://cache.ruby-lang.org/pub/ruby/2.5/ruby-2.5.0.tar.gz
tar -xzf ruby-2.5.0.tar.gz
cd ruby-2.5.0
./configure
make & make install
}
# 安装 logstash
installLogstash() {
cd ${ELASTIC_SOFTWARE_PATH}
wget https://artifacts.elastic.co/downloads/logstash/logstash-${version}.tar.gz
tar -xzf logstash-${version}.tar.gz
}
# 安装 kibana
installKibana() {
cd ${ELASTIC_SOFTWARE_PATH}
wget https://artifacts.elastic.co/downloads/kibana/kibana-${version}-linux-x86_64.tar.gz
tar -xzf kibana-${version}-linux-x86_64.tar.gz
}
# 安装 filebeat
installFilebeat() {
cd ${ELASTIC_SOFTWARE_PATH}
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-${version}-linux-x86_64.tar.gz
tar -zxf filebeat-${version}-linux-x86_64.tar.gz
}
# 替换 Elasticsearch 配置
# 1. 替换 192.168.0.1 为本机 IP
replaceElasticsearchConfig() {
cp ${ELASTIC_SOFTWARE_PATH}/elasticsearch-${version}/config/elasticsearch.yml ${ELASTIC_SOFTWARE_PATH}/elasticsearch-${version}/config/elasticsearch.yml.bak
sed -i "s/#network.host: 192.168.0.1/network.host: ${IP}/g" ${ELASTIC_SOFTWARE_PATH}/elasticsearch-${version}/config/elasticsearch.yml
touch ${ELASTIC_SOFTWARE_PATH}/elasticsearch-${version}/bin/nohup.out
}
replaceLogstashConfig() {
cp ${ELASTIC_SOFTWARE_PATH}/logstash-${version}/config/logstash.yml ${ELASTIC_SOFTWARE_PATH}/logstash-${version}/config/logstash.yml.bak
sed -i "s/# http.host: \"127.0.0.1\"/ http.host: ${IP}/g" ${ELASTIC_SOFTWARE_PATH}/logstash-${version}/config/logstash.yml
touch ${ELASTIC_SOFTWARE_PATH}/logstash-${version}/bin/nohup.out
cd ${ELASTIC_SOFTWARE_PATH}/logstash-${version}/bin
wget "https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/elk/config/logstash.conf"
}
# 替换 Kibana 配置
# 1. 替换 localhost 为本机 IP
replaceKibanaConfig() {
cp ${ELASTIC_SOFTWARE_PATH}/kibana-${version}-linux-x86_64/config/kibana.yml ${ELASTIC_SOFTWARE_PATH}/kibana-${version}-linux-x86_64/config/kibana.yml.bak
sed -i "s/#server.host: \"localhost\"/server.host: ${IP}/g" ${ELASTIC_SOFTWARE_PATH}/kibana-${version}-linux-x86_64/config/kibana.yml
sed -i "s/#elasticsearch.url: \"http://localhost:9200\"/#elasticsearch.url: \"${IP}\"/g" ${ELASTIC_SOFTWARE_PATH}/kibana-${version}-linux-x86_64/config/kibana.yml
touch ${ELASTIC_SOFTWARE_PATH}/kibana-${version}-linux-x86_64/bin/nohup.out
}
# 替换 Filebeat 配置
replaceFilebeatConfig() {
cp ${ELASTIC_SOFTWARE_PATH}/filebeat-${version}-linux-x86_64/filebeat.yml ${ELASTIC_SOFTWARE_PATH}/filebeat-${version}-linux-x86_64/filebeat.yml.bak
cd ${ELASTIC_SOFTWARE_PATH}/filebeat-${version}-linux-x86_64
wget https://github.com/dunwu/OS/blob/master/codes/deploy/tool/elk/config/filebeat.yml
sed -i 's/127.0.0.1/'"${IP}"'/g' ${ELASTIC_SOFTWARE_PATH}/filebeat-${version}-linux-x86_64/filebeat.yml
}
# 为 elk.elk 用户设置权限
setPrivilegeForUser() {
chown -R elk.elk ${ELASTIC_SOFTWARE_PATH}
chown -R elk.elk /var/log/
}
######################################## MAIN ########################################
echo -e "\n>>>>>>>>> install elk"
version=6.1.1
RUBY_SOFTWARE_PATH=/opt/ruby
ELASTIC_SOFTWARE_PATH=/opt/elastic
ELASTIC_SETTINGS_PATH=/opt/elastic/settings
init
installElasticsearch
replaceElasticsearchConfig
installLogstash
replaceLogstashConfig
installKibana
replaceKibanaConfig
installFilebeat
replaceFilebeatConfig
# 最后,将启动脚本下载到本地
mkdir -p /home/zp/script
wget -P /home/zp/script "https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/elk/boot-elk.sh"
#setPrivilegeForUser
================================================
FILE: codes/linux/soft/elk/install_elasticserch.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# version:v1.0
# func:elasticsearch 5.4.1/6.0.1/6.3.1安装
# 定义安装目录、及日志信息
. /etc/init.d/functions
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
download_path=/tmp/tmpdir/
install_log_name=install_elasticsearch.log
env_file=/etc/profile.d/elasticsearch.sh
install_log_path=/var/log/appinstall/
install_path=/usr/local/
software_config_file=${install_path}elasticsearch/config/elasticsearch.yml
sysversion=$(rpm -q centos-release | cut -d- -f3)
jvm_conf="/usr/local/elasticsearch/config/jvm.options"
sys_mem=`free -m | grep Mem: | awk '{print $2}' | awk '{sum+=$1} END {print sum/1024}' | cut -d. -f1`
hostname=elk-server
clear
echo "##########################################"
echo "# #"
echo "# 安装 elasticsearch 5.4.1/6.0.1/6.3.1 #"
echo "# #"
echo "##########################################"
echo "1: Install elasticsearch 5.4.1"
echo "2: Install elasticsearch 6.0.1"
echo "3: Install elasticsearch 6.3.1"
echo "4: EXIT"
# 选择安装软件版本
read -p "Please input your choice:" softversion
if [ "${softversion}" == "1" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/elasticsearch/elasticsearch-5.4.1.tar.gz"
elif [ "${softversion}" == "2" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/elasticsearch/elasticsearch-6.0.1.tar.gz"
elif [ "${softversion}" == "3" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/elasticsearch/elasticsearch-6.3.1.tar.gz"
elif [ "${softversion}" == "4" ]; then
echo "you choce channel!"
exit 1;
else
echo "input Error! Place input{1|2|3|4|5}"
exit 0;
fi
# 传入内容,格式化内容输出,可以传入多个参数,用空格隔开
output_msg() {
for msg in $*; do
action $msg /bin/true
done
}
# 判断命令是否存在,第一个参数 $1 为判断的命令,第二个参数为提供该命令的yum 软件包名称
check_yum_command() {
output_msg "命令检查:$1"
hash $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` check command $1 " >> ${install_log_path}${install_log_name} && return 0
else
yum -y install $2 > /dev/null 2>&1
# hash $Command || { echo "`date +%F' '%H:%M:%S` $2 is installed fail">>${install_log_path}${install_log_name} ; exit 1 }
fi
}
# 判断目录是否存在,传入目录绝对路径,可以传入多个目录
check_dir() {
output_msg "目录检查"
for dirname in $*; do
[ -d $dirname ] || mkdir -p $dirname > /dev/null 2>&1
echo "`date +%F' '%H:%M:%S` $dirname check success!" >> ${install_log_path}${install_log_name}
done
}
# 下载文件并解压至安装目录,传入url链接地址
download_file() {
output_msg "下载源码包"
mkdir -p $download_path
for file in $*; do
wget $file -c -P $download_path &> /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $file download success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` $file download fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 解压文件,可以传入多个压缩文件绝对路径,用空格隔开,解压至安装目录
extract_file() {
output_msg "解压源码"
for file in $*; do
if [ "${file##*.}" == "gz" ]; then
tar -zxf $file -C $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
elif [ "${file##*.}" == "zip" ]; then
unzip -q $file -d $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%S` $file type error, extrac fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 配置环境变量,第一个参数为添加环境变量的绝对路径
config_env() {
output_msg "环境变量配置"
echo "export PATH=\$PATH:$1" > ${env_file}
source ${env_file} && echo "`date +%F' '%H:%M:%S` 软件安装完成!" >> ${install_log_path}${install_log_name}
}
# 配置主机名,第一个为主机名
config_hostname() {
if [ ${sysversion} -eq 6 ]; then
hostname $1
elif [ ${sysversion} -eq 7 ]; then
hostnamectl set-hostname $1
else
echo "`date +%F' '%H:%M:%S` hostname $1 config fail" >> ${install_log_path}${install_log_name}
fi
}
config_limits() {
output_msg "配置limits"
cat >> /etc/security/limits.conf << EOF
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
EOF
echo "vm.max_map_count = 655360" >> /etc/sysctl.conf
sysctl -p > /dev/null 2>&1
}
# 添加配置文件
add_config() {
cat > $1 << EOF
cluster.name: my-application
node.name: ${hostname}
path.data: /usr/local/elasticsearch/data
path.logs: /usr/local/elasticsearch/logs
network.host: 127.0.0.1
http.port: 9200
discovery.zen.ping.unicast.hosts: ["$hostname"]
EOF
}
config_user() {
useradd $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $1 user add success" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%S` $1 user add fail" >> ${install_log_path}${install_log_name} && exit 1
fi
chown ${1}.${1} ${install_path}elasticsearch/ -R
}
config_jvm() {
if [ ${sys_mem} -eq 0 ]; then
sed -i "s#`grep "^-Xmx" ${jvm_conf}`#"-Xmx512m"#g" ${jvm_conf}
sed -i "s#`grep "^-Xms" ${jvm_conf}`#"-Xms512m"#g" ${jvm_conf}
else
sed -i "s#`grep "^-Xmx" ${jvm_conf}`#"-Xmx${sys_mem}g"#g" ${jvm_conf}
sed -i "s#`grep "^-Xms" ${jvm_conf}`#"-Xms${sys_mem}g"#g" ${jvm_conf}
fi
}
main() {
check_dir $install_log_path $install_path
check_yum_command wget wget
download_file $URL
config_hostname $hostname
software_name=$(echo $URL | awk -F'/' '{print $NF}' | awk -F'.tar.gz' '{print $1}')
for filename in `ls $download_path`; do
extract_file ${download_path}$filename
done
rm -fr ${download_path}
ln -s $install_path$software_name ${install_path}elasticsearch
add_config $software_config_file
check_dir ${install_path}elasticsearch/{data,logs}
config_user elasticsearch
config_env ${install_path}elasticsearch/bin
config_limits
config_jvm
echo "请使用一下命令启动服务:'su - elasticsearch -c 'nohup /usr/local/elasticsearch/bin/elasticsearch &'"
}
main
================================================
FILE: codes/linux/soft/elk/install_filebeat.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# version:v1.0
# func:filebeat 5.6.1/6.1.3/6.3.2 安装
# 定义安装目录、及日志信息
. /etc/init.d/functions
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
download_path=/tmp/tmpdir/
install_log_name=install_filebeat.log
env_file=/etc/profile.d/filebeat.sh
install_log_path=/var/log/appinstall/
install_path=/usr/local/
software_config_file=${install_path}filebeat/filebeat.yml
clear
echo "##########################################"
echo "# #"
echo "# 安装 filebeat 5.6.1/6.1.3/6.3.2 #"
echo "# #"
echo "##########################################"
echo "1: Install filebeat 5.6.1"
echo "2: Install filebeat 6.1.3"
echo "3: Install filebeat 6.3.2"
echo "4: EXIT"
# 选择安装软件版本
read -p "Please input your choice:" softversion
if [ "${softversion}" == "1" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/filebeat/filebeat-5.6.1-linux-x86_64.tar.gz"
elif [ "${softversion}" == "2" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/filebeat/filebeat-6.1.3-linux-x86_64.tar.gz"
elif [ "${softversion}" == "3" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/filebeat/filebeat-6.3.2-linux-x86_64.tar.gz"
elif [ "${softversion}" == "4" ]; then
echo "you choce channel!"
exit 1;
else
echo "input Error! Place input{1|2|3|4}"
exit 0;
fi
# 传入内容,格式化内容输出,可以传入多个参数,用空格隔开
output_msg() {
for msg in $*; do
action $msg /bin/true
done
}
# 判断命令是否存在,第一个参数 $1 为判断的命令,第二个参数为提供该命令的yum 软件包名称
check_yum_command() {
output_msg "命令检查:$1"
hash $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` check command $1 " >> ${install_log_path}${install_log_name} && return 0
else
yum -y install $2 > /dev/null 2>&1
# hash $Command || { echo "`date +%F' '%H:%M:%S` $2 is installed fail">>${install_log_path}${install_log_name} ; exit 1 }
fi
}
# 判断目录是否存在,传入目录绝对路径,可以传入多个目录
check_dir() {
output_msg "目录检查"
for dirname in $*; do
[ -d $dirname ] || mkdir -p $dirname > /dev/null 2>&1
echo "`date +%F' '%H:%M:%S` $dirname check success!" >> ${install_log_path}${install_log_name}
done
}
# 下载文件并解压至安装目录,传入url链接地址
download_file() {
output_msg "下载源码包"
mkdir -p $download_path
for file in $*; do
wget $file -c -P $download_path &> /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $file download success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` $file download fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 解压文件,可以传入多个压缩文件绝对路径,用空格隔开,解压至安装目录
extract_file() {
output_msg "解压源码"
for file in $*; do
if [ "${file##*.}" == "gz" ]; then
tar -zxf $file -C $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
elif [ "${file##*.}" == "zip" ]; then
unzip -q $file -d $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%S` $file type error, extrac fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 配置环境变量,第一个参数为添加环境变量的绝对路径
config_env() {
output_msg "环境变量配置"
echo "export PATH=\$PATH:$1" > ${env_file}
source ${env_file} && echo "`date +%F' '%H:%M:%S` 软件安装完成!" >> ${install_log_path}${install_log_name}
}
# 添加配置文件
add_config() {
cat > $1 << EOF
filebeat.prospectors:
- input_type: log
paths:
- /var/log/*.log
output.logstash:
hosts: ["127.0.0.1:5044"]
EOF
}
main() {
check_dir $install_log_path $install_path
check_yum_command wget wget
download_file $URL
software_name=$(echo $URL | awk -F'/' '{print $NF}' | awk -F'.tar.gz' '{print $1}')
for filename in `ls $download_path`; do
extract_file ${download_path}$filename
done
rm -fr ${download_path}
ln -s $install_path$software_name ${install_path}filebeat
add_config ${software_config_file}
}
main
================================================
FILE: codes/linux/soft/elk/install_kibana.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# version:v1.0
# func:kibana 6.0.1/6.2.4/6.3.1 安装
# 定义安装目录、及日志信息
. /etc/init.d/functions
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
download_path=/tmp/tmpdir/
install_log_name=install_kibana.log
env_file=/etc/profile.d/kibana.sh
install_log_path=/var/log/appinstall/
install_path=/usr/local/
software_config_file=${install_path}kibana/config/kibana.yml
clear
echo "##########################################"
echo "# #"
echo "# 安装 kibana 6.0.1/6.2.4/6.3.1 #"
echo "# #"
echo "##########################################"
echo "1: Install kibana 6.0.1"
echo "2: Install kibana 6.2.4"
echo "3: Install kibana 6.3.1"
echo "4: EXIT"
# 选择安装软件版本
read -p "Please input your choice:" softversion
if [ "${softversion}" == "1" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/kibana/kibana-6.0.1-linux-x86_64.tar.gz"
elif [ "${softversion}" == "2" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/kibana/kibana-6.2.4-linux-x86_64.tar.gz"
elif [ "${softversion}" == "3" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/kibana/kibana-6.3.1-linux-x86_64.tar.gz"
elif [ "${softversion}" == "4" ]; then
echo "you choce channel!"
exit 1;
else
echo "input Error! Place input{1|2|3|4}"
exit 0;
fi
# 传入内容,格式化内容输出,可以传入多个参数,用空格隔开
output_msg() {
for msg in $*; do
action $msg /bin/true
done
}
# 判断命令是否存在,第一个参数 $1 为判断的命令,第二个参数为提供该命令的yum 软件包名称
check_yum_command() {
output_msg "命令检查:$1"
hash $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` check command $1 " >> ${install_log_path}${install_log_name} && return 0
else
yum -y install $2 > /dev/null 2>&1
# hash $Command || { echo "`date +%F' '%H:%M:%S` $2 is installed fail">>${install_log_path}${install_log_name} ; exit 1 }
fi
}
# 判断目录是否存在,传入目录绝对路径,可以传入多个目录
check_dir() {
output_msg "目录检查"
for dirname in $*; do
[ -d $dirname ] || mkdir -p $dirname > /dev/null 2>&1
echo "`date +%F' '%H:%M:%S` $dirname check success!" >> ${install_log_path}${install_log_name}
done
}
# 下载文件并解压至安装目录,传入url链接地址
download_file() {
output_msg "下载源码包"
mkdir -p $download_path
for file in $*; do
wget $file -c -P $download_path &> /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $file download success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` $file download fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 解压文件,可以传入多个压缩文件绝对路径,用空格隔开,解压至安装目录
extract_file() {
output_msg "解压源码"
for file in $*; do
if [ "${file##*.}" == "gz" ]; then
tar -zxf $file -C $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
elif [ "${file##*.}" == "zip" ]; then
unzip -q $file -d $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%S` $file type error, extrac fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 配置环境变量,第一个参数为添加环境变量的绝对路径
config_env() {
output_msg "环境变量配置"
echo "export PATH=\$PATH:$1" > ${env_file}
source ${env_file} && echo "`date +%F' '%H:%M:%S` 软件安装完成!" >> ${install_log_path}${install_log_name}
}
# 添加配置文件
add_config() {
cat > $1 << EOF
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.url: "http://127.0.0.1:9200"
EOF
}
main() {
check_dir $install_log_path $install_path
check_yum_command wget wget
download_file $URL
software_name=$(echo $URL | awk -F'/' '{print $NF}' | awk -F'.tar.gz' '{print $1}')
for filename in `ls $download_path`; do
extract_file ${download_path}$filename
done
rm -fr ${download_path}
ln -s ${install_path}$software_name ${install_path}kibana
add_config ${software_config_file}
config_env ${install_path}kibana/bin
}
main
================================================
FILE: codes/linux/soft/elk/install_logstash.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# version:v1.0
# func:logstash 5.4/6.1/6.3 安装
# 定义安装目录、及日志信息
. /etc/init.d/functions
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
download_path=/tmp/tmpdir/
install_log_name=install_logstash.log
env_file=/etc/profile.d/logstash.sh
install_log_path=/var/log/appinstall/
install_path=/usr/local/
software_config_file=${install_path}logstash/config/01-syslog.conf
clear
echo "##########################################"
echo "# #"
echo "# 安装 logstash 5.4/6.1/6.3 #"
echo "# #"
echo "##########################################"
echo "1: Install logstash-5.4"
echo "2: Install logstash-6.1"
echo "3: Install logstash-6.3"
echo "4: EXIT"
# 选择安装软件版本
read -p "Please input your choice:" softversion
if [ "${softversion}" == "1" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/logstash/logstash-5.4.1.tar.gz"
elif [ "${softversion}" == "2" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/logstash/logstash-6.1.3.tar.gz"
elif [ "${softversion}" == "3" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/logstash/logstash-6.3.2.tar.gz"
elif [ "${softversion}" == "4" ]; then
echo "you choce channel!"
exit 1;
else
echo "input Error! Place input{1|2|3|4}"
exit 0;
fi
# 传入内容,格式化内容输出,可以传入多个参数,用空格隔开
output_msg() {
for msg in $*; do
action $msg /bin/true
done
}
# 判断命令是否存在,第一个参数 $1 为判断的命令,第二个参数为提供该命令的yum 软件包名称
check_yum_command() {
output_msg "命令检查:$1"
hash $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` check command $1 " >> ${install_log_path}${install_log_name} && return 0
else
yum -y install $2 > /dev/null 2>&1
# hash $Command || { echo "`date +%F' '%H:%M:%S` $2 is installed fail">>${install_log_path}${install_log_name} ; exit 1 }
fi
}
# 判断目录是否存在,传入目录绝对路径,可以传入多个目录
check_dir() {
output_msg "目录检查"
for dirname in $*; do
[ -d $dirname ] || mkdir -p $dirname > /dev/null 2>&1
echo "`date +%F' '%H:%M:%S` $dirname check success!" >> ${install_log_path}${install_log_name}
done
}
# 下载文件并解压至安装目录,传入url链接地址
download_file() {
output_msg "下载源码包"
mkdir -p $download_path
for file in $*; do
wget $file -c -P $download_path &> /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $file download success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` $file download fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 解压文件,可以传入多个压缩文件绝对路径,用空格隔开,解压至安装目录
extract_file() {
output_msg "解压源码"
for file in $*; do
if [ "${file##*.}" == "gz" ]; then
tar -zxf $file -C $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
elif [ "${file##*.}" == "zip" ]; then
unzip -q $file -d $install_path && echo "`date +%F' '%H:%M:%S` $file extrac success!,path is $install_path" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%S` $file type error, extrac fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 配置环境变量,第一个参数为添加环境变量的绝对路径
config_env() {
output_msg "环境变量配置"
echo "export PATH=\$PATH:$1" > ${env_file}
source ${env_file} && echo "`date +%F' '%H:%M:%S` 软件安装完成!" >> ${install_log_path}${install_log_name}
}
# 添加配置文件
add_config() {
cat > $1 << EOF
input {
beats {
port => "5044"
}
}
output {
elasticsearch {
hosts => "127.0.0.1:9200"
}
stdout { codec => rubydebug }
}
EOF
}
main() {
check_dir $install_log_path $install_path
check_yum_command wget wget
download_file $URL
software_name=$(echo $URL | awk -F'/' '{print $NF}' | awk -F'.tar.gz' '{print $1}')
for filename in `ls $download_path`; do
extract_file ${download_path}$filename
done
rm -fr ${download_path}
ln -s $install_path$software_name ${install_path}logstash
add_config ${software_config_file}
config_env ${install_path}logstash/bin
}
main
================================================
FILE: codes/linux/soft/fastdfs-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# install FastDFS 脚本
# FastDFS 会被install到 /opt/fdfs 路径。
# @system: 适用于 CentOS
# @author: Zhang Peng
# @ses: https://github.com/happyfish100/fastdfs/wiki
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install fastdfs begin.${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "${RED}Require yum but it's not installed.${RESET}\n";
exit 1;
}
command -v git > /dev/null 2>&1 || {
printf "${RED}Require git but it's not installed.${RESET}\n";
exit 1;
}
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh fastdfs-install.sh [path]\n"
printf "\t Example: sh fastdfs-install.sh /opt/fastdfs\n"
printf "${RESET}\n"
fi
path=/opt/fdfs
if [[ -n $1 ]]; then
path=$1
fi
nginx_version=1.16.0
nginx_path=/opt/nginx
printf "${GREEN}>>>>>>>> install required libs.${RESET}\n\n"
yum install -y git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim unzip
# download and decompression
mkdir -p ${path}
path=/opt/fdfs
mkdir -p ${path}/libfastcommon
curl -o ${path}/libfastcommon.zip http://dunwu.test.upcdn.net/soft/fdfs/libfastcommon.zip
if [[ ! -f ${path}/libfastcommon.zip ]]; then
printf "${RED}[Error]install libfastcommon failed,exit. ${RESET}\n"
exit 1
fi
unzip -o ${path}/libfastcommon.zip -d ${path}
cd ${path}/libfastcommon
chmod +x -R ${path}/libfastcommon/*.sh
./make.sh && ./make.sh install
printf "${GREEN}>>>>>>>>> install fastdfs${RESET}"
mkdir -p ${path}/fastdfs
curl -o ${path}/fastdfs.zip http://dunwu.test.upcdn.net/soft/fdfs/fastdfs.zip
if [[ ! -f ${path}/fastdfs.zip ]]; then
printf "${RED}>>>>>>>>> install fastdfs failed,exit. ${RESET}\n"
fi
unzip -o ${path}/fastdfs.zip -d ${path}
cd ${path}/fastdfs
chmod +x -R ${path}/fastdfs/*.sh
./make.sh && ./make.sh install
printf "${GREEN}>>>>>>>>> install fastdfs-nginx-module${RESET}\n"
mkdir -p ${path}/fastdfs-nginx-module
curl -o ${path}/fastdfs-nginx-module.zip http://dunwu.test.upcdn.net/soft/fdfs/fastdfs-nginx-module.zip
if [[ ! -f ${path}/fastdfs-nginx-module.zip ]]; then
printf "${RED}>>>>>>>>> install fastdfs-nginx-module failed,exit. ${RESET}\n"
fi
unzip -o ${path}/fastdfs-nginx-module.zip -d ${path}
printf "${GREEN}>>>>>>>>> install nginx${RESET}"
mkdir -p ${nginx_path}
curl -o ${nginx_path}/nginx-${nginx_version}.tar.gz http://nginx.org/download/nginx-${nginx_version}.tar.gz
tar zxf ${nginx_path}/nginx-${nginx_version}.tar.gz -C ${nginx_path}
cd ${nginx_path}/nginx-${nginx_version}
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre --add-module=${path}/fastdfs-nginx-module/src/
make && make install
printf "${GREEN}>>>>>>>>> fastdfs 配置文件准备${RESET}\n"
# 配置修改参考:https://github.com/happyfish100/fastdfs/wiki
mkdir -p /etc/fdfs
cp ${path}/fastdfs/conf/http.conf /etc/fdfs/ #供nginx访问使用
cp ${path}/fastdfs/conf/mime.types /etc/fdfs/ #供nginx访问使用
cp ${path}/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/fastdfs/tracker.conf -O /etc/fdfs/tracker.conf
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/fastdfs/storage.conf -O /etc/fdfs/storage.conf
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/fastdfs/client.conf -O /etc/fdfs/client.conf
# fdfs 存储路径和服务端口(以默认形式配置)
fdfs_store_path=/home/fdfs
fdfs_server_port=7001
ip=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
mkdir -p ${fdfs_store_path}
printf "${GREEN} - 修改 tracker.conf 配置${RESET}\n"
sed -i "s#^base_path=.*#base_path=${fdfs_store_path}#g" /etc/fdfs/tracker.conf
printf "${GREEN} - 修改 storage.conf 配置${RESET}\n"
sed -i "s#^base_path=.*#base_path=${fdfs_store_path}#g" /etc/fdfs/storage.conf
sed -i "s#^store_path0=.*#store_path0=${fdfs_store_path}#g" /etc/fdfs/storage.conf
sed -i "s#^tracker_server=.*#tracker_server=${ip}:22122#g" /etc/fdfs/storage.conf
sed -i "s#^http.server_port=.*#http.server_port=${fdfs_server_port}#g" /etc/fdfs/storage.conf
printf "${GREEN} - 修改 client.conf 配置${RESET}\n"
sed -i "s#^base_path=.*#base_path=${fdfs_store_path}#g" /etc/fdfs/client.conf
sed -i "s#^tracker_server=.*#tracker_server=${ip}:22122#g" /etc/fdfs/client.conf
printf "${GREEN} - 修改 mod_fastdfs.conf 配置${RESET}\n"
sed -i "s#^url_have_group_name=.*#url_have_group_name=true#g" /etc/fdfs/mod_fastdfs.conf
sed -i "s#^tracker_server=.*#tracker_server=${ip}:22122#g" /etc/fdfs/mod_fastdfs.conf
sed -i "s#^store_path0=.*#store_path0=${fdfs_store_path}#g" /etc/fdfs/mod_fastdfs.conf
printf "${GREEN} - 修改 nginx.conf 配置${RESET}\n"
mkdir -p /usr/local/nginx/conf/conf
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/nginx/nginx.conf -O /usr/local/nginx/conf/nginx.conf
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/nginx/conf/fdfs.conf -O /usr/local/nginx/conf/conf/fdfs.conf
printf "${GREEN}>>>>>>>>> 启动 fastdfs ${RESET}\n"
chmod +x /etc/init.d/fdfs_trackerd
/etc/init.d/fdfs_trackerd start #启动tracker服务
#/etc/init.d/fdfs_trackerd restart #重启动tracker服务
#/etc/init.d/fdfs_trackerd stop #停止tracker服务
chkconfig fdfs_trackerd on #自启动tracker服务
chmod +x /etc/init.d/fdfs_storaged
/etc/init.d/fdfs_storaged start #启动storage服务
#/etc/init.d/fdfs_storaged restart #重动storage服务
#/etc/init.d/fdfs_storaged stop #停止动storage服务
chkconfig fdfs_storaged on #自启动storage服务
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/nginx/nginx.service -O /usr/lib/systemd/system/nginx.service
chmod +x /usr/lib/systemd/system/nginx.service
#设置nginx.service为系统服务
systemctl enable nginx.service
##通过系统服务操作nginx
systemctl start nginx.service
#systemctl reload nginx.service
#systemctl restart nginx.service
#systemctl stop nginx.service
printf ">>>>>>>>> add fastdfs port"
firewall-cmd --zone=public --add-port=${fdfs_server_port}/tcp --permanent
firewall-cmd --zone=public --add-port=22122/tcp --permanent
firewall-cmd --reload
printf "${GREEN}<<<<<<<< install fastdfs end.${RESET}\n"
#touch test.txt
#result=`fdfs_upload_file /etc/fdfs/client.conf test.txt`
#echo ${result}
#rm -f test.txt
================================================
FILE: codes/linux/soft/gitlab/gitlab-backup.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Gitlab 操作脚本
# 支持操作:
# 备份 Gitlab
# 恢复 Gitlab
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Gilab 操作的环境变量,使用方法:
# 可以在执行本脚本之前,export 以下环境变量,否则将按照默认配置执行
# Gitlab 备份文件最大数量(默认为 7 天)
export ENV_BACKUP_MAX_NUM=7
# 备份路径
export ENV_GITLAB_BACKUP_DIR="/var/opt/gitlab/backups"
# 备份日志路径
export ENV_LOG_PATH="${ENV_GITLAB_BACKUP_DIR}/gitlab-backup.log"
ENV_REMOTE_USER=root
ENV_REMOTE_HOST=172.22.6.42
# ------------------------------------------------------------------------------ load libs
GIT_SCRIPTS_DIR=$(cd `dirname $0`; pwd)
if [[ ! -x ${GIT_SCRIPTS_DIR}/gitlab.sh ]]; then
echo "${GIT_SCRIPTS_DIR}/gitlab.sh not exists!"
exit 1
fi
source ${GIT_SCRIPTS_DIR}/gitlab.sh
# ------------------------------------------------------------------------------ functions
backupGitlab
if [[ "$?" != ${ENV_SUCCEED} ]]; then
printError "退出"
exit ${ENV_FAILED}
fi
#将备份文件传输到gitlab备份服务器
BACKUP_FILE=$(find "${ENV_GITLAB_BACKUP_DIR}" -type f -name "*gitlab_backup.tar" | xargs ls -t | head -1)
scp ${BACKUP_FILE} ${ENV_REMOTE_USER}@${ENV_REMOTE_HOST}:${ENV_GITLAB_BACKUP_DIR}
================================================
FILE: codes/linux/soft/gitlab/gitlab.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Gitlab 操作脚本
# 支持操作:
# 备份 Gitlab
# 恢复 Gitlab
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "$@"
return ${ENV_SUCCEED}
else
printError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ env
# Gilab 操作的环境变量,使用方法:
# 可以在执行本脚本之前,export 以下环境变量,否则将按照默认配置执行
# Gitlab 备份文件最大数量(默认为 7 天)
ENV_BACKUP_MAX_NUM=${ENV_BACKUP_MAX_NUM:-2}
# 备份路径
ENV_GITLAB_BACKUP_DIR="${ENV_GITLAB_BACKUP_DIR:-/var/opt/gitlab/backups}"
# 备份日志路径
ENV_LOG_PATH="${ENV_GITLAB_BACKUP_DIR}/gitlab-backup.log"
magentaOutput "------------------------------------------------------------------------------"
magentaOutput "Gitlab 脚本操作环境变量:"
magentaOutput "ENV_BACKUP_MAX_NUM:${ENV_BACKUP_MAX_NUM}"
magentaOutput "ENV_GITLAB_BACKUP_DIR:${ENV_GITLAB_BACKUP_DIR}"
magentaOutput "ENV_LOG_PATH:${ENV_LOG_PATH}"
magentaOutput "------------------------------------------------------------------------------"
# ------------------------------------------------------------------------------ functions
# 安装 Gitlab
installGitlab() {
# 官方安裝參考:https://about.gitlab.com/install/#centos-7
printInfo ">>>> install gitlab on Centos7"
printInfo ">>>> Install and configure the necessary dependencies"
yum install -y curl policycoreutils-python openssh-server
systemctl enable sshd
systemctl start sshd
printInfo ">>>> open http, https and ssh access in the system firewall"
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo systemctl reload firewalld
printInfo ">>>> install postfix"
yum install postfix
systemctl enable postfix
systemctl start postfix
printInfo ">>>> Add the GitLab package repository and install the package"
curl -o- https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | bash
EXTERNAL_URL="http://gitlab.transwarp.io" yum install -y gitlab-ce
}
# 备份 Gitlab
backupGitlab() {
#时间戳
local beginTime=$(date +'%Y-%m-%d %H:%M:%S')
#备份所有数据库
printInfo ">>>> 备份 Gitlab 开始"
gitlab-rake gitlab:backup:create >> ${ENV_LOG_PATH};
#检查备份结果是否成功
if [[ "$?" != ${ENV_SUCCEED} ]]; then
printError "<<<< 备份 Gitlab 失败"
return ${ENV_FAILED}
fi
# 压缩备份sql文件,删除旧的备份文件
cd "${ENV_GITLAB_BACKUP_DIR}"
#只保存期限内的备份文件,其余删除
find "${ENV_GITLAB_BACKUP_DIR} -name *_gitlab_backup.tar -type f -mtime +${ENV_BACKUP_MAX_NUM} -exec rm -rf {} \;" > /dev/null 2>&1
local endTime=$(date +'%Y-%m-%d %H:%M:%S')
local beginSeconds=$(date --date="${beginTime}" +%s)
local endSeconds=$(date --date="${endTime}" +%s)
printInfo "本次备份执行时间:$((endSeconds-beginSeconds)) s"
printInfo "<<<< 备份 Gitlab 成功\n"
return ${ENV_SUCCEED}
}
# 恢复 Mysql
recoveryGitlab() {
local version=$1
if [[ !version ]]; then
printError "<<<< 未指定恢复版本"
return ${ENV_FAILED}
fi
#创建备份目录及日志文件
mkdir -p ${ENV_GITLAB_BACKUP_DIR}
if [[ ! -f ${ENV_LOG_PATH} ]]; then
touch ${ENV_LOG_PATH}
fi
printInfo ">>>> 恢复 Gitlab 开始"
gitlab-ctl stop unicorn
gitlab-ctl stop sidekiq
gitlab-rake gitlab:backup:restore BACKUP=${version}
if [[ "$?" != 0 ]]; then
printError "<<<< 恢复 Gitlab 失败"
return ${ENV_FAILED}
fi
printInfo "<<<< 恢复 Gitlab 成功\n"
return ${ENV_SUCCEED}
}
================================================
FILE: codes/linux/soft/gitlab-install.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Gitlab 安装脚本
# 仅适用于 CentOS7 发行版本
# 官方安裝參考:https://about.gitlab.com/install/#centos-7
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "$@"
return ${ENV_SUCCEED}
else
printError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ main
# 官方安裝參考:https://about.gitlab.com/install/#centos-7
printInfo ">>>> install gitlab on Centos7"
printInfo ">>>> Install and configure the necessary dependencies"
yum install -y curl policycoreutils-python openssh-server
systemctl enable sshd
systemctl start sshd
printInfo ">>>> open http, https and ssh access in the system firewall"
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo systemctl reload firewalld
printInfo ">>>> install postfix"
yum install postfix
systemctl enable postfix
systemctl start postfix
printInfo ">>>> Add the GitLab package repository and install the package"
curl -o- https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | bash
EXTERNAL_URL="http://gitlab.transwarp.io" yum install -y gitlab-ce
================================================
FILE: codes/linux/soft/install_grafana.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# version:v1.0
# func:grafana 5.1.0/5.1.5/5.2.2 安装
# 定义安装目录、及日志信息
. /etc/init.d/functions
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
download_path=/tmp/tmpdir/
install_log_name=install_grafana.log
env_file=/etc/profile.d/grafana.sh
install_log_path=/var/log/appinstall/
install_path=/usr/local/
clear
echo "##########################################"
echo "# #"
echo "# 安装 grafana 5.1.0/5.1.5/5.2.2 #"
echo "# #"
echo "##########################################"
echo "1: Install grafana 5.1.0"
echo "2: Install grafana 5.1.5"
echo "3: Install grafana 5.2.2"
echo "4: EXIT"
# 选择安装软件版本
read -p "Please input your choice:" softversion
if [ "${softversion}" == "1" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/grafana/grafana-5.1.0-1.x86_64.rpm"
elif [ "${softversion}" == "2" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/grafana/grafana-5.1.5-1.x86_64.rpm"
elif [ "${softversion}" == "3" ]; then
URL="https://anchnet-script.oss-cn-shanghai.aliyuncs.com/grafana/grafana-5.2.2-1.x86_64.rpm"
elif [ "${softversion}" == "4" ]; then
echo "you choce channel!"
exit 1;
else
echo "input Error! Place input{1|2|3|4}"
exit 0;
fi
# 传入内容,格式化内容输出,可以传入多个参数,用空格隔开
output_msg() {
for msg in $*; do
action $msg /bin/true
done
}
# 判断命令是否存在,第一个参数 $1 为判断的命令,第二个参数为提供该命令的yum 软件包名称
check_yum_command() {
output_msg "命令检查:$1"
hash $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` check command $1 " >> ${install_log_path}${install_log_name} && return 0
else
yum -y install $2 > /dev/null 2>&1
# hash $Command || { echo "`date +%F' '%H:%M:%S` $2 is installed fail">>${install_log_path}${install_log_name} ; exit 1 }
fi
}
# 判断目录是否存在,传入目录绝对路径,可以传入多个目录
check_dir() {
output_msg "目录检查"
for dirname in $*; do
[ -d $dirname ] || mkdir -p $dirname > /dev/null 2>&1
echo "`date +%F' '%H:%M:%S` $dirname check success!" >> ${install_log_path}${install_log_name}
done
}
# 下载文件并解压至安装目录,传入url链接地址
download_file() {
output_msg "下载源码包"
mkdir -p $download_path
for file in $*; do
wget $file -c -P $download_path &> /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` $file download success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` $file download fail!" >> ${install_log_path}${install_log_name} && exit 1
fi
done
}
# 安装grafana插件,传入安装的插件的名称
install_grafana_plugins() {
output_msg "grafana插件安装"
check_yum_command grafana-cli
grafana-cli plugins install $* > /dev/null
if [ $? -eq 0 ]; then
echo "`date +%F' '%H:%M:%S` grafana plugins $* install success!" >> ${install_log_path}${install_log_name}
else
echo "`date +%F' '%H:%M:%s` grafana plugins $* install success!" >> ${install_log_path}${install_log_name} && exit 1
fi
}
main() {
check_dir $install_log_path $install_path
check_yum_command wget wget
download_file $URL
for filename in `ls $download_path`; do
yum -y install $download_path$filename > /dev/null 2>&1
done
install_grafana_plugins alexanderzobnin-zabbix-app
}
main
================================================
FILE: codes/linux/soft/jdk8-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 JDK8 脚本
# JDK 会被安装到 /usr/lib/jvm/java 路径。
# @system: 适用于 CentOS
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install jdk8 begin.${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "${RED}Require yum but it's not installed.${RESET}\n";
exit 1;
}
yum -y install java-1.8.0-openjdk-devel.x86_64
java -version
printf "${GREEN}<<<<<<<< install jdk8 end.${RESET}\n"
================================================
FILE: codes/linux/soft/jenkins-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 安装 Jenkins 脚本
# 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
echo -e "\n>>>>>>>>> install jenkins"
# 下载并解压 jenkins
mkdir -p /opt/jenkins
curl -o /opt/jenkins/jenkins.war http://mirrors.jenkins.io/war-stable/latest/jenkins.war
================================================
FILE: codes/linux/soft/kafka-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 Kafka 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install kafka begin.${RESET}\n"
command -v java > /dev/null 2>&1 || {
printf "${RED}Require java but it's not installed.${RESET}\n";
exit 1;
}
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh kafka-install.sh [version] [path]\n"
printf "\t Example: sh kafka-install.sh 2.2.0 /opt/kafka\n"
printf "${RESET}\n"
fi
version=2.2.0
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/kafka
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
curl -o ${path}/kafka_2.12-${version}.tgz http://mirrors.tuna.tsinghua.edu.cn/apache/kafka/${version}/kafka_2.12-${version}.tgz
tar zxf ${path}/kafka_2.12-${version}.tgz -C ${path}
printf "${GREEN}<<<<<<<< install kafka end.${RESET}\n"
================================================
FILE: codes/linux/soft/lib/docker.sh
================================================
#!/usr/bin/env bash
LINUX_SCRIPTS_LIB_DIR=`dirname ${BASH_SOURCE[0]}`
source ${LINUX_SCRIPTS_LIB_DIR}/utils.sh
dockerBuild() {
if [[ ! $1 ]] || [[ ! $2 ]] || [[ ! $3 ]]; then
logError "you must input following params in order:"
echo -e "${ENV_COLOR_B_RED}"
echo " (1) source"
echo " (2) repository"
echo " (3) tag"
echo -e "\nEg. dockerBuild /home/workspace tdh60dev01:5000/fide/fide-processor fide-0.0.6-SNAPSHOT"
echo -e "${ENV_COLOR_RESET}"
return ${ENV_FAILED}
fi
local source=$1
local repository=$2
local tag=$3
dockerCheck ${source}
if [[ "${ENV_SUCCEED}" != "$?" ]]; then
return ${ENV_FAILED}
fi
cd ${source}
callAndLog docker build -t ${repository}:${tag} .
if [[ "${ENV_SUCCEED}" != "$?" ]]; then
logError "docker build -t ${repository}:${tag} failed"
return ${ENV_FAILED}
fi
cd -
}
dockerPush() {
if [[ ! $1 ]] || [[ ! $2 ]]; then
logError "you must input following params in order:"
echo -e "${ENV_COLOR_B_RED}"
echo " (1) repository"
echo " (2) tag"
echo -e "\nEg. dockerBuild tdh60dev01:5000/fide/fide-processor fide-0.0.6-SNAPSHOT"
echo -e "${ENV_COLOR_RESET}"
return ${ENV_FAILED}
fi
local repository=$1
local tag=$2
local dockerHashId=$(docker image ls | grep ${repository} | grep ${tag} | awk '{print $3}')
if [[ ! ${dockerHashId} ]]; then
logInfo "try to delete existed image: ${repository}:${tag}"
callAndLog docker rmi ${dockerHashId}
fi
logInfo "try to push new image: ${repository}:${tag}"
callAndLog docker push ${repository}:${tag}
}
# check Dockerfile
# @param $1: project path
dockerCheck() {
local source=$1
if [[ -d "${source}" ]]; then
cd ${source}
if [[ -f "${source}/Dockerfile" ]]; then
return ${ENV_YES}
else
logError "Dockerfile is not exists"
return ${ENV_NO}
fi
cd -
return ${ENV_YES}
else
logError "${source} is not valid docker project"
return ${ENV_NO}
fi
}
================================================
FILE: codes/linux/soft/lib/file.sh
================================================
#!/usr/bin/env bash
# 装载其它库
ROOT=`dirname ${BASH_SOURCE[0]}`
source ${ROOT}/utils.sh
# ------------------------------------------------------------------------------ 文件操作函数
# 文件是否存在
isFileExists() {
if [[ -e $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
isFile() {
if [[ -f $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
isDirectory() {
if [[ -d $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
isFileReadable() {
if [[ -r $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
isFileWritable() {
if [[ -w $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
isFileExecutable() {
if [[ -x $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
# 检查文件夹是否存在,不存在则创建
createFolderIfNotExist() {
if [ ! -d "$1" ]; then
mkdir -p "$1"
fi
}
# 重建目录,如果目录已存在,则删除后重建;如果不存在,直接新建
recreateDir() {
if [[ ! $1 ]]; then
printf "${C_B_RED}<<<< Please input dir path.${C_RESET}\n"
return ${FAILED}
fi
rm -rf $1
mkdir -p $1
isDirectory $1
if [[ "$?" != "${SUCCEED}" ]]; then
printf "${C_B_RED}<<<< create $1 failed.${C_RESET}\n"
return ${FAILED}
fi
return ${SUCCEED}
}
================================================
FILE: codes/linux/soft/lib/git.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Shell Utils
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ util functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ git functions
getGitLocalBranch() {
export GIT_LOCAL_BRANCH=$(git symbolic-ref -q --short HEAD)
}
getGitOriginBranch() {
export GIT_ORIGIN_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name "@{u}")
}
# check specified path is git project or not
IS_GIT=false
checkGit() {
local source=$1
if [[ -d "${source}" ]]; then
cd ${source}
# (1) delete gitstatus.tmp
if [[ -f "gitstatus.tmp" ]]; then
rm -rf gitstatus.tmp
fi
# (2) check git status
git status &> gitstatus.tmp
local gitStatus=false
grep -iwq 'not a git repository' gitstatus.tmp && gitStatus=false || gitStatus=true
rm -rf gitstatus.tmp
if [[ ${gitStatus} == true ]]; then
export IS_GIT=true
return
fi
fi
logWarn "${source} is not exists."
export IS_GIT=false
}
# execute git clone or fetch
# params: Git repository, git group, git project, git branch, local path
cloneOrPullGit() {
local repository=$1
local group=$2
local project=$3
local branch=$4
local root=$5
if [[ ! ${repository} || ! ${group} || ! ${project} || ! ${branch} || ! ${root} ]]; then
logError "Please input root, group, project, branch."
return ${ENV_FAILED}
fi
if [[ ! -d "${root}" ]]; then
logError "${root} is not directory."
return ${ENV_FAILED}
fi
local source=${root}/${group}/${project}
logInfo "project directory is ${source}."
logInfo "git url is ${repository}:${group}/${project}.git."
checkGit ${source}
if [[ "${IS_GIT}" == "true" ]]; then
cd ${source} || return ${ENV_FAILED}
git checkout ${branch}
logInfo "git checkout ${branch} succeed."
git fetch --all
git reset --hard ${GIT_ORIGIN_BRANCH}
logInfo "git reset --hard ${GIT_ORIGIN_BRANCH} succeed."
git pull
logInfo "git pull succeed."
else
git clone "${repository}:${group}/${project}.git" ${source}
logInfo "git clone ${project} succeed."
cd ${source} || return ${ENV_FAILED}
git checkout ${branch}
logInfo "git checkout ${branch} succeed."
fi
logInfo "Clone or pull git project [$2/$3:$4] succeed."
cd ${SOURCE_DIR}
return ${ENV_SUCCEED}
}
================================================
FILE: codes/linux/soft/lib/java.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Java 应用运维脚本
# @author Zhang Peng
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env preparation
# load libs
CURRENT_PATH=`dirname ${BASH_SOURCE[0]}`
source ${CURRENT_PATH}/utils.sh
# ------------------------------------------------------------------------------ functions
stopServer() {
if [[ ! $1 ]]; then
printError "please input java app name"
return ${FAILED}
fi
local javaAppName=$1
local pid=`jps | grep ${javaAppName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
kill -9 ${pid}
if [[ $? -eq ${SUCCEED} ]]; then
printInfo "stop ${javaAppName} succeed"
return ${SUCCEED}
else
printError "stop ${javaAppName} failed"
return ${FAILED}
fi
else
printWarn "${javaAppName} is not running"
return ${SUCCEED}
fi
}
startServer() {
if [[ ! $1 ]]; then
printError "please input java app name"
return ${FAILED}
fi
# >>>> 1. check java app is started or not
# >>>> 1.1. exit script if the app is started
local javaAppName=$1
local pid=`jps | grep ${javaAppName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
printInfo "${javaAppName} is started, PID: ${pid}"
return ${SUCCEED}
fi
# >>>> 2. package options
# GC OPTS
local javaOptions="-server -Xms1g -Xmx2g -Xss256k"
javaOptions="${javaOptions} -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:NewRatio=4"
# GC LOG OPTS
javaOptions="${javaOptions} -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps"
javaOptions="${javaOptions} -verbose:gc -Xloggc:${LOG_PATH}/${javaAppName}.gc.log"
javaOptions="${javaOptions} -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=100M"
# Heap Dump OPTS
javaOptions="${javaOptions} -XX:-OmitStackTraceInFastThrow -XX:+HeapDumpOnOutOfMemoryError"
javaOptions="${javaOptions} -XX:HeapDumpPath=${LOG_PATH}/${javaAppName}.heapdump.hprof"
# APP OPTS
javaOptions="${javaOptions} -Dsun.net.inetaddr.ttl=60 -Djava.net.preferIPv4Stack=true -Dfile.encoding=UTF-8"
if [[ ${PROFILE} ]]; then
javaOptions="${javaOptions} -Dspring.profiles.active=${PROFILE}"
fi
# DEBUG OPTS
if [[ "${DEBUG}" == "on" ]]; then
# JMX OPTS
local ip=$(ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/')
local jmxPort=$(expr 10000 + ${PORT})
javaOptions="${javaOptions} -Dcom.sun.management.jmxremote=true"
javaOptions="${javaOptions} -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false"
javaOptions="${javaOptions} -Djava.rmi.server.hostname=${ip} -Dcom.sun.management.jmxremote.port=${jmxPort}"
# Remote Debug
local debugPort=$(expr 20000 + ${PORT})
javaOptions="${javaOptions} -Xdebug -Xnoagent -Djava.compiler=NONE"
javaOptions="${javaOptions} -Xrunjdwp:transport=dt_socket,address=${debugPort},server=y,suspend=n"
fi
# CLASSPATH
local appOptions="-classpath ${ROOT_PATH}/lib/* -Dlogging.config=file:${ROOT_PATH}/config/logback.dev.xml"
appOptions="${appOptions} --spring.config.location=classpath:/,classpath:/config/,file:${ROOT_PATH},file:${ROOT_PATH}/config/"
if [[ ${PORT} ]]; then
appOptions="${appOptions} --server.port=${PORT}"
fi
# >>>> 3. create log dir and console log file
mkdir -p ${LOG_PATH}
if [[ ! -x ${CONSOLE_LOG} ]]; then
touch ${CONSOLE_LOG}
fi
# >>>> 4. start java app
printInfo "starting ${javaAppName}, execute cli: "
printInfo "nohup java ${javaOptions} -jar ${ROOT_PATH}/${javaAppName}.jar ${appOptions} >> ${CONSOLE_LOG} 2>&1 &"
nohup java ${javaOptions} -jar ${ROOT_PATH}/${javaAppName}.jar ${appOptions} >> ${CONSOLE_LOG} 2>&1 &
# >>>> 5. check java app is started or not
local pid=`jps | grep ${javaAppName} | awk '{print $1}'`
if [[ -n "${pid}" ]]; then
printInfo "start ${javaAppName} succeed, PID: ${pid}"
return ${SUCCEED}
else
printError "start ${javaAppName} failed"
return ${FAILED}
fi
}
# ------------------------------------------------------------------------------ main
export LANG="zh_CN.UTF-8"
ROOT_PATH=$(cd ${CURRENT_PATH}/..; pwd)
APP_NAME=java-app
LOG_PATH=/var/log/myapp
CONSOLE_LOG=${LOG_PATH}/${APP_NAME}.console.log
PORT=8888
PROFILE=dev
DEBUG=off
startServer ${APP_NAME}
#stopServer ${APP_NAME}
if [[ $? -eq ${SUCCEED} ]]; then
exit ${SUCCEED}
else
exit ${FAILED}
fi
================================================
FILE: codes/linux/soft/lib/maven.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# maven operation utils
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ load libs
LINUX_SCRIPTS_LIB_DIR=`dirname ${BASH_SOURCE[0]}`
if [[ ! -x ${LINUX_SCRIPTS_LIB_DIR}/utils.sh ]]; then
echo "${LINUX_SCRIPTS_LIB_DIR}/utils.sh not exists!"
exit 1
fi
source ${LINUX_SCRIPTS_LIB_DIR}/utils.sh
# ------------------------------------------------------------------------------ functions
# execute maven lifecycle operation
# @param $1: maven project path
# @param $2: maven lifecycle, eg. package、install、deploy
# @param $3: maven profile [optional]
mavenOperation() {
local source=$1
local lifecycle=$2
local profile=$3
mavenCheck ${source}
if [[ "${ENV_SUCCEED}" != "$?" ]]; then
return ${ENV_FAILED}
fi
if [[ ! "${lifecycle}" ]]; then
logError "please input maven lifecycle"
return ${ENV_FAILED}
fi
local mvnCli="mvn clean ${lifecycle} -DskipTests=true -B -U"
if [[ ${profile} ]]; then
mvnCli="${mvnCli} -P${profile}"
fi
cd ${source}
if [[ -f "${source}/settings.xml" ]]; then
mvnCli="${mvnCli} -s ${source}/settings.xml"
fi
callAndLog "${mvnCli}"
cd -
return ${ENV_SUCCEED}
}
# check specified path is maven project or not
# @param $1: maven project path
mavenCheck() {
local source=$1
if [[ -d "${source}" ]]; then
cd ${source}
if [[ -f "${source}/pom.xml" ]]; then
return ${ENV_YES}
else
logError "pom.xml is not exists"
return ${ENV_NO}
fi
cd -
return ${ENV_YES}
else
logError "please input valid maven project path"
return ${ENV_NO}
fi
}
================================================
FILE: codes/linux/soft/lib/mysql.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# 数据库操作脚本
# 支持操作:
# 备份 Mysql
# 恢复 Mysql
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "$@"
return ${ENV_SUCCEED}
else
printError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ env
# Mysql 操作的环境变量,使用方法:
# 可以在执行本脚本之前,export 以下环境变量,否则将按照默认配置执行
# Mysql HOST(默认为 127.0.0.1)
ENV_MYSQL_HOST="${ENV_MYSQL_HOST:-127.0.0.1}"
# Mysql 端口(默认为 3306)
ENV_MYSQL_PORT=${ENV_MYSQL_PORT:-3306}
# Mysql 用户名(默认为 root)
ENV_MYSQL_USERNAME=${ENV_MYSQL_USERNAME:-root}
# Mysql 密码(默认为 root)
ENV_MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD:-root}
# Mysql 备份文件最大数量(默认为 7 天)
ENV_BACKUP_MAX_NUM=${ENV_BACKUP_MAX_NUM:-7}
# 备份模式:备份所有数据库(--all-databases)|备份指定数据库列表
ENV_MYSQL_DATABASES="${ENV_MYSQL_DATABASES:---all-databases}"
# 备份路径
ENV_MYSQL_BACKUP_DIR="${ENV_MYSQL_BACKUP_DIR:-/var/lib/mysql/backup}"
# 备份日志路径
ENV_MYSQL_BACKUP_LOG_PATH="${ENV_MYSQL_BACKUP_DIR}/mysql-backup.log"
magentaOutput "------------------------------------------------------------------------------"
magentaOutput "Mysql 脚本操作环境变量:"
magentaOutput "ENV_MYSQL_HOST:${ENV_MYSQL_HOST}"
magentaOutput "ENV_MYSQL_PORT:${ENV_MYSQL_PORT}"
magentaOutput "ENV_MYSQL_USERNAME:${ENV_MYSQL_USERNAME}"
magentaOutput "ENV_MYSQL_PASSWORD:${ENV_MYSQL_PASSWORD}"
magentaOutput "ENV_BACKUP_MAX_NUM:${ENV_BACKUP_MAX_NUM}"
magentaOutput "ENV_MYSQL_DATABASES:${ENV_MYSQL_DATABASES}"
magentaOutput "ENV_MYSQL_BACKUP_DIR:${ENV_MYSQL_BACKUP_DIR}"
magentaOutput "ENV_MYSQL_BACKUP_LOG_PATH:${ENV_MYSQL_BACKUP_LOG_PATH}"
magentaOutput "------------------------------------------------------------------------------"
# ------------------------------------------------------------------------------ functions
# 备份所有 database(schema)
backupAllDatabase() {
#时间戳
local timestamp=$(date +"%Y%m%d")
#备份所有数据库
printInfo ">>>> 备份所有数据库开始"
mysqldump -h ${ENV_MYSQL_HOST} -P${ENV_MYSQL_PORT} -u${ENV_MYSQL_USERNAME} -p${ENV_MYSQL_PASSWORD} --all-databases > "${ENV_MYSQL_BACKUP_DIR}/all-${timestamp}.sql" 2>> ${ENV_MYSQL_BACKUP_LOG_PATH};
#检查备份结果是否成功
if [[ "$?" != ${ENV_SUCCEED} ]]; then
printError "<<<< 备份所有数据库失败"
return ${ENV_FAILED}
fi
# 压缩备份sql文件,删除旧的备份文件
cd "${ENV_MYSQL_BACKUP_DIR}"
if [[ ! -f "${ENV_MYSQL_BACKUP_DIR}/all-${timestamp}.sql" ]]; then
printError "备份文件 ${ENV_MYSQL_BACKUP_DIR}/all-${timestamp}.sql 不存在"
return ${ENV_FAILED}
fi
#为节约硬盘空间,将数据库压缩
tar zcf "all-${timestamp}.tar.gz" "all-${timestamp}.sql" > /dev/null
#删除原始文件,只留压缩后文件
rm -f "all-${timestamp}.sql"
#只保存期限内的备份文件,其余删除
find "${ENV_MYSQL_BACKUP_DIR} -name all-*.tar.gz -type f -mtime +${ENV_BACKUP_MAX_NUM} -exec rm -rf {} \;" > /dev/null 2>&1
printInfo "<<<< 备份所有数据库成功\n"
return ${ENV_SUCCEED}
}
# 备份指定的 database(schema)
backupSelectedDatabase() {
#时间戳
local timestamp=$(date +"%Y%m%d")
#数据库,如有多个库用空格分开
databaseList="${ENV_MYSQL_DATABASES}"
#备份指定数据库列表
printInfo ">>>> 备份指定数据库开始"
for database in ${databaseList}; do
printInfo "正在备份数据库:${database}"
mysqldump -h ${ENV_MYSQL_HOST} -P${ENV_MYSQL_PORT} -u${ENV_MYSQL_USERNAME} -p${ENV_MYSQL_PASSWORD} "${database}" > "${ENV_MYSQL_BACKUP_DIR}/${database}-${timestamp}.sql" 2>> ${ENV_MYSQL_BACKUP_LOG_PATH};
if [[ "$?" != 0 ]]; then
printError "<<<< 备份 ${database} 失败"
return ${ENV_FAILED}
fi
# 压缩备份sql文件,删除旧的备份文件
cd "${ENV_MYSQL_BACKUP_DIR}"
if [[ ! -f "${ENV_MYSQL_BACKUP_DIR}/${database}-${timestamp}.sql" ]]; then
printError "备份文件 ${ENV_MYSQL_BACKUP_DIR}/${database}-${timestamp}.sql 不存在"
return ${ENV_FAILED}
fi
#为节约硬盘空间,将数据库压缩
tar zcf "${database}-${timestamp}.tar.gz" "${database}-${timestamp}.sql" > /dev/null
#删除原始文件,只留压缩后文件
rm -f "${database}-${timestamp}.sql"
#只保存期限内的备份文件,其余删除
find "${ENV_MYSQL_BACKUP_DIR} -name ${database}-*.tar.gz -type f -mtime +${ENV_BACKUP_MAX_NUM} -exec rm -rf {} \;" > /dev/null 2>&1
done
printInfo "<<<< 备份数据库 ${ENV_MYSQL_DATABASES} 成功\n"
return ${ENV_SUCCEED}
}
# 备份 Mysql
backupMysql() {
#创建备份目录及日志文件
mkdir -p ${ENV_MYSQL_BACKUP_DIR}
if [[ ! -f ${ENV_MYSQL_BACKUP_LOG_PATH} ]]; then
touch ${ENV_MYSQL_BACKUP_LOG_PATH}
fi
#正式备份数据库
if [[ ${ENV_MYSQL_DATABASES} == "--all-databases" ]]; then
backupAllDatabase
else
backupSelectedDatabase
fi
}
# 恢复 Mysql
recoveryMysql() {
#创建备份目录及日志文件
mkdir -p ${ENV_MYSQL_BACKUP_DIR}
if [[ ! -f ${ENV_MYSQL_BACKUP_LOG_PATH} ]]; then
touch ${ENV_MYSQL_BACKUP_LOG_PATH}
fi
printInfo ">>>> 恢复数据库开始"
mysql -h ${ENV_MYSQL_HOST} -P${ENV_MYSQL_PORT} -u${ENV_MYSQL_USERNAME} -p${ENV_MYSQL_PASSWORD} < ${ENV_MYSQL_BACKUP_LOG_PATH}
if [[ "$?" != 0 ]]; then
printError "<<<< 恢复数据库失败"
return ${ENV_FAILED}
fi
printInfo "<<<< 恢复数据库成功\n"
return ${ENV_SUCCEED}
}
================================================
FILE: codes/linux/soft/lib/net.sh
================================================
#!/usr/bin/env bash
# ----------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ----------------------------------------------------------------------------------
printf "${PURPLE}"
cat << EOF
# ----------------------------------------------------------------------------------
# XXX 脚本
# @author: Zhang Peng
# ----------------------------------------------------------------------------------
EOF
printf "${RESET}"
printf "${BLUE}>>>>>>>> begin.\n${RESET}"
printf "${GREEN}[OK]\n${RESET}"
printf "${RED}[ERROR]\n${RESET}"
printf "${BLUE}<<<<<<<< end.\n${RESET}"
IP=`ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d '/'`
================================================
FILE: codes/linux/soft/lib/nodejs.sh
================================================
#!/usr/bin/env bash
# 装载其它库
ROOT=`dirname ${BASH_SOURCE[0]}`
source ${ROOT}/file.sh
# ------------------------------------------------------------------------------ nodejs 操作函数
# install Node Version Manager(nvm)
installNvm() {
local nvmVersion=0.35.2
if [[ $1 ]]; then
local nvmVersion=$1
fi
recreateDir "~/.nvm"
curl -o- https://raw.githubusercontent.com/creationix/nvm/v${nvmVersion}/install.sh | bash
source ~/.nvm/nvm.sh
if [[ "$?" != "${YES}" ]]; then
return ${FAILED}
fi
# Check
nvm version
if [[ "$?" != "${YES}" ]]; then
return ${FAILED}
fi
return ${SUCCEED}
}
# Check nodejs version
checkNodejsVersion() {
if [[ ! $1 ]]; then
printf "${C_B_RED}<<<< please specified expect nodejs version.${C_RESET}\n"
return ${FAILED}
fi
local expectVersion=$1
source /root/.bashrc
local nodeVersion=$(nvm version)
if [[ "$?" != "${YES}" ]]; then
printf "${C_B_YELLOW}>>>> nvm not installed.${C_RESET}\n"
local nvmVersion=v0.35.2
installNvm "${nvmVersion}"
if [[ "$?" != "${SUCCEED}" ]]; then
return ${FAILED}
fi
nodeVersion=$(nvm version)
fi
if [[ "${nodeVersion}" != "v${expectVersion}" ]]; then
printf "${C_B_YELLOW}>>>> current nodejs version is ${nodeVersion}, not ${expectVersion}.${C_RESET}\n"
nvm install ${expectVersion}
nvm use ${expectVersion}
fi
return ${SUCCEED}
}
# build nodejs project
buildNodejsProject() {
if [[ ! $1 ]]; then
printf "${C_B_RED}<<<< please input nodejs project path.${C_RESET}\n"
return ${FAILED}
fi
if [[ ! $2 ]]; then
printf "${C_B_RED}<<<< please input nodejs version.${C_RESET}\n"
return ${FAILED}
fi
isDirectory $1
if [[ "$?" != "${YES}" ]]; then
printf "${C_B_RED}<<<< $1 is not valid path.${C_RESET}\n"
return ${FAILED}
fi
local project=$1
local nodeVersion=$2
printf "${C_B_BLUE}>>>> build nodejs project $1 begin.${C_RESET}\n"
cd ${project} || (printf "${C_B_RED}<<<< ${project} is not exists.${C_RESET}\n" && exit 1)
checkNodejsVersion ${nodeVersion}
npm install
if [[ "$?" != "${YES}" ]]; then
printf "${C_B_RED}<<<< update dependencies failed.${C_RESET}\n"
return ${FAILED}
else
printf "${C_B_GREEN}>>>> update dependencies succeed.${C_RESET}\n"
fi
npm run build
if [[ "$?" != "${YES}" ]]; then
printf "${C_B_RED}<<<< build failed.${C_RESET}\n"
return ${FAILED}
else
printf "${C_B_GREEN}<<<< build succeed.${C_RESET}\n"
fi
return ${SUCCEED}
}
# package nodejs artifact dir (default is dist)
packageDist() {
zip -o -r -q ${branch}.zip *
}
================================================
FILE: codes/linux/soft/lib/string.sh
================================================
#!/usr/bin/env bash
strIsEmpty() {
if [[ -z $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
strIsNotEmpty() {
if [[ -n $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
strIsBlank() {
if [[ ! $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
strIsNotBlank() {
if [[ $1 ]]; then
return ${YES}
else
return ${NO}
fi
}
strEquals() {
if [[ "$1" = "$2" ]]; then
return ${YES}
else
return ${NO}
fi
}
strStartWith() {
if [[ "$1" == "$2*" ]]; then
return ${YES}
else
return ${NO}
fi
}
================================================
FILE: codes/linux/soft/lib/utils.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Shell Utils
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Underline Color
export ENV_COLOR_U_BLACK="\033[4;30m"
export ENV_COLOR_U_RED="\033[4;31m"
export ENV_COLOR_U_GREEN="\033[4;32m"
export ENV_COLOR_U_YELLOW="\033[4;33m"
export ENV_COLOR_U_BLUE="\033[4;34m"
export ENV_COLOR_U_MAGENTA="\033[4;35m"
export ENV_COLOR_U_CYAN="\033[4;36m"
export ENV_COLOR_U_WHITE="\033[4;37m"
# Background Color
export ENV_COLOR_BG_BLACK="\033[40m"
export ENV_COLOR_BG_RED="\033[41m"
export ENV_COLOR_BG_GREEN="\033[42m"
export ENV_COLOR_BG_YELLOW="\033[43m"
export ENV_COLOR_BG_BLUE="\033[44m"
export ENV_COLOR_BG_MAGENTA="\033[45m"
export ENV_COLOR_BG_CYAN="\033[46m"
export ENV_COLOR_BG_WHITE="\033[47m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
# 日志路径
LOG_PATH=${ENV_LOG_PATH:-/var/log/shell.log}
# 日志目录
LOG_DIR=${LOG_PATH%/*}
createLogFileIfNotExists() {
if [[ ! -x "${LOG_PATH}" ]]; then
mkdir -p "${LOG_DIR}"
touch "${LOG_PATH}"
fi
}
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
logInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [INFO] [$0] $@" >> "${LOG_PATH}"
}
logWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [WARN] [$0] $@" >> "${LOG_PATH}"
}
logError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
createLogFileIfNotExists
echo "[${SHELL_LOG_TIMESTAMP}] [${USER}] [ERROR] [$0] $@" >> "${LOG_PATH}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
logInfo "$@"
return ${ENV_SUCCEED}
else
logError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
================================================
FILE: codes/linux/soft/maven-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 Maven3 脚本
# Maven 会被安装到 /opt/maven 路径。
# @system: 适用于所有 linux 发行版本。
# 注意:Maven 要求必须先安装 JDK
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install maven begin.${RESET}\n"
command -v java > /dev/null 2>&1 || {
printf "${RED}Require java but it's not installed.${RESET}\n";
exit 1;
}
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh maven-install.sh [version] [path]\n"
printf "\t Example: sh maven-install.sh 3.6.0 /opt/maven\n"
printf "${RESET}\n"
fi
version=3.5.4
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/maven
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" -O ${path}/apache-maven-${version}-bin.tar.gz http://apache.01link.hk/maven/maven-3/${version}/binaries/apache-maven-${version}-bin.tar.gz
tar -zxvf ${path}/apache-maven-${version}-bin.tar.gz -C ${path}
# setting env
path=${path}/apache-maven-${version}
cat >> /etc/profile << EOF
export MAVEN_HOME=${path}
export PATH=\$MAVEN_HOME/bin:\$PATH
EOF
source /etc/profile
# replace mirrors in settings.xml
echo -e "\n>>>>>>>>> replace ${path}/conf/settings.xml"
cp ${path}/conf/settings.xml ${path}/conf/settings.xml.bak
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/settings-aliyun.xml -O ${path}/conf/settings.xml
printf "${GREEN}<<<<<<<< install maven end.${RESET}\n"
mvn -v
================================================
FILE: codes/linux/soft/mongodb-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 mongodb 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install mongodb begin.${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh mongodb-install.sh [version] [path]\n"
printf "\t Example: sh mongodb-install.sh 4.0.9 /opt/mongodb\n"
printf "${RESET}\n"
fi
version=4.0.9
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/mongodb
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
curl -o ${path}/mongodb-linux-x86_64-${version}.tgz https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-${version}.tgz
tar zxf ${path}/mongodb-linux-x86_64-${version}.tgz -C ${path}
mkdir -p /data/db
printf "${GREEN}<<<<<<<< install mongodb end.${RESET}\n"
================================================
FILE: codes/linux/soft/mysql-backup.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# Mysql 备份脚本
# 可以通过 crond 服务,设置称为定时执行脚本:
# (1)执行 crontab -e 编辑定时执行任务,如:59 23 * * * /home/scripts/mysql-backup.sh
# (2)vi /etc/crontab,编辑 crontab 文件后保存,可以通过 crontab -l 查看
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Mysql Host
export ENV_MYSQL_HOST="127.0.0.1"
# Mysql 端口
export ENV_MYSQL_PORT=3306
# Mysql 用户名
export ENV_MYSQL_USERNAME=root
# Mysql 密码
export ENV_MYSQL_PASSWORD=root
# Mysql 备份文件最大数量
export ENV_BACKUP_MAX_NUM=7
# 备份模式:备份所有数据库(--all-databases)|备份指定数据库列表
export ENV_MYSQL_DATABASES=--all-databases
# 备份路径
export ENV_MYSQL_BACKUP_DIR=/var/lib/mysql/backup
# 备份日志路径
export ENV_LOG_PATH="${ENV_MYSQL_BACKUP_DIR}/mysql-backup.log"
# ------------------------------------------------------------------------------ libs
LINUX_SCRIPTS_LIB_DIR=`dirname ${BASH_SOURCE[0]}`
if [[ ! -x ${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh ]]; then
echo "${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh not exists!"
exit 1
fi
source ${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh
# ------------------------------------------------------------------------------ main
# 执行备份方法
backupMysql
================================================
FILE: codes/linux/soft/mysql-install.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# 安装 Mysql 脚本
# 仅适用于 CentOS7 发行版本
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "$@"
return ${ENV_SUCCEED}
else
printError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ main
printInfo ">>>> install mysql begin"
command -v wget > /dev/null 2>&1 || {
printError "Require wget but it's not installed"
exit 1;
}
command -v rpm > /dev/null 2>&1 || {
printError "Require rpm but it's not installed"
exit 1;
}
command -v yum > /dev/null 2>&1 || {
printError "Require yum but it's not installed"
exit 1;
}
printInfo ">>>> install mysql by rpm"
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
sudo rpm -Uvh mysql80-community-release-el7-3.noarch.rpm
sudo yum install mysql-community-server
printInfo ">>>> modify my.cnf"
cp /etc/my.cnf /etc/my.cnf.bak
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/mysql/my.cnf -O /etc/my.cnf
printInfo ">>>> create mysql log file"
mkdir -p /var/log/mysql
touch /var/log/mysql/mysql.log
touch /var/log/mysql/mysql_slow_query_log.log
chmod 777 /var/log/mysql/mysql.log
chmod 777 /var/log/mysql/mysql_slow_query_log.log
chown -R mysql:mysql /var/log/mysql
printInfo ">>>> modify limits.conf"
cat >> /etc/security/limits.conf << EOF
mysql soft nofile 65536
mysql hard nofile 65536
EOF
printInfo ">>>> start mysqld"
systemctl enable mysqld
systemctl start mysqld
systemctl daemon-reload
printInfo ">>>> 管理员密码如下,请登录 mysql 后重置新密码:"
password=$(grep "password" /var/log/mysql/mysql.log | awk '{print $NF}')
blueOutput "${password}"
printInfo "<<<< install mysql success"
================================================
FILE: codes/linux/soft/mysql-recovery.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# MYSQL 恢复脚本
# @author Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Mysql Host
export ENV_MYSQL_HOST="127.0.0.1"
# Mysql 端口
export ENV_MYSQL_PORT=3306
# Mysql 用户名
export ENV_MYSQL_USERNAME=root
# Mysql 密码
export ENV_MYSQL_PASSWORD=root
# Mysql 备份文件最大数量
export ENV_BACKUP_MAX_NUM=7
# 备份模式:备份所有数据库(--all-databases)|备份指定数据库列表
export ENV_MYSQL_DATABASES=--all-databases
# 备份路径
export ENV_MYSQL_BACKUP_DIR=/var/lib/mysql/backup
# 备份日志路径
export ENV_LOG_PATH="${ENV_MYSQL_BACKUP_DIR}/mysql-backup.log"
# ------------------------------------------------------------------------------ libs
LINUX_SCRIPTS_LIB_DIR=`dirname ${BASH_SOURCE[0]}`
if [[ ! -x ${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh ]]; then
echo "${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh not exists!"
exit 1
fi
source ${LINUX_SCRIPTS_LIB_DIR}/lib/mysql.sh
# ------------------------------------------------------------------------------ main
# 执行备份方法
recoveryMysql
================================================
FILE: codes/linux/soft/nacos-install.sh
================================================
#!/usr/bin/env bash
cat << EOF
###################################################################################
# 安装 nacos 脚本
# 需要提前安装 jdk、maven
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
command -v java > /dev/null 2>&1 || {
printf "${RED}Require java but it's not installed.${RESET}\n";
exit 1;
}
command -v mvn > /dev/null 2>&1 || {
printf "${RED}Require mvn but it's not installed.${RESET}\n";
exit 1;
}
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
echo "Usage: sh nacos-install.sh [version] [path]"
printf "Example: sh nacos-install.sh 1.0.0 /opt/nacos\n"
fi
version=1.0.0
if [[ -n $1 ]]; then
version=$1
fi
root=/opt/nacos
if [[ -n $2 ]]; then
root=$2
fi
echo "Current execution: install nacos ${version} to ${root}"
echo -e "\n>>>>>>>>> download nacos"
mkdir -p ${root}
curl -o ${root}/nacos-server-${version}.zip https://github.com/alibaba/nacos/releases/download/${version}/nacos-server-${version}.zip
echo -e "\n>>>>>>>>> install nacos"
unzip ${root}/nacos-server-${version}.zip -d ${root}/nacos-server-${version}
mv ${root}/nacos-server-${version}/nacos/* ${root}/nacos-server-${version}
rm -rf ${root}/nacos-server-${version}/nacos
================================================
FILE: codes/linux/soft/nexus-install.sh
================================================
#!/usr/bin/env bash
# -----------------------------------------------------------------------------------------------------
# 安装 sonatype nexus(用于搭建 maven 私服) 脚本
# @system: 适用于所有 linux 发行版本。
# sonatype nexus 会被安装到 /opt/maven 路径。
# 注意:sonatype nexus 要求必须先安装 JDK
# @author: Zhang Peng
# -----------------------------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ env
# Regular Color
export ENV_COLOR_BLACK="\033[0;30m"
export ENV_COLOR_RED="\033[0;31m"
export ENV_COLOR_GREEN="\033[0;32m"
export ENV_COLOR_YELLOW="\033[0;33m"
export ENV_COLOR_BLUE="\033[0;34m"
export ENV_COLOR_MAGENTA="\033[0;35m"
export ENV_COLOR_CYAN="\033[0;36m"
export ENV_COLOR_WHITE="\033[0;37m"
# Bold Color
export ENV_COLOR_B_BLACK="\033[1;30m"
export ENV_COLOR_B_RED="\033[1;31m"
export ENV_COLOR_B_GREEN="\033[1;32m"
export ENV_COLOR_B_YELLOW="\033[1;33m"
export ENV_COLOR_B_BLUE="\033[1;34m"
export ENV_COLOR_B_MAGENTA="\033[1;35m"
export ENV_COLOR_B_CYAN="\033[1;36m"
export ENV_COLOR_B_WHITE="\033[1;37m"
# Reset Color
export ENV_COLOR_RESET="$(tput sgr0)"
# status
export ENV_YES=0
export ENV_NO=1
export ENV_SUCCEED=0
export ENV_FAILED=1
# ------------------------------------------------------------------------------ functions
# 显示打印日志的时间
SHELL_LOG_TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
# 那个用户在操作
USER=$(whoami)
redOutput() {
echo -e "${ENV_COLOR_RED} $@${ENV_COLOR_RESET}"
}
greenOutput() {
echo -e "${ENV_COLOR_B_GREEN} $@${ENV_COLOR_RESET}"
}
yellowOutput() {
echo -e "${ENV_COLOR_YELLOW} $@${ENV_COLOR_RESET}"
}
blueOutput() {
echo -e "${ENV_COLOR_BLUE} $@${ENV_COLOR_RESET}"
}
magentaOutput() {
echo -e "${ENV_COLOR_MAGENTA} $@${ENV_COLOR_RESET}"
}
cyanOutput() {
echo -e "${ENV_COLOR_CYAN} $@${ENV_COLOR_RESET}"
}
whiteOutput() {
echo -e "${ENV_COLOR_WHITE} $@${ENV_COLOR_RESET}"
}
printInfo() {
echo -e "${ENV_COLOR_B_GREEN}[INFO] $@${ENV_COLOR_RESET}"
}
printWarn() {
echo -e "${ENV_COLOR_B_YELLOW}[WARN] $@${ENV_COLOR_RESET}"
}
printError() {
echo -e "${ENV_COLOR_B_RED}[ERROR] $@${ENV_COLOR_RESET}"
}
callAndLog () {
$*
if [[ $? -eq ${ENV_SUCCEED} ]]; then
printInfo "$@"
return ${ENV_SUCCEED}
else
printError "$@ EXECUTE FAILED"
return ${ENV_FAILED}
fi
}
# ------------------------------------------------------------------------------ main
ENV_NEXUS_VERSION=${ENV_NEXUS_VERSION:-3.13.0-01}
ENV_NEXUS_DIR=${ENV_NEXUS_DIR:-/opt/maven}
printInfo ">>>> install nexus begin."
mkdir -p ${ENV_NEXUS_DIR}
printInfo "download nexus"
#由于国内网络问题,有可能下载失败
curl -o ${ENV_NEXUS_DIR}/nexus-unix.tar.gz https://sonatype-download.global.ssl.fastly.net/repository/repositoryManager/3/nexus-${ENV_NEXUS_VERSION}-unix.tar.gz
if [[ "$?" != ${ENV_SUCCEED} ]]; then
printError "<<<< download nexus-${ENV_NEXUS_VERSION}-unix.tar.gz failed"
return ${ENV_FAILED}
fi
tar -zxf nexus-unix.tar.gz
printInfo ">>>> setting systemd."
#通过设置 systemd,是的 nexus 注册为服务,开机自启动
touch /lib/systemd/system/nexus.service
cat >> /lib/systemd/system/nexus.service << EOF
[Unit]
Description=nexus
After=network.target
[Service]
Type=forking
LimitNOFILE=65536 #警告处理
Environment=RUN_AS_USER=root
ExecStart=${ENV_NEXUS_DIR}/nexus-${ENV_NEXUS_VERSION}/bin/nexus start
ExecReload=${ENV_NEXUS_DIR}/nexus-${ENV_NEXUS_VERSION}/bin/nexus restart
ExecStop=${ENV_NEXUS_DIR}/nexus-${ENV_NEXUS_VERSION}/bin/nexus stop
Restart=on-failure
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
systemctl enable nexus
systemctl start nexus
printInfo ">>>> setting firewalld."
firewall-cmd --zone=public --add-port=8081/tcp --permanent
firewall-cmd --reload
# 如果防火墻使用的是 iptables,使用如下配置:
#iptables -I INPUT -p tcp -m tcp --dport 8081 -j ACCEPT
#/etc/rc.d/init.d/iptables save
#service iptables restart
printInfo "<<<<<<<< install nexus success."
================================================
FILE: codes/linux/soft/nginx-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}\n"
cat << EOF
###################################################################################
# 采用编译方式安装 Nginx, 并将其注册为 systemd 服务
# 默认下载安装 1.16.0 版本,安装路径为:/usr/local/nginx
# @system: 适用于 CentOS7+
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "${RED}Require yum but it's not installed.${RESET}\n";
exit 1;
}
printf "\n${GREEN}>>>>>>>> install nginx begin${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t Usage: sh nginx-install.sh [version] \n"
printf "\t Default: sh nginx-install.sh 1.16.0 \n"
printf "\t Example: sh nginx-install.sh 1.16.0 \n"
printf "${RESET}\n"
fi
temp=/opt/nginx
version=1.16.0
if [[ -n $1 ]]; then
version=$1
fi
# install info
printf "${PURPLE}[Install Info]\n"
printf "\t version = ${version}\n"
printf "${RESET}\n"
printf "${CYAN}>>>> install required libs${RESET}\n"
yum install -y zlib zlib-devel gcc-c++ libtool openssl openssl-devel pcre
# download and decompression
printf "${CYAN}>>>> download nginx${RESET}\n"
mkdir -p ${temp}
curl -o ${temp}/nginx-${version}.tar.gz http://nginx.org/download/nginx-${version}.tar.gz
tar zxf ${temp}/nginx-${version}.tar.gz -C ${temp}
# configure and makefile
printf "${CYAN}>>>> compile nginx${RESET}\n"
cd ${temp}/nginx-${version}
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre
make && make install
rm -rf ${temp}
cd -
# setting systemd service
printf "${CYAN}>>>> set nginx as a systemd service${RESET}\n"
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/nginx/nginx.service -O /usr/lib/systemd/system/nginx.service
chmod +x /usr/lib/systemd/system/nginx.service
# boot nginx
printf "${CYAN}>>>> start nginx${RESET}\n"
systemctl enable nginx.service
systemctl start nginx.service
printf "\n${GREEN}<<<<<<<< install nginx end${RESET}\n"
printf "\n${PURPLE}nginx service status: ${RESET}\n"
systemctl status nginx
================================================
FILE: codes/linux/soft/nodejs-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 通过 nvm 安装 Nodejs 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
# @see: https://github.com/nvm-sh/nvm
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install nodejs begin.${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh nodejs-install.sh [version]\n"
printf "\t Example: sh nodejs-install.sh 10.15.2\n"
printf "${RESET}\n"
fi
version=10.15.2
if [[ -n $1 ]]; then
version=$1
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "${RESET}\n"
# install nvm
printf "${GREEN}>>>>>>>> install nvm.${RESET}\n"
rm -rf ~/.nvm
mkdir -p ~/.nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
. ~/.nvm/nvm.sh
nvm --version
printf "${GREEN}>>>>>>>> install nodejs by nvm.${RESET}\n"
nvm install ${version}
nvm use ${version}
node --version
printf "${GREEN}<<<<<<<< install nodejs end.${RESET}\n"
================================================
FILE: codes/linux/soft/redis-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
##########################################################################cd#########
printf "${BLUE}\n"
cat << EOF
###################################################################################
# 采用编译方式安装 Redis
# @system: 适用于 CentOS7+
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "${RED}Require yum but it's not installed.${RESET}\n";
exit 1;
}
printf "\n${GREEN}>>>>>>>> install redis begin${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]] || [[ $# -lt 3 ]] || [[ $# -lt 4 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t Usage: sh redis-install.sh [version] [port] [password] \n"
printf "\t Default: sh redis-install.sh 5.0.4 6379 \n"
printf "\t Example: sh redis-install.sh 5.0.4 6379 123456 \n"
printf "${RESET}\n"
fi
version=5.0.4
if [[ -n $1 ]]; then
version=$1
fi
port=6379
if [[ -n $2 ]]; then
port=$2
fi
password=
if [[ -n $3 ]]; then
password=$3
fi
# install info
printf "${PURPLE}[Install Info]\n"
printf "\t version = ${version}\n"
printf "\t port = ${port}\n"
printf "\t password = ${password}\n"
printf "${RESET}\n"
printf "${CYAN}>>>> install required libs${RESET}\n"
yum install -y zlib zlib-devel gcc-c++ libtool openssl openssl-devel tcl
# download and decompression
printf "${CYAN}>>>> download redis${RESET}\n"
temp="/tmp/redis"
path="/usr/local/redis"
mkdir -p ${temp}
curl -o ${temp}/redis-${version}.tar.gz http://download.redis.io/releases/redis-${version}.tar.gz
tar zxf ${temp}/redis-${version}.tar.gz -C ${temp}
mv ${temp}/redis-${version} ${path}
# configure and makefile
printf "${CYAN}>>>> compile redis${RESET}\n"
cd ${path}
make && make install
rm -rf ${temp}
cd -
printf "${CYAN}>>>> modify redis config${RESET}\n"
cp ${path}/redis.conf ${path}/redis.conf.default
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/redis/redis.conf -O ${path}/redis.conf
sed -i "s/^port 6379/port ${port}/g" ${path}/redis.conf
if [[ -n ${password} ]]; then
sed -i "s/^protected-mode no/protected-mode yes/g" ${path}/redis.conf
sed -i "s/^# requirepass/requirepass ${password}/g" ${path}/redis.conf
fi
printf "\n${CYAN}>>>> open redis port in firewall${RESET}\n"
firewall-cmd --zone=public --add-port=${port}/tcp --permanent
firewall-cmd --reload
# setting systemd service
printf "${CYAN}>>>> set redis as a systemd service${RESET}\n"
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/soft/config/redis/redis.service -O /usr/lib/systemd/system/redis.service
chmod +x /usr/lib/systemd/system/redis.service
# boot redis
printf "${CYAN}>>>> start redis${RESET}\n"
systemctl enable redis.service
systemctl start redis.service
printf "\n${GREEN}<<<<<<<< install redis end${RESET}\n"
printf "\n${PURPLE}redis service status: ${RESET}\n"
systemctl status redis
================================================
FILE: codes/linux/soft/rocketmq-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 rocketmq 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install tomcat begin.${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh rocketmq-install.sh [version] [path]\n"
printf "\t Example: sh rocketmq-install.sh 4.5.0 /opt/rocketmq\n"
printf "${RESET}\n"
fi
version=4.5.0
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/rocketmq
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
curl -o ${path}/rocketmq-all-${version}-bin-release.zip http://mirrors.tuna.tsinghua.edu.cn/apache/rocketmq/${version}/rocketmq-all-${version}-bin-release.zip
unzip -o ${path}/rocketmq-all-${version}-bin-release.zip -d ${path}/rocketmq-all-${version}/
mv ${path}/rocketmq-all-${version}/rocketmq-all-${version}-bin-release/* ${path}/rocketmq-all-${version}
rm -rf ${path}/rocketmq-all-${version}/rocketmq-all-${version}-bin-release
printf "${GREEN}<<<<<<<< install rocketmq end.${RESET}\n"
================================================
FILE: codes/linux/soft/tomcat8-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 Tomcat 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install tomcat begin.${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh tomcat8-install.sh [version] [path]\n"
printf "\t Example: sh tomcat8-install.sh 8.5.28 /opt/tomcat8\n"
printf "${RESET}\n"
fi
version=8.5.28
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/tomcat
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
curl -o ${path}/apache-tomcat-${version}.tar.gz https://archive.apache.org/dist/tomcat/tomcat-8/v${version}/bin/apache-tomcat-${version}.tar.gz
tar zxf ${path}/apache-tomcat-${version}.tar.gz -C ${path}
printf "${GREEN}<<<<<<<< install tomcat end.${RESET}\n"
================================================
FILE: codes/linux/soft/zookeeper-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 ZooKeeper 脚本
# @system: 适用于所有 linux 发行版本。
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install zookeeper begin.${RESET}\n"
if [[ $# -lt 1 ]] || [[ $# -lt 2 ]]; then
printf "${PURPLE}[Hint]\n"
printf "\t sh zookeeper-install.sh [version] [path]\n"
printf "\t Example: sh zookeeper-install.sh 3.4.12 /opt/zookeeper\n"
printf "${RESET}\n"
fi
version=3.4.12
if [[ -n $1 ]]; then
version=$1
fi
path=/opt/zookeeper
if [[ -n $2 ]]; then
path=$2
fi
# install info
printf "${PURPLE}[Info]\n"
printf "\t version = ${version}\n"
printf "\t path = ${path}\n"
printf "${RESET}\n"
# download and decompression
mkdir -p ${path}
curl -o ${path}/zookeeper-${version}.tar.gz http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-${version}/zookeeper-${version}.tar.gz
tar zxf ${path}/zookeeper-${version}.tar.gz -C ${path}
printf "${GREEN}<<<<<<<< install zookeeper end.${RESET}\n"
================================================
FILE: codes/linux/soft/zsh/oh-my-zsh-install.sh
================================================
# -------------------------------------------------------------------------------------------------------------------
# 由于国内经常无法使用 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 所以,索性将安装脚本下载下来直接使用
# -------------------------------------------------------------------------------------------------------------------
#!/bin/sh
#
# This script should be run via curl:
# sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# or wget:
# sh -c "$(wget -qO- https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
#
# As an alternative, you can first download the install script and run it afterwards:
# wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh
# sh install.sh
#
# You can tweak the install behavior by setting variables when running the script. For
# example, to change the path to the Oh My Zsh repository:
# ZSH=~/.zsh sh install.sh
#
# Respects the following environment variables:
# ZSH - path to the Oh My Zsh repository folder (default: $HOME/.oh-my-zsh)
# REPO - name of the GitHub repo to install from (default: ohmyzsh/ohmyzsh)
# REMOTE - full remote URL of the git repo to install (default: GitHub via HTTPS)
# BRANCH - branch to check out immediately after install (default: master)
#
# Other options:
# CHSH - 'no' means the installer will not change the default shell (default: yes)
# RUNZSH - 'no' means the installer will not run zsh after the install (default: yes)
# KEEP_ZSHRC - 'yes' means the installer will not replace an existing .zshrc (default: no)
#
# You can also pass some arguments to the install script to set some these options:
# --skip-chsh: has the same behavior as setting CHSH to 'no'
# --unattended: sets both CHSH and RUNZSH to 'no'
# --keep-zshrc: sets KEEP_ZSHRC to 'yes'
# For example:
# sh install.sh --unattended
#
set -e
# Default settings
ZSH=${ZSH:-~/.oh-my-zsh}
REPO=${REPO:-ohmyzsh/ohmyzsh}
REMOTE=${REMOTE:-https://github.com/${REPO}.git}
BRANCH=${BRANCH:-master}
# Other options
CHSH=${CHSH:-yes}
RUNZSH=${RUNZSH:-yes}
KEEP_ZSHRC=${KEEP_ZSHRC:-no}
command_exists() {
command -v "$@" >/dev/null 2>&1
}
error() {
echo ${RED}"Error: $@"${RESET} >&2
}
setup_color() {
# Only use colors if connected to a terminal
if [ -t 1 ]; then
RED=$(printf '\033[31m')
GREEN=$(printf '\033[32m')
YELLOW=$(printf '\033[33m')
BLUE=$(printf '\033[34m')
BOLD=$(printf '\033[1m')
RESET=$(printf '\033[m')
else
RED=""
GREEN=""
YELLOW=""
BLUE=""
BOLD=""
RESET=""
fi
}
setup_ohmyzsh() {
# Prevent the cloned repository from having insecure permissions. Failing to do
# so causes compinit() calls to fail with "command not found: compdef" errors
# for users with insecure umasks (e.g., "002", allowing group writability). Note
# that this will be ignored under Cygwin by default, as Windows ACLs take
# precedence over umasks except for filesystems mounted with option "noacl".
umask g-w,o-w
echo "${BLUE}Cloning Oh My Zsh...${RESET}"
command_exists git || {
error "git is not installed"
exit 1
}
if [ "$OSTYPE" = cygwin ] && git --version | grep -q msysgit; then
error "Windows/MSYS Git is not supported on Cygwin"
error "Make sure the Cygwin git package is installed and is first on the \$PATH"
exit 1
fi
git clone -c core.eol=lf -c core.autocrlf=false \
-c fsck.zeroPaddedFilemode=ignore \
-c fetch.fsck.zeroPaddedFilemode=ignore \
-c receive.fsck.zeroPaddedFilemode=ignore \
--depth=1 --branch "$BRANCH" "$REMOTE" "$ZSH" || {
error "git clone of oh-my-zsh repo failed"
exit 1
}
echo
}
setup_zshrc() {
# Keep most recent old .zshrc at .zshrc.pre-oh-my-zsh, and older ones
# with datestamp of installation that moved them aside, so we never actually
# destroy a user's original zshrc
echo "${BLUE}Looking for an existing zsh config...${RESET}"
# Must use this exact name so uninstall.sh can find it
OLD_ZSHRC=~/.zshrc.pre-oh-my-zsh
if [ -f ~/.zshrc ] || [ -h ~/.zshrc ]; then
# Skip this if the user doesn't want to replace an existing .zshrc
if [ $KEEP_ZSHRC = yes ]; then
echo "${YELLOW}Found ~/.zshrc.${RESET} ${GREEN}Keeping...${RESET}"
return
fi
if [ -e "$OLD_ZSHRC" ]; then
OLD_OLD_ZSHRC="${OLD_ZSHRC}-$(date +%Y-%m-%d_%H-%M-%S)"
if [ -e "$OLD_OLD_ZSHRC" ]; then
error "$OLD_OLD_ZSHRC exists. Can't back up ${OLD_ZSHRC}"
error "re-run the installer again in a couple of seconds"
exit 1
fi
mv "$OLD_ZSHRC" "${OLD_OLD_ZSHRC}"
echo "${YELLOW}Found old ~/.zshrc.pre-oh-my-zsh." \
"${GREEN}Backing up to ${OLD_OLD_ZSHRC}${RESET}"
fi
echo "${YELLOW}Found ~/.zshrc.${RESET} ${GREEN}Backing up to ${OLD_ZSHRC}${RESET}"
mv ~/.zshrc "$OLD_ZSHRC"
fi
echo "${GREEN}Using the Oh My Zsh template file and adding it to ~/.zshrc.${RESET}"
sed "/^export ZSH=/ c\\
export ZSH=\"$ZSH\"
" "$ZSH/templates/zshrc.zsh-template" > ~/.zshrc-omztemp
mv -f ~/.zshrc-omztemp ~/.zshrc
echo
}
setup_shell() {
# Skip setup if the user wants or stdin is closed (not running interactively).
if [ $CHSH = no ]; then
return
fi
# If this user's login shell is already "zsh", do not attempt to switch.
if [ "$(basename "$SHELL")" = "zsh" ]; then
return
fi
# If this platform doesn't provide a "chsh" command, bail out.
if ! command_exists chsh; then
cat <<-EOF
I can't change your shell automatically because this system does not have chsh.
${BLUE}Please manually change your default shell to zsh${RESET}
EOF
return
fi
echo "${BLUE}Time to change your default shell to zsh:${RESET}"
# Prompt for user choice on changing the default login shell
printf "${YELLOW}Do you want to change your default shell to zsh? [Y/n]${RESET} "
read opt
case $opt in
y*|Y*|"") echo "Changing the shell..." ;;
n*|N*) echo "Shell change skipped."; return ;;
*) echo "Invalid choice. Shell change skipped."; return ;;
esac
# Check if we're running on Termux
case "$PREFIX" in
*com.termux*) termux=true; zsh=zsh ;;
*) termux=false ;;
esac
if [ "$termux" != true ]; then
# Test for the right location of the "shells" file
if [ -f /etc/shells ]; then
shells_file=/etc/shells
elif [ -f /usr/share/defaults/etc/shells ]; then # Solus OS
shells_file=/usr/share/defaults/etc/shells
else
error "could not find /etc/shells file. Change your default shell manually."
return
fi
# Get the path to the right zsh binary
# 1. Use the most preceding one based on $PATH, then check that it's in the shells file
# 2. If that fails, get a zsh path from the shells file, then check it actually exists
if ! zsh=$(which zsh) || ! grep -qx "$zsh" "$shells_file"; then
if ! zsh=$(grep '^/.*/zsh$' "$shells_file" | tail -1) || [ ! -f "$zsh" ]; then
error "no zsh binary found or not present in '$shells_file'"
error "change your default shell manually."
return
fi
fi
fi
# We're going to change the default shell, so back up the current one
if [ -n "$SHELL" ]; then
echo $SHELL > ~/.shell.pre-oh-my-zsh
else
grep "^$USER:" /etc/passwd | awk -F: '{print $7}' > ~/.shell.pre-oh-my-zsh
fi
# Actually change the default shell to zsh
if ! chsh -s "$zsh"; then
error "chsh command unsuccessful. Change your default shell manually."
else
export SHELL="$zsh"
echo "${GREEN}Shell successfully changed to '$zsh'.${RESET}"
fi
echo
}
main() {
# Run as unattended if stdin is closed
if [ ! -t 0 ]; then
RUNZSH=no
CHSH=no
fi
# Parse arguments
while [ $# -gt 0 ]; do
case $1 in
--unattended) RUNZSH=no; CHSH=no ;;
--skip-chsh) CHSH=no ;;
--keep-zshrc) KEEP_ZSHRC=yes ;;
esac
shift
done
setup_color
if ! command_exists zsh; then
echo "${YELLOW}Zsh is not installed.${RESET} Please install zsh first."
exit 1
fi
if [ -d "$ZSH" ]; then
cat <<-EOF
${YELLOW}You already have Oh My Zsh installed.${RESET}
You'll need to remove '$ZSH' if you want to reinstall.
EOF
exit 1
fi
setup_ohmyzsh
setup_zshrc
setup_shell
printf "$GREEN"
cat <<-'EOF'
__ __
____ / /_ ____ ___ __ __ ____ _____/ /_
/ __ \/ __ \ / __ `__ \/ / / / /_ / / ___/ __ \
/ /_/ / / / / / / / / / / /_/ / / /_(__ ) / / /
\____/_/ /_/ /_/ /_/ /_/\__, / /___/____/_/ /_/
/____/ ....is now installed!
Please look over the ~/.zshrc file to select plugins, themes, and options.
p.s. Follow us on https://twitter.com/ohmyzsh
p.p.s. Get stickers, shirts, and coffee mugs at https://shop.planetargon.com/collections/oh-my-zsh
EOF
printf "$RESET"
if [ $RUNZSH = no ]; then
echo "${YELLOW}Run zsh to try it out.${RESET}"
exit
fi
exec zsh -l
}
main "$@"
================================================
FILE: codes/linux/soft/zsh-install.sh
================================================
#!/usr/bin/env bash
###################################################################################
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
###################################################################################
printf "${BLUE}"
cat << EOF
###################################################################################
# 安装 zsh、oh-my-zsh 脚本
# @system: 适用于 CentOS
# @author: Zhang Peng
# See: https://github.com/robbyrussell/oh-my-zsh
###################################################################################
EOF
printf "${RESET}"
printf "${GREEN}>>>>>>>> install zsh begin.${RESET}\n"
command -v yum > /dev/null 2>&1 || {
printf "${RED}Require yum but it's not installed.${RESET}\n";
exit 1;
}
command -v git > /dev/null 2>&1 || {
printf "${RED}Require git but it's not installed.${RESET}\n";
exit 1;
}
# install zsh
yum install -y zsh
chsh -s /bin/zsh
# install oh-my-zsh
# 由于国内经常无法使用 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 所以,索性将安装脚本下载下来直接使用
#curl -o- https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash
zsh/oh-my-zsh-install.sh
# choose oh-my-zsh theme
sed -i "s/^ZSH_THEME=.*/ZSH_THEME=\"ys\"/g" ~/.zshrc
# install oh-my-zsh plugins
git clone https://github.com/zsh-users/zsh-autosuggestions.git ~/.oh-my-zsh/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ~/.oh-my-zsh/plugins/zsh-syntax-highlighting
sed -i "s/^plugins=.*/plugins=(git z wd extract zsh-autosuggestions zsh-syntax-highlighting)/g" ~/.zshrc
# reload zsh
# 注册到 /etc/shells
echo "/usr/bin/zsh" >> /etc/shells
# 切换 shell
chsh -s $(which zsh)
printf "${GREEN}<<<<<<<< install zsh finished${RESET}\n"
printf "${GREEN}Please reboot to take effect.${RESET}\n"
================================================
FILE: codes/linux/sys/README.md
================================================
# 脚本使用说明
> 建议按照顺序执行本文脚本。
- [替换 yum repo 源](#替换-yum-repo-源)
- [安装基本工具(可选)](#安装基本工具可选)
- [安装常见 lib](#安装常见-lib)
- [关闭防火墙](#关闭防火墙)
- [设置 DNS](#设置-dns)
- [设置 ntp](#设置-ntp)
## 替换 yum repo 源
由于 CentOS 默认 yum 源,访问速度很慢,所以推荐使用国内镜像。
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/yum/change-yum-repo.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/yum/change-yum-repo.sh | bash
```
## 安装基本工具(可选)
工具清单(可以根据需要,在 install-tools.sh 中把不需要的工具注掉):
```
# 核心工具:df、du、chkconfig
# 网络工具:ifconfig、netstat、route、iptables
# IP工具:ip、ss、ping、tracepath、traceroute
# DNS工具:dig、host、nslookup、whois
# 端口工具:lsof、nc、telnet
# 下载工具:curl、wget
# 编辑工具:emacs、vim
# 流量工具:iftop、nethogs
# 抓包工具:tcpdump
# 压缩工具:unzip、zip
# 版本控制工具:git、subversion
```
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/install-tools.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/install-tools.sh | bash
```
## 安装常见 lib
lib 清单(可以根据需要,在 install-libs.sh 中把不需要的工具注掉):
```
# gcc gcc-c++ kernel-devel libtool
# openssl openssl-devel
# zlib zlib-devel
# pcre
```
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/install-libs.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/install-libs.sh | bash
```
## 关闭防火墙
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/stop-firewall.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/stop-firewall.sh | bash
```
## 设置 DNS
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/set-dns.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/set-dns.sh | bash
```
## 设置 ntp
使用方法:执行以下任意命令即可执行脚本。
```shell
curl -o- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/set-ntp.sh | bash
wget -qO- https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/set-ntp.sh | bash
```
================================================
FILE: codes/linux/sys/change-yum-repo.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
printf "${BLUE}\n"
cat << EOF
###################################################################################
# 本脚本用于替换 yum repo,使用国内 yum 仓库,加速下载
# 要求:仅适用于 Linux CentOS 发行版本,并且环境必须已支持 yum 、lsb_release 命令
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
printf "\n${GREEN}>>>>>>>>> 替换 yum repo 源开始${RESET}\n"
# 备份
cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
# 执行 lsb_release 命令,获取系统发行版本
# version=`lsb_release -r | awk '{print substr($2,1,1)}'` # 很多机器没有 lsb_release 命令
version=`cat /etc/redhat-release | awk '{print substr($4,1,1)}'`
# 根据发型版本选择相应 yum 镜像
if [[ ${version} == 5 ]]; then
# Cento5 已废弃,只能使用 http://vault.CentOS.org/ 替换,但由于是国外镜像,速度较慢
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/yum/Centos-5.repo -O /etc/yum.repos.d/CentOS-Base.repo
# 根据实际发型版本情况替换
detailVersion=`lsb_release -r | awk '{print substr($2,1,3)}'`
sed -i 's/$releasever/'"${detailVersion}"'/g' /etc/yum.repos.d/CentOS-Base.repo
# 不替换下面的开关,可能会出现错误:Could not open/read repomd.xml
sed -i 's/enabled=1/enabled=0/g' /etc/yum.repos.d/CentOS-Media.repo
elif [[ ${version} == 6 ]]; then
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/yum/Centos-6.repo -O /etc/yum.repos.d/CentOS-Base.repo
elif [[ ${version} == 7 ]]; then
wget -N https://gitee.com/turnon/linux-tutorial/raw/master/codes/linux/sys/yum/Centos-7.repo -O /etc/yum.repos.d/CentOS-Base.repo
else
printf "\n${RED}版本不支持,替换 yum repo 失败${RESET}\n"
fi
# 更新缓存
yum clean all
yum makecache
printf "\n${GREEN}<<<<<<<< 替换 yum repo 源结束${RESET}\n"
================================================
FILE: codes/linux/sys/install-libs.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
printf "${BLUE}\n"
cat << EOF
###################################################################################
# 安装常见 lib
# 如果不知道命令在哪个 lib,可以使用 yum search xxx 来查找
# lib 清单如下:
# gcc gcc-c++ kernel-devel libtool
# openssl openssl-devel
# zlib zlib-devel
# pcre
#
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
printf "\n${GREEN}>>>>>>>>> 安装常见 lib 开始${RESET}\n"
printf "\n${CYAN}>>>> install gcc gcc-c++ kernel-devel libtool${RESET}\n"
yum -y install make gcc gcc-c++ kernel-devel libtool
printf "\n${CYAN}>>>> install openssl openssl-devel${RESET}\n"
yum -y install make openssl openssl-devel
printf "\n${CYAN}>>>> install zlib zlib-devel${RESET}\n"
yum -y install make zlib zlib-devel
printf "\n${CYAN}>>>> install pcre${RESET}\n"
yum -y install pcre
printf "\n${GREEN}<<<<<<<< 安装常见 lib 结束${RESET}\n"
================================================
FILE: codes/linux/sys/install-tools.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
printf "${BLUE}\n"
cat << EOF
###################################################################################
# 安装常用命令工具
# 命令工具清单如下:
# 核心工具:df、du、chkconfig
# 网络工具:ifconfig、netstat、route、iptables
# IP工具:ip、ss、ping、tracepath、traceroute
# DNS工具:dig、host、nslookup、whois
# 端口工具:lsof、nc、telnet
# 下载工具:curl、wget
# 编辑工具:emacs、vim
# 流量工具:iftop、nethogs
# 抓包工具:tcpdump
# 压缩工具:unzip、zip
# 版本控制工具:git、subversion
#
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
printf "\n${GREEN}>>>>>>>>> 安装常用命令工具开始${RESET}\n"
# 核心工具
printf "\n${CYAN}>>>> install coreutils(df、du)${RESET}\n"
yum install -y coreutils
printf "\n${CYAN}>>>> install chkconfig${RESET}\n"
yum install -y chkconfig
# 网络工具
printf "\n${CYAN}>>>> install net-tools(ifconfig、netstat、route)${RESET}\n"
yum install -y net-tools
printf "\n${CYAN}>>>> install iptables${RESET}\n"
yum install -y iptables
# IP工具
printf "\n${CYAN}>>>> install iputils(ping、tracepath)${RESET}\n"
yum install -y iputils
printf "\n${CYAN}>>>> install traceroute${RESET}\n"
yum install -y traceroute
printf "\n${CYAN}>>>> install iproute(ip、ss)${RESET}\n"
yum install -y iproute
# 端口工具
printf "\n${CYAN}>>>> install lsof${RESET}\n"
yum install -y lsof
printf "\n${CYAN}>>>> install nc${RESET}\n"
yum install -y nc
printf "\n${CYAN}>>>> install netstat${RESET}\n"
yum install -y netstat
# DNS工具
printf "\n${CYAN}>>>> install bind-utils(dig、host、nslookup)${RESET}\n"
yum install -y bind-utils
printf "\n${CYAN}>>>> install whois${RESET}\n"
yum install -y whois
# 下载工具
printf "\n${CYAN}>>>> install curl${RESET}\n"
yum install -y curl
printf "\n${CYAN}>>>> install wget${RESET}\n"
yum install -y wget
# 编辑工具
printf "\n${CYAN}>>>> install emacs${RESET}\n"
yum install -y emacs
printf "\n${CYAN}>>>> install vim${RESET}\n"
yum install -y vim
# 流量工具
printf "\n${CYAN}>>>> install iftop${RESET}\n"
yum install -y iftop
printf "\n${CYAN}>>>> install nethogs${RESET}\n"
yum install -y nethogs
# 抓包工具
printf "\n${CYAN}>>>> install tcpdump${RESET}\n"
yum install -y tcpdump
# 压缩工具
printf "\n${CYAN}>>>> install unzip${RESET}\n"
yum install -y unzip
# 版本控制工具
printf "\n${CYAN}>>>> install git${RESET}\n"
yum install -y git
printf "\n${CYAN}>>>> install subversion${RESET}\n"
yum install -y subversion
printf "\n${GREEN}<<<<<<<< 安装常用命令工具结束${RESET}\n"
================================================
FILE: codes/linux/sys/set-dns.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
###################################################################################
# 在 /etc/resolv.conf 中配置 DNS 服务器
# 在 /etc/hosts 中配置本机域名
# @author: Zhang Peng
###################################################################################
printf "\n${GREEN}>>>>>>>>> 配置 DNS 开始${RESET}\n"
printf "\n${CYAN}>>>> 配置 DNS 解析服务器${RESET}\n"
cat >> /etc/resolv.conf << EOF
nameserver 114.114.114.114
nameserver 8.8.8.8
EOF
printf "\n${CYAN}>>>> 配置本机域名和IP映射${RESET}\n"
ip=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
host=`hostname`
cat >> /etc/hosts << EOF
${ip} ${host}
EOF
printf "\n${GREEN}<<<<<<<< 配置 DNS 结束${RESET}\n"
================================================
FILE: codes/linux/sys/set-ntp.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
###################################################################################
# 使用 NTP 进行时间同步
# 参考:https://www.cnblogs.com/quchunhui/p/7658853.html
# @author: Zhang Peng
###################################################################################
printf "\n${GREEN}>>>>>>>>> 设置 NTP 开始${RESET}\n"
printf "\n${CYAN}>>>> 安装 NTP 服务${RESET}\n"
yum -y install ntp
ip=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
/sbin/iptables -A INPUT -p UDP -i eth0 -s ${ip}/24 --dport 123 -j ACCEPT
printf "\n${CYAN}>>>> 启动 NTP 服务${RESET}\n"
systemctl start ntpd.service
printf "\n${CYAN}>>>> 立即执行时间同步${RESET}\n"
/usr/sbin/ntpdate ntp.sjtu.edu.cn
printf "\n${CYAN}>>>> 自动定时同步时间${RESET}\n"
echo "* 3 * * * /usr/sbin/ntpdate ntp.sjtu.edu.cn" >> /etc/crontab
systemctl restart crond.service
printf "\n${CYAN}>>>> 同步结束,当前系统时间:${RESET}\n"
date
printf "\n${GREEN}<<<<<<<< 设置 NTP 结束${RESET}\n"
================================================
FILE: codes/linux/sys/stop-firewall.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
###################################################################################
# 关闭防火墙
# 参考:https://www.cnblogs.com/moxiaoan/p/5683743.html
# @author: Zhang Peng
###################################################################################
systemctl stop firewalld
systemctl disable firewalld
printf "\n${GREEN}<<<<<<<< 已关闭防火墙${RESET}\n"
================================================
FILE: codes/linux/sys/sys-settings.sh
================================================
#!/usr/bin/env bash
# ---------------------------------------------------------------------------------
# 控制台颜色
BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
PURPLE="\033[1;35m"
CYAN="\033[1;36m"
RESET="$(tput sgr0)"
# ---------------------------------------------------------------------------------
printHeadInfo() {
printf "${BLUE}\n"
cat << EOF
###################################################################################
# Linux Centos7 系统配置脚本(根据需要选择)
# @author: Zhang Peng
###################################################################################
EOF
printf "${RESET}\n"
}
setLimit() {
cat >> /etc/security/limits.conf << EOF
* - nofile 65535
* - nproc 65535
EOF
}
setLang() {
cat > /etc/sysconfig/i18n << EOF
LANG="zh_CN.UTF-8"
EOF
}
closeShutdownShortkey() {
printf "\n${CYAN}>>>> 关闭 Ctrl+Alt+Del 快捷键防止重新启动${RESET}\n"
sed -i 's#exec /sbin/shutdown -r now#\#exec /sbin/shutdown -r now#' /etc/init/control-alt-delete.conf
}
closeSelinux() {
# see http://blog.51cto.com/13570193/2093299
printf "\n${CYAN}>>>> 关闭 selinux${RESET}\n"
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
}
setBootMode() {
# 1. 停机(记得不要把 initdefault 配置为 0,因为这样会使 Linux 不能启动)
# 2. 单用户模式,就像 Win9X 下的安全模式
# 3. 多用户,但是没有 NFS
# 4. 完全多用户模式,准则的运行级
# 5. 通常不用,在一些特殊情况下可以用它来做一些事情
# 6. X11,即进到 X-Window 系统
# 7. 重新启动 (记得不要把 initdefault 配置为 6,因为这样会使 Linux 不断地重新启动)
printf "\n${CYAN}>>>> 配置 Linux 启动模式${RESET}\n"
sed -i 's/id:5:initdefault:/id:3:initdefault:/' /etc/inittab
}
# 配置 IPv4
configIpv4() {
printf "\n${CYAN}>>>> 配置 IPv4${RESET}\n"
cat >> /etc/sysctl.conf << EOF
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_syn_backlog = 16384
net.core.netdev_max_backlog = 16384
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.ip_local_port_range = 2000 65535
net.ipv4.tcp_max_tw_buckets = 5000
vm.swappiness=10
EOF
}
# 关闭 IPv6
closeIpv6() {
printf "\n${CYAN}>>>> 关闭 IPv6${RESET}\n"
cat > /etc/modprobe.d/ipv6.conf << EOF
alias net-pf-10 off
options ipv6 disable=1
EOF
echo "NETWORKING_IPV6=off" >> /etc/sysconfig/network
}
# 入口函数
main() {
PS3="请选择要执行的操作:"
select ITEM in "配置 DNS" "配置 NTP" "关闭防火墙" "配置 IPv4" "关闭 IPv6" "全部执行"
do
case ${ITEM} in
"配置 DNS")
sh ${root}/set-dns.sh ;;
"配置 NTP")
sh ${root}/set-ntp.sh ;;
"关闭防火墙")
sh ${root}/stop-firewall.sh ;;
"配置 IPv4")
configIpv4 ;;
"关闭 IPv6")
closeIpv6 ;;
"全部执行")
sh ${root}/set-dns.sh
sh ${root}/set-ntp.sh
sh ${root}/stop-firewall.sh
configIpv4
closeIpv6
;;
*)
printf "\n${RED}输入项不支持${RESET}\n"
main
;;
esac
break
done
}
######################################## MAIN ########################################
root=$(pwd)
if [[ -n $1 ]]; then
root=$1
fi
printHeadInfo
main
================================================
FILE: codes/linux/sys/syscheck.sh
================================================
#!/usr/bin/env bash
##############################################################################
# console color
C_RESET="$(tput sgr0)"
C_BLACK="\033[1;30m"
C_RED="\033[1;31m"
C_GREEN="\033[1;32m"
C_YELLOW="\033[1;33m"
C_BLUE="\033[1;34m"
C_PURPLE="\033[1;35m"
C_CYAN="\033[1;36m"
C_WHITE="\033[1;37m"
##############################################################################
printf "${C_PURPLE}"
cat << EOF
###################################################################################
# 系统信息检查脚本
# @author: Zhang Peng
###################################################################################
EOF
printf "${C_RESET}"
[[ $(id -u) -gt 0 ]] && echo "请用root用户执行此脚本!" && exit 1
sysversion=$(rpm -q centos-release | cut -d- -f3)
double_line="==============================================================="
line="----------------------------------------------"
# 打印头部信息
printHeadInfo() {
cat << EOF
+---------------------------------------------------------------------------------+
| 欢迎使用 【系统信息检查脚本】 |
| @author: Zhang Peng |
+---------------------------------------------------------------------------------+
EOF
}
# 打印尾部信息
printFootInfo() {
cat << EOF
+---------------------------------------------------------------------------------+
| 脚本执行结束,感谢使用! |
+---------------------------------------------------------------------------------+
EOF
}
options=( "获取系统信息" "获取服务信息" "获取CPU信息" "获取系统网络信息" "获取系统内存信息" "获取系统磁盘信息" "获取CPU/内存占用TOP10" "获取系统用户信息" "输出所有信息" "退出" )
printMenu() {
printf "${C_BLUE}"
printf "主菜单:\n"
for i in "${!options[@]}"; do
index=`expr ${i} + 1`
val=`expr ${index} % 2`
printf "\t(%02d) %-30s" "${index}" "${options[$i]}"
if [[ ${val} -eq 0 ]]; then
printf "\n"
fi
done
printf "${C_BLUE}请输入需要执行的指令:\n"
printf "${C_RESET}"
}
# 获取系统信息
get_systatus_info() {
sys_os=$(uname -o)
sys_release=$(cat /etc/redhat-release)
sys_kernel=$(uname -r)
sys_hostname=$(hostname)
sys_selinux=$(getenforce)
sys_lang=$(echo $LANG)
sys_lastreboot=$(who -b | awk '{print $3,$4}')
sys_runtime=$(uptime | awk '{print $3,$4}' | cut -d, -f1)
sys_time=$(date)
sys_load=$(uptime | cut -d: -f5)
cat << EOF
【系统信息】
系统: ${sys_os}
发行版本: ${sys_release}
系统内核: ${sys_kernel}
主机名: ${sys_hostname}
selinux状态: ${sys_selinux}
系统语言: ${sys_lang}
系统当前时间: ${sys_time}
系统最后重启时间: ${sys_lastreboot}
系统运行时间: ${sys_runtime}
系统负载: ${sys_load}
EOF
}
# 获取CPU信息
get_cpu_info() {
Physical_CPUs=$(grep "physical id" /proc/cpuinfo | sort | uniq | wc -l)
Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l)
CPU_Kernels=$(grep "cores" /proc/cpuinfo | uniq | awk -F ': ' '{print $2}')
CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq)
CPU_Arch=$(uname -m)
cat << EOF
【CPU信息】
物理CPU个数:$Physical_CPUs
逻辑CPU个数:$Virt_CPUs
每CPU核心数:$CPU_Kernels
CPU型号:$CPU_Type
CPU架构:$CPU_Arch
EOF
}
# 获取服务信息
get_service_info() {
port_listen=$(netstat -lntup | grep -v "Active Internet")
kernel_config=$(sysctl -p 2> /dev/null)
if [[ ${sysversion} -gt 6 ]]; then
service_config=$(systemctl list-unit-files --type=service --state=enabled | grep "enabled")
run_service=$(systemctl list-units --type=service --state=running | grep ".service")
else
service_config=$(/sbin/chkconfig | grep -E ":on|:启用" | column -t)
run_service=$(/sbin/service --status-all | grep -E "running")
fi
cat << EOF
【服务信息】
${service_config}
${line}
运行的服务:
${run_service}
${line}
监听端口:
${port_listen}
${line}
内核参考配置:
${kernel_config}
EOF
}
# 获取系统内存信息
get_mem_info() {
check_mem=$(free -m)
MemTotal=$(grep MemTotal /proc/meminfo | awk '{print $2}') #KB
MemFree=$(grep MemFree /proc/meminfo | awk '{print $2}') #KB
let MemUsed=MemTotal-MemFree
MemPercent=$(awk "BEGIN {if($MemTotal==0){printf 100}else{printf \"%.2f\",$MemUsed*100/$MemTotal}}")
report_MemTotal="$((MemTotal/1024))" "MB" #内存总容量(MB)
report_MemFree="$((MemFree/1024))" "MB" #内存剩余(MB)
report_MemUsedPercent=$(free | sed -n '2p' | gawk 'x = int(( $3 / $2 ) * 100) {print x}' | sed 's/$/%/')
cat << EOF
【内存信息】
内存总容量(MB): ${report_MemTotal}
内存剩余量(MB):${report_MemFree}
内存使用率: ${report_MemUsedPercent}
EOF
}
# 获取系统网络信息
get_net_info() {
pri_ipadd=$(ip addr | awk '/^[0-9]+: / {}; /inet.*global/ {print gensub(/(.*)\/(.*)/, "\\1", "g", $2)}')
pub_ipadd=$(curl ifconfig.me -s)
gateway=$(ip route | grep default | awk '{print $3}')
mac_info=$(ip link | egrep -v "lo" | grep link | awk '{print $2}')
dns_config=$(egrep -v "^$|^#" /etc/resolv.conf)
route_info=$(route -n)
cat << EOF
【网络信息】
系统公网地址:${pub_ipadd}
系统私网地址:${pri_ipadd}
网关地址:${gateway}
MAC地址:${mac_info}
路由信息:
${route_info}
DNS 信息:
${dns_config}
EOF
}
# 获取系统磁盘信息
get_disk_info() {
disk_info=$(fdisk -l | grep "Disk /dev" | cut -d, -f1)
disk_use=$(df -hTP | awk '$2!="tmpfs"{print}')
disk_percent=$(free | sed -n '2p' | gawk 'x = int(( $3 / $2 ) * 100) {print x}' | sed 's/$/%/')
disk_inode=$(df -hiP | awk '$1!="tmpfs"{print}')
cat << EOF
【磁盘信息】
${disk_info}
磁盘使用: ${disk_use}
磁盘使用百分比: ${disk_percent}
inode信息: ${disk_inode}
EOF
}
# 获取系统用户信息
get_sys_user() {
login_user=$(awk -F: '{if ($NF=="/bin/bash") print $0}' /etc/passwd)
ssh_config=$(egrep -v "^#|^$" /etc/ssh/sshd_config)
sudo_config=$(egrep -v "^#|^$" /etc/sudoers | grep -v "^Defaults")
host_config=$(egrep -v "^#|^$" /etc/hosts)
crond_config=$(for cronuser in /var/spool/cron/*; do
ls ${cronuser} 2> /dev/null | cut -d/ -f5; egrep -v "^$|^#" ${cronuser} 2> /dev/null;
echo "";
done)
cat << EOF
【用户信息】
系统登录用户:
${login_user}
${line}
ssh 配置信息:
${ssh_config}
${line}
sudo 配置用户:
${sudo_config}
${line}
定时任务配置:
${crond_config}
${line}
hosts 信息:
${host_config}
EOF
}
# 获取CPU/内存占用TOP10
get_process_top_info() {
top_title=$(top -b n1 | head -7 | tail -1)
cpu_top10=$(top -b n1 | head -17 | tail -11)
mem_top10=$(top -b n1 | head -17 | tail -10 | sort -k10 -r)
cat << EOF
【TOP10】
CPU占用TOP10:
${cpu_top10}
内存占用TOP10:
${top_title}
${mem_top10}
EOF
}
show_dead_process() {
printf "僵尸进程:\n"
ps -al | gawk '{print $2,$4}' | grep Z
}
get_all_info() {
get_systatus_info
echo ${double_line}
get_service_info
echo ${double_line}
get_cpu_info
echo ${double_line}
get_net_info
echo ${double_line}
get_mem_info
echo ${double_line}
get_disk_info
echo ${double_line}
get_process_top_info
echo ${double_line}
get_sys_user
}
main() {
while [[ 1 ]]
do
printMenu
read option
local index=$[ ${option} - 1 ]
case ${options[${index}]} in
"获取系统信息")
get_systatus_info ;;
"获取服务信息")
get_service_info ;;
"获取CPU信息")
get_cpu_info ;;
"获取系统网络信息")
get_net_info ;;
"获取系统内存信息")
get_mem_info ;;
"获取系统磁盘信息")
get_disk_info ;;
"获取CPU/内存占用TOP10")
get_process_top_info ;;
"获取系统用户信息")
get_sys_user ;;
"输出所有信息")
get_all_info > sys.log
printf "${C_GREEN}信息已经输出到 sys.log 中。${C_RESET}\n\n"
;;
"退出")
exit ;;
*)
clear
echo "抱歉,不支持此选项" ;;
esac
done
}
######################################## MAIN ########################################
printHeadInfo
main
printFootInfo
printf "${C_RESET}"
================================================
FILE: codes/linux/sys/yum/Centos-5.repo
================================================
[base]
name=CentOS-$releasever - Base
baseurl=http://vault.centos.org/$releasever/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
#released updates
[updates]
name=CentOS-$releasever - Updates
baseurl=http://vault.centos.org/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras
baseurl=http://vault.centos.org/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus
baseurl=http://vault.centos.org/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib
baseurl=http://vault.centos.org/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-$releasever
================================================
FILE: codes/linux/sys/yum/Centos-6.repo
================================================
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-6
#released updates
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-6
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-6
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-6
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-6
================================================
FILE: codes/linux/sys/yum/Centos-7.repo
================================================
# CentOS-Base.repo
#
# The mirror system uses the connecting IP address of the client and the
# update status of each mirror to pick mirrors that are updated to and
# geographically close to the client. You should use this for CentOS updates
# unless you are manually picking other mirrors.
#
# If the mirrorlist= does not work for you, as a fall back you can try the
# remarked out baseurl= line instead.
#
#
[base]
name=CentOS-$releasever - Base - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/os/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/os/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/os/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#released updates
[updates]
name=CentOS-$releasever - Updates - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/updates/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/updates/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/updates/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that may be useful
[extras]
name=CentOS-$releasever - Extras - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/extras/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/extras/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/extras/$basearch/
gpgcheck=1
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#additional packages that extend functionality of existing packages
[centosplus]
name=CentOS-$releasever - Plus - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/centosplus/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/centosplus/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/centosplus/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
#contrib - packages by Centos Users
[contrib]
name=CentOS-$releasever - Contrib - mirrors.aliyun.com
failovermethod=priority
baseurl=http://mirrors.aliyun.com/centos/$releasever/contrib/$basearch/
http://mirrors.aliyuncs.com/centos/$releasever/contrib/$basearch/
http://mirrors.cloud.aliyuncs.com/centos/$releasever/contrib/$basearch/
gpgcheck=1
enabled=0
gpgkey=http://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-7
================================================
FILE: codes/linux/tool/Autoinstall_ELK_V1.3.sh
================================================
#!/usr/bin/env bash
#mail:xuel@anchnet.com
#data:2017/9/7
#AutoInstall ELK scripts
#Software:elasticsearch-5.4.1/logstash-5.4.1/filebeat-5.4.1/kibana-5.4.1
clear
echo "##########################################"
echo "# Auto Install ELK. ##"
echo "# Press Ctrl + C to cancel ##"
echo "# Any key to continue ##"
echo "##########################################"
read -p
software_dir="/usr/local/software"
elasticsearch_url="https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.4.1.tar.gz"
kibana_url="https://artifacts.elastic.co/downloads/kibana/kibana-5.4.1-linux-x86_64.tar.gz"
logstash_url="https://artifacts.elastic.co/downloads/logstash/logstash-5.4.1.tar.gz"
filebeat_url="https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.4.1-linux-x86_64.tar.gz"
sys_version=`cat /etc/redhat-release | awk '{print $4}' | cut -d. -f1`
IP=`ip addr | grep "inet " | grep -v 127.0.0.1 | awk '{print $2}' | cut -d/ -f1`
jvm_conf="/usr/local/elasticsearch/config/jvm.options"
sys_mem=`free -m | grep Mem: | awk '{print $2}' | awk '{sum+=$1} END {print sum/1024}' | cut -d. -f1`
#wget software
wget_fun() {
if [ ! -d ${software_dir} ]; then
mkdir -p ${software_dir} && cd ${software_dir}
else
cd ${software_dir}
fi
for software in $elasticsearch_url $kibana_url $logstash_url $filebeat_url
do
wget -c $software
done
clear
}
#initial system:install java wget;set hostname;disable firewalld
init_sys() {
[ -f /etc/init.d/functions ] && . /etc/init.d/functions
[ "${sys_version}" != "7" ] && echo "Error:This Scripts Support Centos7.xx" && exit 1
[ $(id -u) != "0" ] && echo "Error: You must be root to run this script" && exit 1
sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config
setenforce 0
yum install -y java-1.8.0-openjdk wget net-tools
hostnamectl set-hostname elk-server
systemctl stop firewalld
cat >> /etc/security/limits.conf << EOF
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
EOF
}
#install elasticsearch
install_elasticsearch() {
cd $software_dir
tar zxf elasticsearch-5.4.1.tar.gz
mv elasticsearch-5.4.1 /usr/local/elasticsearch
mkdir -p /usr/local/elasticsearch/data /usr/local/elasticsearch/logs
useradd elasticsearch
chown -R elasticsearch:elasticsearch /usr/local/elasticsearch
echo "vm.max_map_count = 655360" >> /etc/sysctl.conf && sysctl -p
if [ ${sys_mem} -eq 0 ]; then
sed -i "s#`grep "^-Xmx" ${jvm_conf}`#"-Xmx512m"#g" ${jvm_conf}
sed -i "s#`grep "^-Xms" ${jvm_conf}`#"-Xms512m"#g" ${jvm_conf}
else
sed -i "s#`grep "^-Xmx" ${jvm_conf}`#"-Xmx${sys_mem}g"#g" ${jvm_conf}
sed -i "s#`grep "^-Xms" ${jvm_conf}`#"-Xms${sys_mem}g"#g" ${jvm_conf}
fi
cat >> /usr/local/elasticsearch/config/elasticsearch.yml << EOF
cluster.name: my-application
node.name: elk-server
path.data: /usr/local/elasticsearch/data
path.logs: /usr/local/elasticsearch/logs
network.host: 127.0.0.1
http.port: 9200
discovery.zen.ping.unicast.hosts: ["elk-server"]
EOF
su - elasticsearch -c "nohup /usr/local/elasticsearch/bin/elasticsearch &"
}
#install logstash
install_logstash() {
cd $software_dir
tar -zxf logstash-5.4.1.tar.gz
mv logstash-5.4.1 /usr/local/logstash
cat > /usr/local/logstash/config/01-syslog.conf << EOF
input {
beats {
port => "5044"
}
}
output {
elasticsearch {
hosts => "127.0.0.1:9200"
}
stdout { codec => rubydebug }
}
EOF
nohup /usr/local/logstash/bin/logstash -f /usr/local/logstash/config/01-syslog.conf & > /dev/null
}
#install filebeat
install_filebeat() {
cd $software_dir
tar -zxf filebeat-5.4.1-linux-x86_64.tar.gz
mv filebeat-5.4.1-linux-x86_64 /usr/local/filebeat
cat > /usr/local/filebeat/filebeat.yml << EOF
filebeat.prospectors:
- input_type: log
paths:
- /var/log/*.log
output.logstash:
hosts: ["127.0.0.1:5044"]
EOF
cd /usr/local/filebeat/
nohup /usr/local/filebeat/filebeat & > /dev/null
}
#install kibana
install_kibana() {
cd $software_dir
tar -zxf kibana-5.4.1-linux-x86_64.tar.gz
mv kibana-5.4.1-linux-x86_64 /usr/local/kibana
cat >> /usr/local/kibana/config/kibana.yml << EOF
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.url: "http://127.0.0.1:9200"
EOF
nohup /usr/local/kibana/bin/kibana & > /dev/null
}
check() {
port=$1
program=$2
check_port=`netstat -lntup | grep ${port} | wc -l`
check_program=`ps -ef | grep ${program} | grep -v grep | wc -l`
if [ $check_port -gt 0 ] && [ $check_program -gt 0 ]; then
action "${program} run is ok!" /bin/true
else
action "${program} run is error!" /bin/false
fi
}
main() {
init_sys
wget_fun
install_elasticsearch
install_filebeat
install_logstash
install_kibana
echo -e "\033[32m Checking Elasticsearch...\033[0m"
sleep 20
check :9200 "elasticsearch"
echo -e "\033[32m Checking Logstash...\033[0m"
sleep 2
check ":9600" "logstash"
echo -e "\033[32m Checking Kibana...\033[0m"
sleep 2
check ":5601" "kibana"
action "ELK install is success!" /bin/true
echo "url:http://$IP:5601"
}
main
================================================
FILE: codes/linux/tool/Cpu_Limit.sh
================================================
#!/usr/bin/env bash
# auth:kaliarch
# func:sys info check
# version:v1.0
# sys:centos6.x/7.x
set -e
[ $(id -u) -gt 0 ] && exit 1
# cpu使用超过百分之多少进行限制
PEC_CPU=80
# 限制进程使用百分之多少,如果程序为多线程,单个cpu限制为85,如果为多核心,就需要按照比例写,例如cpu为2c,像限制多线程占比80%,就写170
LIMIT_CPU=85
# 日志
LOG_DIR=/var/log/cpulimit/
# 超过阀值进程pid
PIDARG=$(ps -aux | awk -v CPU=${PEC_CPU} '{if($3 > CPU) print $2}')
CPULIMITCMD=$(which cpulimit)
install_cpulimit() {
[ ! -d /tmp ] && mkdir /tmp || cd /tmp
wget -c https://github.com/opsengine/cpulimit/archive/v0.2.tar.gz
tar -zxf v0.2.tar.gz
cd cpulimit-0.2 && make
[ $? -eq 0 ] && cp src/cpulimit /usr/bin/
}
do_cpulimit() {
[ ! -d ${LOG_DIR} ] && mkdir -p ${LOG_DIR}
for i in ${PIDARG};
do
MSG=$(ps -aux | awk -v pid=$i '{if($2 == pid) print $0}')
echo ${MSG}
[ ! -d /tmp ] && mkdir /tmp || cd /tmp
nohup ${CPULIMITCMD} -p $i -l ${LIMIT_CPU} &
echo "$(date) -- ${MSG}" >> ${LOG_DIR}$(date +%F).log
done
}
main() {
hash cpulimit
if [ $? -eq 0 ]; then
do_cpulimit
else
install_cpulimit && do_cpulimit
fi
}
main
================================================
FILE: codes/linux/tool/Custom_Rm.sh
================================================
#!/usr/bin/env bash
# function:自定义rm命令,每天晚上定时清理
CMD_SCRIPTS=$HOME/.rm_scripts.sh
TRASH_DIR=$HOME/.TRASH_DIR
CRON_FILE=/var/spool/cron/root
BASHRC=$HOME/.bashrc
[ ! -d ${TRASH_DIR} ] && mkdir -p ${TRASH_DIR}
cat > $CMD_SCRIPTS << EOF
PARA_CNT=\$#
TRASH_DIR=$TRASH_DIR
for i in \$*; do
DATE=\$(date +%F%T)
fileName=\$(basename \$i)
mv \$i \$TRASH_DIR/\$fileName.\$DATE
done
EOF
sed -i "s@$(grep 'alias rm=' $BASHRC)@alias rm='bash ${CMD_SCRIPTS}'@g" $BASHRC
source $HOME/.bashrc
echo "0 0 * * * rm -rf $TRASH_DIR/*" >> $CRON_FILE
echo "删除目录:$TRASH_DIR"
echo "删除脚本:$CMD_SCRIPTS"
echo "请执行:source $BASHRC 来加载文件或退出当前shell重新登录"
================================================
FILE: codes/linux/tool/Daily_Archive.sh
================================================
#!/usr/bin/env bash
#
# Daily_Archive - Archive designated files & directories
######################################################
#
# Gather Current Date
#
DATE=`date +%y%m%d`
#
# Set Archive File Name
#
FILE=archive$DATE.tar.gz
#
# Set Configuration and Destination File
#
CONFIG_FILE=/home/tiandi/archive/Files_To_Backup
DESTINATION=/home/tiandi/archive/$FILE
#
##################### Main Script ###############
#
# Check Backup Config file exists
#
if [ -f $CONFIG_FILE ] #Make sure the config file still exists
then
echo
else
echo
echo "$CONFIG_FILE does not exist."
echo "Backup not completed due to missing Configuration file"
echo
exit
fi
#
# Build the names of all the files to backup
#
FILE_NO=1 # Start on Line 1 of Config file.
exec < $CONFIG_FILE # Redirect Std Input to name of Config File
#
read FILE_NAME # Read 1st record
#
while [ $? -eq 0 ]
do
# Make sure the file or directory exists.
if [ -f $FILE_NAME -o -d $FILE_NAME ]
then
# If file exists, add its name to the lists
FILE_LIST="$FILE_LIST $FILE_NAME"
else
# If file doesn't exist, issue warning
echo
echo "$FILE_NAME, does not exist."
echo "Obviously, I will not include it in this archive."
echo "It is listed on line $FILE_NO of the config file."
echo "Continuing to build archive file."
echo
fi
#
FILE_NO=$[ $FILE_NO + 1 ] # Increase Line/File number by one
read FILE_NAME # Read next record.
done
###########################################################
#
# Backup the files and Compress Archive
#
tar -czf $DESTINATION $FILE_LIST 2> /dev/null
#
================================================
FILE: codes/linux/tool/Hourly_Archive.sh
================================================
#!/usr/bin/env bash
#
# Hourly_Archive - Every hour create an archive
######################################################
#
# Set Configuration and Destination File
#
CONFIG_FILE=/home/tiandi/archive/Files_To_Backup
#
# Gather Current Date,Month & Time
#
DAY=`date +%d`
MONTH=`date +%m`
TIME=`date +%k%M`
#
# Set Base Archive Destination Location
#
BASEDEST=/home/tiandi/archive/hourly
#
# Create Archive Destination Directory
mkdir -p $BASEDEST/$MONTH/$DAY
#
# Build Archive Destination File Name
DESTINATION=$BASEDEST/$MONTH/$DAY/archive$TIME.tar.gz
#
##################### Main Script ###############
#
# Check Backup Config file exists
#
if [ -f $CONFIG_FILE ] #Make sure the config file still exists
then
echo
else
echo
echo "$CONFIG_FILE does not exist."
echo "Backup not completed due to missing Configuration file"
echo
exit
fi
#
# Build the names of all the files to backup
#
FILE_NO=1 # Start on Line 1 of Config file.
exec < $CONFIG_FILE # Redirect Std Input to name of Config File
#
read FILE_NAME # Read 1st record
#
while [ $? -eq 0 ]
do
# Make sure the file or directory exists.
if [ -f $FILE_NAME -o -d $FILE_NAME ]
then
# If file exists, add its name to the lists
FILE_LIST="$FILE_LIST $FILE_NAME"
else
# If file doesn't exist, issue warning
echo
echo "$FILE_NAME, does not exist."
echo "Obviously, I will not include it in this archive."
echo "It is listed on line $FILE_NO of the config file."
echo "Continuing to build archive file."
echo
fi
#
FILE_NO=$[ $FILE_NO + 1 ] # Increase Line/File number by one
read FILE_NAME # Read next record.
done
###########################################################
#
# Backup the files and Compress Archive
#
tar -czf $DESTINATION $FILE_LIST 2> /dev/null
#
================================================
FILE: codes/linux/tool/gitcheck
================================================
#!/bin/sh
###################################################################################
# 此脚本用于检测 git 状态
# Copy from https://github.com/fboender/multi-git-status
###################################################################################
# MIT license
if [ -t 1 ]; then
# Our output is not being redirected, so we can use colors.
C_RED="\033[1;31m"
C_GREEN="\033[1;32m"
C_YELLOW="\033[1;33m"
C_BLUE="\033[1;34m"
C_PURPLE="\033[1;35m"
C_CYAN="\033[1;36m"
C_RESET="$(tput sgr0)"
fi
C_OK="$C_GREEN"
C_LOCKED="$C_RED"
C_NEEDS_PUSH="$C_YELLOW"
C_NEEDS_PULL="$C_BLUE"
C_NEEDS_COMMIT="$C_RED"
C_NEEDS_UPSTREAM="$C_PURPLE"
C_UNTRACKED="$C_CYAN"
C_STASHES="$C_YELLOW"
DEBUG=0
usage() {
cat << EOF >&2
Usage: $0 [-w] [-e] [-f] [--no-X] [DIR] [DEPTH=2]
Scan for .git dirs under DIR (up to DEPTH dirs deep) and show git status
-w Warn about dirs that are not Git repositories
-e Exclude repos that are 'ok'
-f Do a 'git fetch' on each repo (slow for many repos)
You can limit output with the following options:
--no-push
--no-pull
--no-upstream
--no-uncommitted
--no-untracked
--no-stashes
EOF
}
# Handle commandline options
WARN_NOT_REPO=0
EXCLUDE_OK=0
DO_FETCH=0
NO_PUSH=0
NO_PULL=0
NO_UPSTREAM=0
NO_UNCOMMITTED=0
NO_UNTRACKED=0
NO_STASHES=0
while [ \! -z "$1" ]; do
# Stop reading when we've run out of options.
[ "$(echo "$1" | cut -c 1)" != "-" ] && break
if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
usage
exit 1
fi
if [ "$1" = "-w" ]; then
WARN_NOT_REPO=1
fi
if [ "$1" = "-e" ]; then
EXCLUDE_OK=1
fi
if [ "$1" = "-f" ]; then
DO_FETCH=1
fi
if [ "$1" = "--no-push" ]; then
NO_PUSH=1
fi
if [ "$1" = "--no-pull" ]; then
NO_PULL=1
fi
if [ "$1" = "--no-upstream" ]; then
NO_UPSTREAM=1
fi
if [ "$1" = "--no-uncommitted" ]; then
NO_UNCOMMITTED=1
fi
if [ "$1" = "--no-untracked" ]; then
NO_UNTRACKED=1
fi
if [ "$1" = "--no-stashes" ]; then
NO_STASHES=1
fi
shift
done
if [ -z "$1" ]; then
ROOT_DIR="."
else
ROOT_DIR="$1"
fi
if [ -z "$2" ]; then
DEPTH=2
else
DEPTH="$2"
fi
# Find all .git dirs, up to DEPTH levels deep
find -L "$ROOT_DIR" -maxdepth "$DEPTH" -type d | while read -r PROJ_DIR
do
GIT_DIR="$PROJ_DIR/.git"
# If this dir is not a repo, and WARN_NOT_REPO is 1, tell the user.
if [ \! -d "$GIT_DIR" ]; then
if [ "$WARN_NOT_REPO" -eq 1 ] && [ "$PROJ_DIR" != "." ]; then
printf "${PROJ_DIR}: not a git repo\n"
fi
continue
fi
[ $DEBUG -eq 1 ] && echo "${PROJ_DIR}"
# Check if repo is locked
if [ -f "$GIT_DIR/index.lock" ]; then
printf "${PROJ_DIR}: ${C_LOCKED}Locked. Skipping.${C_RESET}\n"
continue
fi
# Do a 'git fetch' if requested
if [ "$DO_FETCH" -eq 1 ]; then
git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" fetch -q > /dev/null
fi
# Refresh the index, or we might get wrong results.
git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" update-index -q --refresh > /dev/null 2>&1
# Find all remote branches that have been checked out and figure out if
# they need a push or pull. We do this with various tests and put the name
# of the branches in NEEDS_XXXX, seperated by newlines. After we're done,
# we remove duplicates from NEEDS_XXX.
NEEDS_PUSH_BRANCHES=""
NEEDS_PULL_BRANCHES=""
NEEDS_UPSTREAM_BRANCHES=""
for REF_HEAD in $(cd "$GIT_DIR/refs/heads" && find . -type 'f' | sed "s/^\.\///"); do
# Check if this branch is tracking an upstream (local/remote branch)
UPSTREAM=$(git --git-dir "$GIT_DIR" rev-parse --abbrev-ref --symbolic-full-name "$REF_HEAD@{u}" 2> /dev/null)
EXIT_CODE="$?"
if [ "$EXIT_CODE" -eq 0 ]; then
# Branch is tracking a remote branch. Find out how much behind /
# ahead it is of that remote branch.
CNT_AHEAD_BEHIND=$(git --git-dir "$GIT_DIR" rev-list --left-right --count "$REF_HEAD...$UPSTREAM")
CNT_AHEAD=$(echo "$CNT_AHEAD_BEHIND" | awk '{ print $1 }')
CNT_BEHIND=$(echo "$CNT_AHEAD_BEHIND" | awk '{ print $2 }')
[ $DEBUG -eq 1 ] && echo "CNT_AHEAD_BEHIND: $CNT_AHEAD_BEHIND"
[ $DEBUG -eq 1 ] && echo "CNT_AHEAD: $CNT_AHEAD"
[ $DEBUG -eq 1 ] && echo "CNT_BEHIND: $CNT_BEHIND"
if [ "$CNT_AHEAD" -gt 0 ]; then
NEEDS_PUSH_BRANCHES="${NEEDS_PUSH_BRANCHES}\n$REF_HEAD"
fi
if [ "$CNT_BEHIND" -gt 0 ]; then
NEEDS_PULL_BRANCHES="${NEEDS_PULL_BRANCHES}\n$REF_HEAD"
fi
# Check if this branch is a branch off another branch. and if it needs
# to be updated.
REV_LOCAL=$(git --git-dir "$GIT_DIR" rev-parse --verify "$REF_HEAD" 2> /dev/null)
REV_REMOTE=$(git --git-dir "$GIT_DIR" rev-parse --verify "$UPSTREAM" 2> /dev/null)
REV_BASE=$(git --git-dir "$GIT_DIR" merge-base "$REF_HEAD" "$UPSTREAM" 2> /dev/null)
[ $DEBUG -eq 1 ] && echo "REV_LOCAL: $REV_LOCAL"
[ $DEBUG -eq 1 ] && echo "REV_REMOTE: $REV_REMOTE"
[ $DEBUG -eq 1 ] && echo "REV_BASE: $REV_BASE"
if [ "$REV_LOCAL" = "$REV_REMOTE" ]; then
: # NOOP
else
if [ "$REV_LOCAL" = "$REV_BASE" ]; then
NEEDS_PULL_BRANCHES="${NEEDS_PULL_BRANCHES}\n$REF_HEAD"
fi
if [ "$REV_REMOTE" = "$REV_BASE" ]; then
NEEDS_PUSH_BRANCHES="${NEEDS_PUSH_BRANCHES}\n$REF_HEAD"
fi
fi
else
# Branch does not have an upstream (local/remote branch).
NEEDS_UPSTREAM_BRANCHES="${NEEDS_UPSTREAM_BRANCHES}\n$REF_HEAD"
fi
done
# Remove duplicates from NEEDS_XXXX and make comma-seperated
NEEDS_PUSH_BRANCHES=$(printf "$NEEDS_PUSH_BRANCHES" | sort | uniq | tr '\n' ',' | sed "s/^,\(.*\),$/\1/")
NEEDS_PULL_BRANCHES=$(printf "$NEEDS_PULL_BRANCHES" | sort | uniq | tr '\n' ',' | sed "s/^,\(.*\),$/\1/")
NEEDS_UPSTREAM_BRANCHES=$(printf "$NEEDS_UPSTREAM_BRANCHES" | sort | uniq | tr '\n' ',' | sed "s/^,\(.*\),$/\1/")
# Find out if there are unstaged, uncommitted or untracked changes
UNSTAGED=$(git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" diff-index --quiet HEAD -- 2> /dev/null;
echo $?)
UNCOMMITTED=$(git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" diff-files --quiet --ignore-submodules --;
echo $?)
UNTRACKED=$(git --work-tree "$(dirname "$GIT_DIR")" --git-dir "$GIT_DIR" ls-files --exclude-standard --others)
cd "$(dirname "$GIT_DIR")" || exit
STASHES=$(git stash list | wc -l)
cd "$OLDPWD" || exit
# Build up the status string
IS_OK=0 # 0 = Repo needs something, 1 = Repo needs nothing ('ok')
STATUS_NEEDS=""
if [ \! -z "$NEEDS_PUSH_BRANCHES" ] && [ "$NO_PUSH" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_NEEDS_PUSH}Needs push ($NEEDS_PUSH_BRANCHES)${C_RESET} "
fi
if [ \! -z "$NEEDS_PULL_BRANCHES" ] && [ "$NO_PULL" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_NEEDS_PULL}Needs pull ($NEEDS_PULL_BRANCHES)${C_RESET} "
fi
if [ \! -z "$NEEDS_UPSTREAM_BRANCHES" ] && [ "$NO_UPSTREAM" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_NEEDS_UPSTREAM}Needs upstream ($NEEDS_UPSTREAM_BRANCHES)${C_RESET} "
fi
if [ "$UNSTAGED" -ne 0 ] || [ "$UNCOMMITTED" -ne 0 ] && [ "$NO_UNCOMMITTED" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_NEEDS_COMMIT}Uncommitted changes${C_RESET} "
fi
if [ "$UNTRACKED" != "" ] && [ "$NO_UNTRACKED" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_UNTRACKED}Untracked files${C_RESET} "
fi
if [ "$STASHES" -ne 0 ] && [ "$NO_STASHES" -eq 0 ]; then
STATUS_NEEDS="${STATUS_NEEDS}${C_STASHES}$STASHES stashes${C_RESET} "
fi
if [ "$STATUS_NEEDS" = "" ]; then
IS_OK=1
STATUS_NEEDS="${STATUS_NEEDS}${C_OK}ok${C_RESET} "
fi
# Print the output, unless repo is 'ok' and -e was specified
if [ "$IS_OK" -ne 1 ] || [ "$EXCLUDE_OK" -ne 1 ]; then
printf "${PROJ_DIR}: $STATUS_NEEDS\n"
fi
done
================================================
FILE: codes/linux/tool/删除用户脚本.sh
================================================
#!/usr/bin/env bash
#
# Delete_User - Automates the 4 steps to remove an account
#
#################################################################
#
# Define Functions
#
#################################################################
function get_answer {
#
unset ANSWER
ASK_COUNT=0
#
while [ -z "$ANSWER" ] # while no answer is given, keep asking
do
ASK_COUNT=$[ $ASK_COUNT + 1 ]
#
case $ASK_COUNT in
# If user gives no answer in time allowed
2)
echo
echo "Please answer the question."
echo
;;
3)
echo
echo "One last try... please answer the question."
echo
;;
4)
echo
echo "Since you refuse to answer the question..."
echo "exiting program."
echo
#
exit
;;
esac
#
echo
#
if [ -n "$LINE2" ]
then
echo $LINE1 # Print 2 lines
echo -e $LINE2" \c"
else
# Print 1 line
echo -e $LINE1" \c"
fi
#
# Allow 60 seconds to answer before time-out
read -t 60 ANSWER
done
#
# Do a little variable clean-up
#
unset LINE1
unset LINE2
#
}
#end of get_answer function
#
#################################################################
function process_answer {
#
case $ANSWER in
y | Y | YES | yes | yEs | yeS | YEs | yES)
# If user answers "yes".do nothing.
;;
*)
# If user answers anything but "yes", exit script
echo
echo $EXIT_LINE1
echo $EXIT_LINE2
echo
exit
;;
esac
#
# Do a little variable clean-up
unset EXIT_LINE1
unset EXIT_LINE2
#
}
#End of process_answer function
#
################################################################
#
# End of Function Definitions
#
############### Main Script #################################
#
# Get name of User Account to check
#
echo "Step #1 - Determine User Account name to delete "
echo
LINE1="Please enter the username of the user"
LINE2="account you wish to delete from system:"
get_answer
USER_ACCOUNT=$ANSWER
#
# Double check with script user that this is the correct User Account
#
LINE1="Is $USER_ACCOUNT the user account"
LINE2="you wish to delete from the system?[ y/n ]:"
get_answer
#
############################################################
#
# Check that USER_ACCOUNT is really an account on the system
#
USER_ACCOUNT_RECORD=$(cat /etc/passwd | grep -w $USER_ACCOUNT)
#
if [ $? -eq 1 ] # If the account is not found, exit script
then
echo
echo "Account, $USER_ACCOUNT, not found."
echo "Leaving the script..."
echo
exit
fi
#
echo
echo "I found this record:"
echo $USER_ACCOUNT_RECORD
echo
#
LINE1="Is this the correct User Account?[y/n]:"
get_answer
#
#
# Call process_answer function:
# if user answers anything but "yes", exit script
#
EXIT_LINE1="Because the account, $USER_ACCOUNT, is not "
EXIT_LINE2="the one you wish to delete, we are leaving the script..."
process_anser
#
##############################################################
#
# Search for any running processes that belong to the User Account
#
echo
echo "Step #2 - Find process on system belonging to user account"
echo
echo "$USER_ACCOUNT has the following processes running: "
echo
#
ps -u $USER_ACCOUNT #List the processes running
#
case $? in
1) # No processes running for this User Account
#
echo "There are no processes for this account currently running."
echo
;;
0) # Processes running for this User Account.
# Ask Script User if wants us to kill the processes.
#
unset ANSWER # I think this line is not needed
LINE1="Would you like me to kill the process(es)? [y/n]:"
get_answer
#
case $ANSWER in
y | Y | YES | yes | Yes | yEs | yeS | YEs | yES) # if user answer "yes",
#kill User Account processes
#
echo
#
# Clean-up temp file upon signals
#
trap "rm$USER_ACCOUNT_Running_Process.rpt" SIGTERM SIGINT SIGQUIT
#
# List user processes running
ps -u $USER_ACCOUNT > $USER_ACCOUNT_Running_Process.rpt
#
exec < $USER_ACCOUNT_Running_Process.rpt # Make report Std Input
#
read USER_PROCESS_REC # First record will be blank
read USER_PROCESS_REC
#
while [ $? -eq 0 ]
do
# obtain PID
USER_PID=$(echo $USER_PROCESS_REC | cut -d " " -f1)
kill -9 $USER_PID
echo "Killed process $USER_PID"
read USER_PROCESS_REC
done
#
echo
#
rm $USER_ACCOUNT_Running_Process.rpt # Remove temp report
;;
*) # If user answers anything but "yes", do not kill.
echo
echo "Will not kill the process(es)."
echo
;;
esac
;;
esac
###################################################################################
#
# Create a report of all files owned by User Account
#
echo
echo "Step #3 - Find files on system belonging to user account"
echo
echo "Creating a report of all files owned by $USER_ACCOUNT."
echo
echo "It is recommended that you backup/archive these files."
echo "and then do one of two things:"
echo " 1) Delete the files"
echo " 2) Change the files' ownership to a current user account."
echo
echo "Please wait. This may take a while..."
#
REPORT_DATE=`date +%y%m%d`
REPORT_FILE=$USER_ACCOUNT"_Files_"$REPORT_DATE".rpt"
#
find / -user $USER_ACCOUNT > $REPORT_FILE 2> /dev/null
#
echo
echo "Report is complete."
echo "Name of report: $REPORT_FILE"
echo "Location of report: `pwd`"
echo
################################################################
#
# Remove User Account
echo
echo "Step #4 - Remove user account"
echo
#
LINE1="Do you wish to remove $USER_ACCOUNT's account from system? [y/n]:"
get_answer
#
# Cass process_answer function:
# if user answers anything but "yes", exit script
#
EXIT_LINE1="Since you do not wish to remove the user account."
EXIT_LINE2="$USER_ACCOUNT at this time, exiting the script..."
process_answer
#
userdel $USER_ACCOUNT # delete user account
echo
echo "User account, $USER_ACCOUNT, has been removed"
echo
#
================================================
FILE: codes/linux/tool/查看指定目录磁盘使用情况.sh
================================================
#!/usr/bin/env bash
#DIRS="/var/log /home /opt"
#DATE=$(date '+%m%d%y')
#exec > disk_space_${DATE}.log
echo "Top Ten Disk Space Usage"
echo "for ${DIRS} Directories"
for DIR in ${DIRS}
do
echo ""
echo "The ${DIR} Directory:"
du -S ${DIR} 2> /dev/null |
sort -rn |
sed '{11,$D; =}' |
sed 'N; s/\n/ /' |
gawk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
done
================================================
FILE: codes/shell/README.md
================================================
# Shell 脚本大全
> **Shell 脚本大全** 精心收集、整理了 Linux 环境下的常见 Shell 脚本操作片段。
>
> 当您面临以下问题时,**Shell 脚本大全** 也许可以给你一些借鉴:
>
> - 你想要执行某个操作,却不知 Shell 命令如何写
> - 你想要快速掌握 Shell 基本用法
## 参考资料
- [pure-bash-bible](https://github.com/dylanaraps/pure-bash-bible#change-a-string-to-lowercase)
================================================
FILE: codes/shell/lib/env.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------ 颜色状态
# Regular Color
C_BLACK="\033[0;30m"
C_RED="\033[0;31m"
C_GREEN="\033[0;32m"
C_YELLOW="\033[0;33m"
C_BLUE="\033[0;34m"
C_MAGENTA="\033[0;35m"
C_CYAN="\033[0;36m"
C_WHITE="\033[0;37m"
# Bold Color
C_B_BLACK="\033[1;30m"
C_B_RED="\033[1;31m"
C_B_GREEN="\033[1;32m"
C_B_YELLOW="\033[1;33m"
C_B_BLUE="\033[1;34m"
C_B_MAGENTA="\033[1;35m"
C_B_CYAN="\033[1;36m"
C_B_WHITE="\033[1;37m"
# Underline Color
C_U_BLACK="\033[4;30m"
C_U_RED="\033[4;31m"
C_U_GREEN="\033[4;32m"
C_U_YELLOW="\033[4;33m"
C_U_BLUE="\033[4;34m"
C_U_MAGENTA="\033[4;35m"
C_U_CYAN="\033[4;36m"
C_U_WHITE="\033[4;37m"
# Background Color
C_BG_BLACK="\033[40m"
C_BG_RED="\033[41m"
C_BG_GREEN="\033[42m"
C_BG_YELLOW="\033[43m"
C_BG_BLUE="\033[44m"
C_BG_MAGENTA="\033[45m"
C_BG_CYAN="\033[46m"
C_BG_WHITE="\033[47m"
# Reset Color
C_RESET="$(tput sgr0)"
# ------------------------------------------------------------------------------ 常用状态值
YES=0
NO=1
SUCCEED=0
FAILED=1
================================================
FILE: codes/shell/mysql/SQL批处理执行脚本.sh
================================================
#!/usr/bin/env bash
user='root'
password='xxxxxx'
database='test'
for f in `ls */*.sql`
do
echo ${f};
mysql -u${user} -p${password} -f ${database} -e "source $f";
done
echo 'OK!'
================================================
FILE: codes/shell/mysql/向数据库中插入数据.sh
================================================
#!/usr/bin/env bash
# send data to the the table in the MYSQL database
MYSQL=`which mysql`
if [ $# -ne 2 ]
then
echo "Usage:mtest2 emplid lastname firstname salary"
else
#脚本变量一定要用双引号,字符串变量使用单引号
statement=" insert into em_admin values(NULL, '$1', $2)"
$MYSQL emwjs -u test << EOF
$statement
EOF
if [ $? -eq 0 ]
then
echo Data successfully added
else
echo Problem adding data
fi
fi
================================================
FILE: codes/shell/mysql/格式化输出数据.sh
================================================
#!/usr/bin/env bash
#redirecting SQL output to a variable
MYSQL=`which mysql`
dbs=`$MYSQL emwjs -u test -Bse 'show tables;'`
for db in $dbs
do
echo $db
done
#使用xml输出数据
$MYSQL emwjs -u test -X -e 'select * from em_admin'
#使用table标签输出数据
$MYSQL emwjs -u test -H -e 'select * from em_admin'
================================================
FILE: codes/shell/mysql/连接数据库并发送命令.sh
================================================
#!/usr/bin/env bash
#连接数据库
mysql=`which mysql`
#发送单个命令
$mysql emwjs -u test -e "show databases;"
#发送多个命令
$mysql emwjs -u test << EOF
show tables;
select * from em_admin;
EOF
================================================
FILE: codes/shell/基本脚本/echo示例.sh
================================================
#!/usr/bin/env bash
# 输出普通字符串
echo "hello, world"
# Output: hello, world
# 输出含变量的字符串
echo "hello, \"zp\""
# Output: hello, "zp"
# 输出含变量的字符串
name=zp
echo "hello, \"${name}\""
# Output: hello, "zp"
# 输出含换行符的字符串
echo "YES\nNO"
# Output: YES\nNO
echo -e "YES\nNO" # -e 开启转义
# Output:
# YES
# NO
# 输出含不换行符的字符串
echo "YES"
echo "NO"
# Output:
# YES
# NO
echo -e "YES\c" # -e 开启转义 \c 不换行
echo "NO"
# Output:
# YESNO
# 输出内容定向至文件
echo "test" > test.txt
# 输出执行结果
echo `pwd`
# Output:(当前目录路径)
================================================
FILE: codes/shell/基本脚本/exit命令.sh
================================================
#!/usr/bin/env bash
#退出状态码,最大为255,超过则进行模运算
#testing the exit status
var1=10
var2=20
var3=$[ $var1 + $var2 ]
echo The answer is $var3
exit 5
================================================
FILE: codes/shell/基本脚本/printf示例.sh
================================================
#!/usr/bin/env bash
# 单引号
printf '%d %s\n' 1 "abc"
# Output:1 abc
# 双引号
printf "%d %s\n" 1 "abc"
# Output:1 abc
# 无引号
printf %s abcdef
# Output: abcdef(并不会换行)
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出
printf "%s\n" abc def
# Output:
# abc
# def
printf "%s %s %s\n" a b c d e f g h i j
# Output:
# a b c
# d e f
# g h i
# j
# 如果没有参数,那么 %s 用 NULL 代替,%d 用 0 代替
printf "%s and %d \n"
# Output:
# and 0
# 格式化输出
printf "%-10s %-8s %-4s\n" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f\n" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f\n" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f\n" 郭芙 女 47.9876
# Output:
# 姓名 性别 体重kg
# 郭靖 男 66.12
# 杨过 男 48.65
# 郭芙 女 47.99
================================================
FILE: codes/shell/基本脚本/使用expr执行数学运算.sh
================================================
#!/usr/bin/env bash
#An example of using the expr command
var1=10
var2=20
var3=`expr $var2 / $var1`
echo "The result is $var3"
================================================
FILE: codes/shell/基本脚本/使用内联重定向计算表达式.sh
================================================
#!/usr/bin/env bash
var1=10.45
var2=43.67
var3=33.2
var4=71
var5=`bc << EOF
scale=4
a1 = $var1 * $var2
b1 = $var3 * $var4
a1 + b1
EOF
`
echo The final answer for this mess is $var5
================================================
FILE: codes/shell/基本脚本/使用方括号执行数学运算.sh
================================================
#!/usr/bin/env bash
var1=10
var2=50
var3=45
var4=$[ $var1 * ( $var2 - $var3 ) ]
echo 'The final result is '$var4
================================================
FILE: codes/shell/基本脚本/反引号的使用.sh
================================================
#!/usr/bin/env bash
#using the backtick character 会把反引号里面当作一条命令来执行
testing=`date`
echo "The date and time are:$testing"
================================================
FILE: codes/shell/基本脚本/变量使用示例.sh
================================================
#!/usr/bin/env bash
################### 声明变量 ###################
name="world"
echo "hello ${name}"
# Output: hello world
################### 输出变量 ###################
folder=$(pwd)
echo "current path: ${folder}"
################### 只读变量 ###################
rword="hello"
echo ${rword}
# Output: hello
readonly rword
# rword="bye" # 如果放开注释,执行时会报错
################### 删除变量 ###################
dword="hello" # 声明变量
echo ${dword} # 输出变量值
# Output: hello
unset dword # 删除变量
echo ${dword}
# Output: (空)
################### 系统变量 ###################
echo "UID:$UID"
echo LOGNAME:$LOGNAME
echo User:$USER
echo HOME:$HOME
echo PATH:$PATH
echo HOSTNAME:$HOSTNAME
echo SHELL:$SHELL
echo LANG:$LANG
################### 自定义变量 ###################
days=10
user="admin"
echo "$user logged in $days days age"
days=5
user="root"
echo "$user logged in $days days age"
# Output:
# admin logged in 10 days age
# root logged in 5 days age
################### 从变量读取列表 ###################
colors="Red Yellow Blue"
colors=$colors" White Black"
for color in $colors
do
echo " $color"
done
================================================
FILE: codes/shell/基本脚本/在脚本中使用bc.sh
================================================
#!/usr/bin/env bash
var1=100
var2=45
var3=`echo "scale=4; $var1 / $var2" | bc`
echo The answer for this is $var3
================================================
FILE: codes/shell/基本脚本/字符串使用示例.sh
================================================
#!/usr/bin/env bash
################### 使用单引号拼接字符串 ###################
name1='white'
str1='hello, '${name1}''
str2='hello, ${name1}'
echo ${str1}_${str2}
# Output:
# hello, white_hello, ${name1}
################### 使用双引号拼接字符串 ###################
name2="black"
str3="hello, "${name2}""
str4="hello, ${name2}"
echo ${str3}_${str4}
# Output:
# hello, black_hello, black
################### 获取字符串长度 ###################
text="12345"
echo "${text} length is: ${#text}"
# Output:
# 12345 length is: 5
# 获取子字符串
text="12345"
echo ${text:2:2}
# Output:
# 34
################### 查找子字符串 ###################
text="hello"
echo `expr index "${text}" ll`
# Output:
# 3
################### 判断字符串中是否包含子字符串 ###################
result=$(echo "${str}" | grep "feature/")
if [[ "$result" != "" ]]; then
echo "feature/ 是 ${str} 的子字符串"
else
echo "feature/ 不是 ${str} 的子字符串"
fi
################### 截取关键字左边内容 ###################
full_branch="feature/1.0.0"
branch=`echo ${full_branch#feature/}`
echo "branch is ${branch}"
################### 截取关键字右边内容 ###################
full_version="0.0.1-SNAPSHOT"
version=`echo ${full_version%-SNAPSHOT}`
echo "version is ${version}"
################### 字符串分割成数组 ###################
str="0.0.0.1"
OLD_IFS="$IFS"
IFS="."
array=( ${str} )
IFS="$OLD_IFS"
size=${#array[*]}
lastIndex=`expr ${size} - 1`
echo "数组长度:${size}"
echo "最后一个数组元素:${array[${lastIndex}]}"
for item in ${array[@]}
do
echo "$item"
done
################### 判断字符串是否为空 ###################
#-n 判断长度是否非零
#-z 判断长度是否为零
str=testing
str2=''
if [[ -n "$str" ]]
then
echo "The string $str is not empty"
else
echo "The string $str is empty"
fi
if [[ -n "$str2" ]]
then
echo "The string $str2 is not empty"
else
echo "The string $str2 is empty"
fi
# Output:
# The string testing is not empty
# The string is empty
################### 字符串比较 ###################
str=hello
str2=world
if [[ $str = "hello" ]]; then
echo "str equals hello"
else
echo "str not equals hello"
fi
if [[ $str2 = "hello" ]]; then
echo "str2 equals hello"
else
echo "str2 not equals hello"
fi
================================================
FILE: codes/shell/基本脚本/数组使用示例.sh
================================================
#!/usr/bin/env bash
################### 创建数组 ###################
nums=( [ 2 ] = 2 [ 0 ] = 0 [ 1 ] = 1 )
colors=( red yellow "dark blue" )
################### 访问数组的单个元素 ###################
echo ${nums[1]}
# Output: 1
################### 访问数组的所有元素 ###################
echo ${colors[*]}
# Output: red yellow dark blue
echo ${colors[@]}
# Output: red yellow dark blue
printf "+ %s\n" ${colors[*]}
# Output:
# + red
# + yellow
# + dark
# + blue
printf "+ %s\n" "${colors[*]}"
# Output:
# + red yellow dark blue
printf "+ %s\n" "${colors[@]}"
# Output:
# + red
# + yellow
# + dark blue
################### 访问数组的部分元素 ###################
echo ${nums[@]:0:2}
# Output:
# 0 1
################### 获取数组长度 ###################
echo ${#nums[*]}
# Output:
# 3
################### 向数组中添加元素 ###################
colors=( white "${colors[@]}" green black )
echo ${colors[@]}
# Output:
# white red yellow dark blue green black
################### 从数组中删除元素 ###################
unset nums[ 0 ]
echo ${nums[@]}
# Output:
# 1 2
================================================
FILE: codes/shell/基本脚本/显示时间和登录者.sh
================================================
#!/usr/bin/env bash
#This script displays the date and who's logged on
#如果想在同一行显示
#echo -n -e 'The time is:\n\n'
echo The time is:
date
echo The one who has been logged is:
who
================================================
FILE: codes/shell/基本脚本/显示系统变量和转义字符.sh
================================================
#!/usr/bin/env bash
#display user information from system
echo "User info fro userId:$USER"
echo UID:$UID
echo HOME:$HOME
#换行
echo -e '\n'
echo 'The cost of the item is \$15'
================================================
FILE: codes/shell/基本脚本/注释示例.sh
================================================
#!/usr/bin/env bash
#--------------------------------------------
# shell 注释示例
# author:zp
#--------------------------------------------
# echo '这是单行注释'
########## 这是分割线 ##########
: << EOF
echo '这是多行注释'
echo '这是多行注释'
echo '这是多行注释'
EOF
# Execute: ./comment-demo.sh
# Output: null
================================================
FILE: codes/shell/基本脚本/通过反引号获得当前日期并生成唯一文件名.sh
================================================
#!/usr/bin/env bash
#copy the /usr/bin directory listing to a log file
today=`date +%y%m%d`
ls /usr/bin -al > log.$today
================================================
FILE: codes/shell/控制/定时执行脚本.sh
================================================
#!/usr/bin/env bash
# testing the at command
at -f 4.sh 22:10
================================================
FILE: codes/shell/控制/捕捉信号.sh
================================================
#!/usr/bin/env bash
# testing signal trapping
trap "echo'Sorry! I have trapped Ctrl-C'" SIGINT SIGTERM
echo this is a test program
count=1
while [ $count -le 10 ]
do
echo "Loop #$count"
sleep 5
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/控制/捕捉脚本的退出.sh
================================================
#!/usr/bin/env bash
# trapping the script exit
trap "echobyebye" EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 3
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/控制/移除捕捉.sh
================================================
#!/usr/bin/env bash
# removeing a set trap
trap "echobyebye" EXIT
count=1
while [ $count -le 5 ]
do
echo "Loop #$count"
sleep 3
count=$[ $count + 1 ]
done
#移除捕捉
trap - EXIT
echo "I just removed the trap"
================================================
FILE: codes/shell/操作符/关系运算符.sh
================================================
#!/usr/bin/env bash
x=10
if [[ -n $1 ]]; then
x=$1
fi
y=20
if [[ -n $2 ]]; then
y=$2
fi
echo "x=${x}, y=${y}"
if [[ ${x} -eq ${y} ]]; then
echo "${x} -eq ${y} : x 等于 y"
else
echo "${x} -eq ${y}: x 不等于 y"
fi
if [[ ${x} -ne ${y} ]]; then
echo "${x} -ne ${y}: x 不等于 y"
else
echo "${x} -ne ${y}: x 等于 y"
fi
if [[ ${x} -gt ${y} ]]; then
echo "${x} -gt ${y}: x 大于 y"
else
echo "${x} -gt ${y}: x 不大于 y"
fi
if [[ ${x} -lt ${y} ]]; then
echo "${x} -lt ${y}: x 小于 y"
else
echo "${x} -lt ${y}: x 不小于 y"
fi
if [[ ${x} -ge ${y} ]]; then
echo "${x} -ge ${y}: x 大于或等于 y"
else
echo "${x} -ge ${y}: x 小于 y"
fi
if [[ ${x} -le ${y} ]]; then
echo "${x} -le ${y}: x 小于或等于 y"
else
echo "${x} -le ${y}: x 大于 y"
fi
# Output:
# x=10, y=20
# 10 -eq 20: x 不等于 y
# 10 -ne 20: x 不等于 y
# 10 -gt 20: x 不大于 y
# 10 -lt 20: x 小于 y
# 10 -ge 20: x 小于 y
# 10 -le 20: x 小于或等于 y
================================================
FILE: codes/shell/操作符/字符串运算符.sh
================================================
#!/usr/bin/env bash
x="abc"
if [[ -n $1 ]]; then
x=$1
fi
y="xyz"
if [[ -n $2 ]]; then
y=$2
fi
echo "x=${x}, y=${y}"
if [[ ${x} = ${y} ]]; then
echo "${x} = ${y} : x 等于 y"
else
echo "${x} = ${y}: x 不等于 y"
fi
if [[ ${x} != ${y} ]]; then
echo "${x} != ${y} : x 不等于 y"
else
echo "${x} != ${y}: x 等于 y"
fi
if [[ -z ${x} ]]; then
echo "-z ${x} : 字符串长度为 0"
else
echo "-z ${x} : 字符串长度不为 0"
fi
if [[ -n "${x}" ]]; then
echo "-n ${x} : 字符串长度不为 0"
else
echo "-n ${x} : 字符串长度为 0"
fi
if [[ ${x} ]]; then
echo "${x} : 字符串不为空"
else
echo "${x} : 字符串为空"
fi
# Output:
# x=abc, y=xyz
# abc = xyz: x 不等于 y
# abc != xyz : x 不等于 y
# -z abc : 字符串长度不为 0
# -n abc : 字符串长度不为 0
# abc : 字符串不为空
================================================
FILE: codes/shell/操作符/布尔运算符.sh
================================================
#!/usr/bin/env bash
x=10
if [[ -n $1 ]]; then
x=$1
fi
y=20
if [[ -n $2 ]]; then
y=$2
fi
echo "x=${x}, y=${y}"
if [[ ${x} != ${y} ]]; then
echo "${x} != ${y} : x 不等于 y"
else
echo "${x} != ${y}: x 等于 y"
fi
if [[ ${x} -lt 100 && ${y} -gt 15 ]]; then
echo "${x} 小于 100 且 ${y} 大于 15 : 返回 true"
else
echo "${x} 小于 100 且 ${y} 大于 15 : 返回 false"
fi
if [[ ${x} -lt 100 || ${y} -gt 100 ]]; then
echo "${x} 小于 100 或 ${y} 大于 100 : 返回 true"
else
echo "${x} 小于 100 或 ${y} 大于 100 : 返回 false"
fi
if [[ ${x} -lt 5 || ${y} -gt 100 ]]; then
echo "${x} 小于 5 或 ${y} 大于 100 : 返回 true"
else
echo "${x} 小于 5 或 ${y} 大于 100 : 返回 false"
fi
# Output:
# x=10, y=20
# 10 != 20 : x 不等于 y
# 10 小于 100 且 20 大于 15 : 返回 true
# 10 小于 100 或 20 大于 100 : 返回 true
# 10 小于 5 或 20 大于 100 : 返回 false
================================================
FILE: codes/shell/操作符/文件测试运算符.sh
================================================
#!/usr/bin/env bash
file="/etc/hosts"
if [[ -r ${file} ]]; then
echo "${file} 文件可读"
else
echo "${file} 文件不可读"
fi
if [[ -w ${file} ]]; then
echo "${file} 文件可写"
else
echo "${file} 文件不可写"
fi
if [[ -x ${file} ]]; then
echo "${file} 文件可执行"
else
echo "${file} 文件不可执行"
fi
if [[ -f ${file} ]]; then
echo "${file} 文件为普通文件"
else
echo "${file} 文件为特殊文件"
fi
if [[ -d ${file} ]]; then
echo "${file} 文件是个目录"
else
echo "${file} 文件不是个目录"
fi
if [[ -s ${file} ]]; then
echo "${file} 文件不为空"
else
echo "${file} 文件为空"
fi
if [[ -e ${file} ]]; then
echo "${file} 文件存在"
else
echo "${file} 文件不存在"
fi
# Output:(根据文件的实际情况,输出结果可能不同)
# /etc/hosts 文件可读
# /etc/hosts 文件可写
# /etc/hosts 文件不可执行
# /etc/hosts 文件为普通文件
# /etc/hosts 文件不是个目录
# /etc/hosts 文件不为空
# /etc/hosts 文件存在
================================================
FILE: codes/shell/操作符/算术运算符.sh
================================================
#!/usr/bin/env bash
x=10
if [[ -n $1 ]]; then
x=$1
fi
y=20
if [[ -n $2 ]]; then
y=$2
fi
echo "x=${x}, y=${y}"
val=`expr ${x} + ${y}`
echo "${x} + ${y} = $val"
val=`expr ${x} - ${y}`
echo "${x} - ${y} = $val"
val=`expr ${x} \* ${y}`
echo "${x} * ${y} = $val"
val=`expr ${y} / ${x}`
echo "${y} / ${x} = $val"
val=`expr ${y} % ${x}`
echo "${y} % ${x} = $val"
if [[ ${x} == ${y} ]]; then
echo "${x} = ${y}"
fi
if [[ ${x} != ${y} ]]; then
echo "${x} != ${y}"
fi
# Execute: ./算术运算符.sh
# Output:
# x=10, y=20
# 10 + 20 = 30
# 10 - 20 = -10
# 10 * 20 = 200
# 20 / 10 = 2
# 20 % 10 = 0
# 10 != 20
# Execute: ./算术运算符.sh 10 30
# Output:
# x=10, y=30
# 10 + 30 = 40
# 10 - 30 = -20
# 10 * 30 = 300
# 30 / 10 = 3
# 30 % 10 = 0
# 10 不等于 30
================================================
FILE: codes/shell/操作符/逻辑运算符.sh
================================================
#!/usr/bin/env bash
x=10
if [[ -n $1 ]]; then
x=$1
fi
y=20
if [[ -n $2 ]]; then
y=$2
fi
echo "x=${x}, y=${y}"
if [[ ${x} -lt 100 && ${y} -gt 100 ]]
then
echo "${x} -lt 100 && ${y} -gt 100 返回 true"
else
echo "${x} -lt 100 && ${y} -gt 100 返回 false"
fi
if [[ ${x} -lt 100 || ${y} -gt 100 ]]
then
echo "${x} -lt 100 || ${y} -gt 100 返回 true"
else
echo "${x} -lt 100 || ${y} -gt 100 返回 false"
fi
# Output:
# x=10, y=20
# 10 -lt 100 && 20 -gt 100 返回 false
# 10 -lt 100 || 20 -gt 100 返回 true
================================================
FILE: codes/shell/文件操作/log.txt
================================================
Add git message title here
# See links to relevant web pages, issue trackers, etc.
See: https://github.com/
See: [Git Page](https://github.com/)
# List all co-authors, so people can contact with them
Co-authored-by: Name
# Why is this change happening, e.g. goals, use cases, stories, etc.?
Why:
# How is this change happening, e.g. implementations, algorithms, etc.?
How:
# Tags suitable for searching, such as hashtags, keywords, etc.
Tags:
# ## Help ##
#
# Subject line imperative uppercase verbs:
#
# Add = Create a capability e.g. feature, test, dependency.
# Drop = Delete a capability e.g. feature, test, dependency.
# Fix = Fix an issue e.g. bug, typo, accident, misstatement.
# Bump = Increase the version of something e.g. a dependency.
# Make = Change the build process, or tools, or infrastructure.
# Start = Begin doing something; e.g. enable a toggle, feature flag, etc.
# Stop = End doing something; e.g. disable a toggle, feature flag, etc.
# Refactor = A change that MUST be just refactoring.
# Reformat = A change that MUST be just format, e.g. indent line, trim space, etc.
# Rephrase = A change that MUST be just textual, e.g. edit a comment, doc, etc.
# Optimize = A change that MUST be just about performance, e.g. speed up code.
# Document = A change that MUST be only in the documentation, e.g. help files.
#
# For the subject line:
# * Use 50 characters maximum.
# * Do not use a sentence-ending period.
#
# For the body text:
# * Use as many lines as you like.
# * Use 72 characters maximum per line for typical word wrap text.
#
#
# ## About ##
#
# This is our git commit messages.
# You can edit this template if you want
#
# ## Usage ##
#
# Put the template file here:
#
# ~/.git_commit_template.txt
#
# Configure git to use the template file by running:
#
# git config --global commit.template ~/.git_commit_template.txt
#
# Add the template file to the ~/.gitconfig file:
#
# [commit]
# template = ~/.git_commit_template.txt
#
# you could put it in other location if you prefer
#
================================================
FILE: codes/shell/文件操作/创建临时文件.sh
================================================
#!/usr/bin/env bash
tempFile=`mktemp test.XXXXXX`
exec 3> ${tempFile}
echo "This script writes to temp file ${tempFile}"
echo "This is the first line" >&3
echo "This is the second line" >&3
echo "This is the last line" >&3
exec 3>&-
echo "Done creating temp file. The contents are:"
cat ${tempFile}
rm -f ${tempFile} 2> /dev/null
================================================
FILE: codes/shell/文件操作/创建临时目录.sh
================================================
#!/usr/bin/env bash
tempDir=`mktemp -d dir.XXXXXX`
cd ${tempDir} || exit 1
tempFile1=`mktemp temp.XXXXXX`
tempFile2=`mktemp temp.XXXXXX`
exec 7> ${tempFile1}
exec 8> ${tempFile2}
echo "Sending data to directory $tempDir"
echo "This is a test line of data for $tempFile1" >&7
echo "This is a test line of data for $tempFile2" >&8
================================================
FILE: codes/shell/文件操作/文件路径操作.sh
================================================
#!/usr/bin/env bash
path=/dir1/dir2/dir3/test.txt
echo ${path##*/} 获取文件名 test.txt
echo ${path##*.} 获取后缀 txt
#不带后缀的文件名
temp=${path##*/}
echo ${temp%.*} test
#获取目录
echo ${path%/*} /dir1/dir2/dir3
================================================
FILE: codes/shell/文件操作/目录基本操作.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# 目录操作示例
# @author: Zhang Peng
# ------------------------------------------------------------------------------
# 创建目录(整个文件路径中的目录如果不存在,都会一一创建,如果目录已存在,则什么也不做)
mkdir -p /home/linux-tutorial/temp
# 进入目录,如果失败,则退出脚本
cd /home/linux-tutorial/temp || exit 1
# 获取当前目录路径
CURRENT_DIR=$(pwd)
echo "当前目录是:${CURRENT_DIR}"
# 获取上一级目录路径
PARENT_DIR=$(dirname $(pwd))
echo "父目录是:${PARENT_DIR}"
# 获取当前执行脚本名
DIR_NAME=$(basename $0)
echo "当前执行脚本名是:${DIR_NAME}"
# 复制目录(复制 temp 目录所有内容,并命名新文件夹叫 temp2)
cp -rf /home/linux-tutorial/temp /home/linux-tutorial/temp2
# 移动目录(将 temp2 移到 temp 目录下)
mv /home/linux-tutorial/temp2 /home/linux-tutorial/temp/temp2
# 删除目录
rm -rf /home/linux-tutorial
================================================
FILE: codes/shell/文件操作/读文件.sh
================================================
#!/usr/bin/env bash
FILE=log.txt
count=1
cat ${FILE} | while read line
do
echo "$count: $line"
count=$[ $count + 1 ]
done
echo "Finished reading."
================================================
FILE: codes/shell/查找替换文本/gawk/gawk.sh
================================================
#!/usr/bin/env bash
BEGIN {
print "The latest list of users and shells"
print "Userid Shell"
print "------ -----"
FS=":"
}
{
print $1 " " $7
}
END {
print "This concludes the listing"
}
#执行gawk命令截取/etc/passwd输出
#gawk -f gawk.sh /etc/passwd
================================================
FILE: codes/shell/查找替换文本/gawk/gawk函数库
================================================
#!/bin/bash
function myprint()
{
printf "%-16s - %s", $1, $4
}
function myrand ( limit )
{
return int ( limit * rand ( ) )
}
================================================
FILE: codes/shell/查找替换文本/gawk/gawk脚本
================================================
#!/bin/bash
BEGIN{ FS="\n";
RS=""}
{
myprint()
}
================================================
FILE: codes/shell/查找替换文本/gawk/script
================================================
BEGIN{FS=","; print n}
{print $n}
================================================
FILE: codes/shell/查找替换文本/gawk/test
================================================
10
5
123
50
================================================
FILE: codes/shell/查找替换文本/gawk/使用变量.sh
================================================
#!/usr/bin/env bash
#使用内建变量
# NF 当前记录的字段个数
# NR 到目前为止读的记录数量
#下面的程序在每行开头输出行号,并在最后输出文件的总字段数
gawk '{ total+=NF; print NR, $0 }END{ print "Total: ", total}'
gawk 'BEGIN {testing="This is a test"; print testing; testing=45; print testing}'
#处理数字值
gawk 'BEGIN{x=4; x= x*2+3; printx}'
#处理数组
gawk 'BEGIN{capital["Ill"] = "SprintField"; print capital["Ill"]}'
#遍历数组变量
gawk 'BEGIN{
var["a"] = 1
var["g"] = 2
var["m"] = 3
for( test in var)
{
print "Index:",test,"- Value:",var[test]
}
}'
print "------"
#删除数组变量
gawk 'BEGIN{
var["a"] = 1
var["g"] = 2
for (test in var)
{
print "Index:",test," - Value:", var[test]
}
delete var["g"]
print "----"
for (test in var)
{
print "Index;",test," - Value:", var[test]
}
}'
================================================
FILE: codes/shell/查找替换文本/gawk/使用模式,结构化命令.sh
================================================
#!/usr/bin/env bash
#正则表达式
gawk 'BEGIN{FS=","}
/11/{print $1}
' test
#if-else语句
gawk '{
if($1 > 20)
{
x=$1*20
print x
}
else
{
x=$1/2
print x
}
}' test
#while 语句
gawk '{
total = 0
i=1
while(i<4)
{
total+=$i
i++
}
avg = total/3
print "Average:".avg
}' test
#do-while语句
gawk '{
total=0
i=1
do
{
total += $i
i++
}while(total < 150)
print total }' test
#for语句
gawk '{
total = 0
for (i=1; i<4; i++)
{
total+=$i
}
avg = total/3
print "Average:".avg
}' test
================================================
FILE: codes/shell/查找替换文本/gawk/自定义函数.sh
================================================
#!/usr/bin/env bash
#gawk 自定义函数
gawk '
function myprint()
{
printf "%-16s - %s\n", $1, $4
}
BEGIN{FS="\n"; RS=""}
{
myprint()
}' test
================================================
FILE: codes/shell/查找替换文本/gawk/调用函数库和脚本.sh
================================================
#!/usr/bin/env bash
#使用函数库和gawk脚本
gawk -f gawk函数库 -f gawk脚本 test
================================================
FILE: codes/shell/查找替换文本/gawk/输出.sh
================================================
#!/usr/bin/env bash
#print用于产生简单输出
#多个表达式的字符串值之间用输出字段分隔符分开
gawk '{ print $1, $2 }'
#输出字段分割符与输出记录分隔符存储在内建变量OFS与ORS中,
#初始情况下,OFS与ORS被设置成一个空格符与一个换行符,但它们的值可以在任何时候改变
#下面这个程序打印每一行的第1第2个字段,字段之间用分号分开,在每一行的第2个字段之后输出两个换行符
gawk 'BEGIN { OFS = ":"; ORS = "\n\n" }
{ print $1, $2 }'
#下面这个程序拼接第1个与第2个字段,两个字段之间没有输出字段分隔符插入
gawk '{ print $1 $2 }'
#这两句话等价
gawk '{ print }'
gawk '{ print $0 }'
#输出空行
gawk '{ print "" }'
#printf用于产生格式化输出
#printf不会自动换行,需要手动添加\n
#格式说明符以%开始,以转换字符结束
# - 表达式在它的域内左对齐,没有则右对齐
# width 为了达到规定的宽度,必要时填充空格
# .prec 字符串最大宽度, 或十进制数的小数部分的位数
gawk '{ printf ("Name:%-10sAge:%-5dWeight:%7.2f\n", $1, $2, $3) }'
#输出到文件
#重定向运算符>与>>用于将输出重定向到文件,文件名必须用双引号括起来
#下面这个程序将所有输入行的第1个与第3个字段输出到两个文件中:如果第3个字段大于100,则输出到bigpop,否则输出到smallpop
gawk '{ print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop") }'
#输出到管道
#print的输出将以管道的方式传递给command
# Canada 3852
# China 3705
# USA 3615
# Brazil 3286
gawk '{ pop[$1]+=$2 }
END{ for(c in pop) printf("%15-s%6d\n", c, pop[c]) | "sort -nk 2"; close("sort -nk 2") }'
#关闭文件与管道
#语句close(expression)关闭一个文件或管道,文件或管道由expression指定。
#expression的字符串值必须与最初用于创建文件或管道的字符串值相同。
#在同一个程序中,如果你写了一个文件,而待会儿想要读取它,那么就需要调用close。
#某一时刻,同时处于打开状态的文件或管道数量最大值由实现定义。
close ( " sort -nk 2 " )
================================================
FILE: codes/shell/查找替换文本/grep.sh
================================================
#!/usr/bin/env bash
# 使用 grep 命令可以用于在文件中查找指定文本
# 在二进制文件中查找字符串
file=$1
keyword=$2
strings ${file} | grep ${keyword}
================================================
FILE: codes/shell/查找替换文本/regex/目录文件计数.sh
================================================
#!/usr/bin/env bash
# count number of files in your PATH
mypath=`echo $PATH | sed 's/:/ /g'`
count=0
for directory in $mypath
do
check=`ls $directory`
echo $check
for item in $check
do
count=$[ $count + 1 ]
done
echo "$directory - $count"
count=0
done
================================================
FILE: codes/shell/查找替换文本/regex/邮件验证.sh
================================================
#!/usr/bin/env bash
#验证邮件
gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\+]+)\.([a-zA-Z]{2,5})/{print $0}'
================================================
FILE: codes/shell/查找替换文本/sed/sed文件操作.sh
================================================
#!/usr/bin/env bash
#向文件写入
sed '1,2w test1' test1
echo -e "next\n"
#从文件读取
sed '3r ./test' ./test
echo -e "next\n"
#从文件读取,并插入字符流
sed '/lazy/r test' test
#向数据流末尾添加数据
sed '$r test' test
echo -e "next1\n"
sed '/lazy/ {
r test
d
}' test
================================================
FILE: codes/shell/查找替换文本/sed/sed编辑器基础.sh
================================================
#!/usr/bin/env bash
#sed编辑器基础
#替换标记
sed 's/lazy/ht/' ./test
echo -e "next\n"
#可用的替换标记
#1.数字 表明新闻本将替换第几处模式匹配的地方
sed 's/lazy/ht/2' ./test
#2.g 表明新文件将会替换所有已有文本出现的地方
sed 's/lazy/ht/g' ./test
#3.p 表明原来行的内容要打印出来,替换后的
sed 's/lazy/ht/p' ./test
#4.w file 将替换的结果写到文件中
sed 's/lazy/ht/w test1' ./test
echo -e "next\n"
#替换字符
sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
#或者
sed 's!/bin/bash!/bin/csh!' /etc/passwd
echo -e "next\n"
#使用地址
#1.数字方式的行寻址
sed '2s/lazy/cat/' ./test
sed '2,3s/lazy/cat/' ./test
sed '2,$s/lazy/cat/' ./test
#2.使用文本模式过滤器
sed '/tiandi/s/bash/csh/' /etc/passwd
echo -e "next\n"
#组合命令
sed '2{
s/fox/elephant/
s/dog/cat/
}' test
sed '2,${
s/fox/elephant/
s/dog/cat/
}' test
echo -e "next\n"
#删除行
sed '3d' ./test
sed '2,$d' ./test
sed '/number 1/d' ./test
#删除两个文本模式来删除某个范围的行,第一个开启删除功能,第二个关闭删除功能
sed '/1/,/3/d' ./test
echo -e "next\n"
#插入和附加文本
sed '3i\
This is an appended line.' ./test
sed '$a\
This is a new line of text.' ./test
#修改行
sed '3c\
This a changed line of text.' ./test
sed '/number 1/c\
This a changed line of text.' ./test
#替换两行文本
#sed '2,3c\
#This a changed line of text.' ./test
#转换命令,处理单个字符
#sed 'y/123/789/' ./test
echo -e "next\n"
#回顾打印
# p 打印文本行
# -n 禁止其他行,只打印包含匹配文本模式的行
sed -n '/number 3/p' ./test
#查看修改之前的行和修改之后的行
#sed -n '/3/{
#p
#s/line/test/p
#}' ./test
echo -e "next\n"
# 打印行号
sed '=' ./test
#打印指定的行和行号
#sed -n '/lazy/{
#=
#p
#}' ./test
#列出行 打印数据流中的文本和不可打印的ASCII字符,任何不可打印的字符都用它们的八进制值前加一个反斜线或标准C风格的命名法,比如用\t来代表制表符
sed -n 'l' ./test
================================================
FILE: codes/shell/查找替换文本/sed/test
================================================
This is the header line
This is the first data line
This is the data line
This is the second data line
line This is the last line
================================================
FILE: codes/shell/查找替换文本/sed/保持空间.sh
================================================
#!/usr/bin/env bash
#h将模式空间保存到保持空间
#H将模式空间附加到保持空间
#g将保持空间复制到模式空间
#G将保持空间保存到模式空间
#x交换模式空间和保持空间的内容
sed -n '/first/{
h
p
n
p
g
p
}' test
================================================
FILE: codes/shell/查找替换文本/sed/删除指定的空白行和删除html标签.sh
================================================
#!/usr/bin/env bash
#多个空格只保留一个
#sed '/./,/^$/!d' test
#删除开头的空白行
#sed '/./,$!d' test
#删除结尾的空白行
sed '{
:start
/^\n*$/{$d; N; b start}
}' test
#删除html标签
#有问题
#s/<.*>//g
#sed 's/<[^>]*>//g' test1
#sed 's/<[^>]*>//g;/^$/d' test1
================================================
FILE: codes/shell/查找替换文本/sed/在脚本中使用sed.sh
================================================
#!/usr/bin/env bash
# shell wrapper for sed editor script to reverse lines
sed -n '{
1!G
h
$p
}' $1
================================================
FILE: codes/shell/查找替换文本/sed/排除命令.sh
================================================
!/bin/bash
#排除命令,使本来起作用的命令不起作用
sed -n '/heade/!p' test
#反转文本文件
sed -n '{1!G ; h; $p}' test
================================================
FILE: codes/shell/查找替换文本/sed/模式替代.sh
================================================
#!/usr/bin/env bash
#and符号,代表替换命令中的匹配模式,不管预定义模式是什么文本,都可以用and符号替换,and符号会提取匹配替换命令中指定替换模式中的所有字符串
echo "The cat sleeps in his hat" | sed 's/.at/"&"/g'
#替换单独的单词
echo "The System Administrator manual" | sed 's/\(System\) Administrator/\1 user/'
#在长数字中插入逗号
echo "1234567" | sed '{:start; s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/; t start}'
================================================
FILE: codes/shell/查找替换文本/sed/测试.sh
================================================
#!/usr/bin/env bash
#测试,如果测试成功,如果没有标签,sed会跳转到结尾,如果有标签,就跳转到标签,如果测试失败,则不会跳转
sed -n '{s/first/matched/; t; s/This is the/No match on/}' test
================================================
FILE: codes/shell/查找替换文本/sed/给文件中的行编号.sh
================================================
#!/usr/bin/env bash
sed '=' test | sed 'N; s/\n/ /'
================================================
FILE: codes/shell/查找替换文本/sed/跳转.sh
================================================
#!/usr/bin/env bash
#跳转到指定脚本
sed '{/first/b jump1; s/This is the/No jump on/; :jump1; s/This is the/Jump here on/}' test
#跳转到开头,删除每一个逗号,并保证删除最后一个逗号之后,跳出循环
sed -n '{:start; s/,//1p; /,/b start}' test
================================================
FILE: codes/shell/查找替换文本/sed/输出末尾指定行数的数据.sh
================================================
#!/usr/bin/env bash
#输出末尾10行数据
sed '{
:start
$q
N
11,$D
b start
}' /etc/passwd
================================================
FILE: codes/shell/查找替换文本/sed/重定向sed输出.sh
================================================
#!/usr/bin/env bash
# add commas to numbers in factorial answer
factorial=1
counter=1
number=$1
while [ $counter -le $number ]
do
factorial=$[ $factorial * $counter ]
counter=$[ $counter + 1 ]
done
result=`echo $factorial | sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start
}'`
echo "The result is $result"
================================================
FILE: codes/shell/系统管理/控制远程服务器执行指令.sh
================================================
#!/usr/bin/expect
user="root"
password="root"
/usr/bin/expect << EOF
set timeout 5
spawn ssh -o "StrictHostKeyChecking no" ${user}@${host}
expect {
"yes/no)?" { send "yes\r"; exp_continue }
"password:" { send "${password}\r" }
}
expect "root*"
send "ssh-keygen -t rsa\r"
expect "Enter file in which to save the key*"
send "\r"
expect {
"(y/n)?" { send "n\r"; exp_continue }
"Enter passphrase*" { send "\r"; exp_continue }
"Enter same passphrase again:" { send "\r" }
}
expect "root*"
send "df -h\r"
expect "root*"
send "exit\r"
EOF
================================================
FILE: codes/shell/系统管理/系统用户管理.sh
================================================
#!/usr/bin/env bash
###################################################################################
# Linux 系统用户管理
# @author: Zhang Peng
###################################################################################
# 创建用户组
groupadd elk
# 创建新用户,-g elk 设置其用户组为 elk,-p elk 设置其密码为 elk
useradd elk -g elk -p elk
# 更改 /opt 文件夹及内部文件的所属用户及组为 elk:elk
chown -R elk:elk /opt
================================================
FILE: codes/shell/脚本函数/lib.sh
================================================
#!/usr/bin/env bash
add() {
echo $[ $1 + $2 ]
}
sub() {
echo $[ $1 - $2 ]
}
mul() {
echo $[ $1 * $2 ]
}
div() {
if [[ $2 -ne 0 ]]; then
echo $[ $1 / $2 ]
else
echo -1
fi
}
================================================
FILE: codes/shell/脚本函数/从函数返回数组.sh
================================================
#!/usr/bin/env bash
# returning an array value
function arraydblr {
local origarry
local newarray
local elements
local i
origarry=( `echo "$@"` )
newarray=( `echo "$@"` )
elements=$[ $# - 1 ]
for (( i = 0; i <= $elements; i ++ ))
{
newarray [ $i ] = $[ ${origarry[$i]} * 2 ]
}
echo ${newarray[*]}
}
myarray=( 1 2 3 4 5 )
echo "The original array is : ${myarray[*]}"
arg1=`echo ${myarray[*]}`
result=( `arraydblr $arg1` )
echo "The new array is : ${result[*]}"
================================================
FILE: codes/shell/脚本函数/使用return命令.sh
================================================
#!/usr/bin/env bash
# using the return command in a function
function db1 {
read -p "Enter a value:" value
echo "doubling the value"
return $[ $value * 2 ]
}
db1
echo "The new value is $?"
================================================
FILE: codes/shell/脚本函数/使用全局变量带来的问题.sh
================================================
#!/usr/bin/env bash
# demonstrating a bad use of variables
function func1 {
temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temlp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "Temp is larger"
else
echo "temp is smaller"
fi
================================================
FILE: codes/shell/脚本函数/使用函数输出.sh
================================================
#!/usr/bin/env bash
# using the echo to return a value
function db1 {
read -p "Enter a value:" value
echo $[ $value * 2 ]
}
result=`db1`
echo "The new value is $result"
================================================
FILE: codes/shell/脚本函数/使用命令行中传递的参数.sh
================================================
#!/usr/bin/env bash
# using a global variable to pass a value
function db1 {
# $1和$2 不能从命令行中传递,只能调用函数时,手动传递
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=`db1 $1 $2`
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
================================================
FILE: codes/shell/脚本函数/使用局部变量.sh
================================================
#!/usr/bin/env bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
================================================
FILE: codes/shell/脚本函数/使用库函数.sh
================================================
#!/usr/bin/env bash
# 装载其它脚本
source lib.sh
echo "20 + 10 = $(add 20 10)"
echo "20 - 10 = $(sub 20 10)"
echo "20 * 10 = $(mul 20 10)"
echo "20 / 10 = $(div 20 10)"
================================================
FILE: codes/shell/脚本函数/全局变量.sh
================================================
#!/usr/bin/env bash
# using a global variable to pass a value
function db1 {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is : $value"
================================================
FILE: codes/shell/脚本函数/函数入参.sh
================================================
#!/usr/bin/env bash
x=0
if [[ -n $1 ]]; then
echo "第一个参数为:$1"
x=$1
else
echo "第一个参数为空"
fi
y=0
if [[ -n $2 ]]; then
echo "第二个参数为:$2"
y=$2
else
echo "第二个参数为空"
fi
paramsFunction() {
echo "函数第一个入参:$1"
echo "函数第二个入参:$2"
}
paramsFunction ${x} ${y}
================================================
FILE: codes/shell/脚本函数/函数入参2.sh
================================================
#!/usr/bin/env bash
runner() {
return 0
}
name=zp
paramsFunction() {
echo "函数第一个入参:$1"
echo "函数第二个入参:$2"
echo "传递到脚本的参数个数:$#"
echo "所有参数:"
printf "+ %s\n" "$*"
echo "脚本运行的当前进程 ID 号:$$"
echo "后台运行的最后一个进程的 ID 号:$!"
echo "所有参数:"
printf "+ %s\n" "$@"
echo "Shell 使用的当前选项:$-"
runner
echo "runner 函数的返回值:$?"
}
paramsFunction 1 "abc" "hello, \"zp\""
# Output:
# 函数第一个入参:1
# 函数第二个入参:abc
# 传递到脚本的参数个数:3
# 所有参数:
# + 1 abc hello, "zp"
# 脚本运行的当前进程 ID 号:26400
# 后台运行的最后一个进程的 ID 号:
# 所有参数:
# + 1
# + abc
# + hello, "zp"
# Shell 使用的当前选项:hB
# runner 函数的返回值:0
================================================
FILE: codes/shell/脚本函数/函数基本示例.sh
================================================
#!/usr/bin/env bash
# using a function in script
function func1 {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now this is the end of the script"
================================================
FILE: codes/shell/脚本函数/函数基本示例2.sh
================================================
#!/usr/bin/env bash
calc() {
PS3="choose the oper: "
select oper in "+" "-" "*" "/" # 生成操作符选择菜单
do
echo -n "enter first num: " && read x # 读取输入参数
echo -n "enter second num: " && read y # 读取输入参数
exec
case ${oper} in
"+")
return $((${x} + ${y}))
;;
"-")
return $((${x} - ${y}))
;;
"*")
return $((${x} * ${y}))
;;
"/")
return $((${x} / ${y}))
;;
*)
echo "${oper} is not support!"
return 0
;;
esac
break
done
}
calc
echo "the result is: $?" # $? 获取 calc 函数返回值
# $ ./function-demo.sh
# 1) +
# 2) -
# 3) *
# 4) /
# choose the oper: 3
# enter first num: 10
# enter second num: 10
# the result is: 100
================================================
FILE: codes/shell/脚本函数/函数递归.sh
================================================
#!/usr/bin/env bash
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=`factorial $temp`
echo $[ $result * $1 ]
fi
}
read -p "Please input a value: " value
result=`factorial $value`
echo "The factorial of $value is: $result"
================================================
FILE: codes/shell/脚本函数/在函数中使用参数.sh
================================================
#!/usr/bin/env bash
# passing parameters to a function
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "Adding 10 and 15:"
value=`addem 10 15`
echo $value
echo -n "Let's try adding just one number: "
value=`addem 10`
echo $value
echo -n "Now trying adding no number: "
value=`addem`
echo $value
echo -n "Finally, try adding three or more numbers: "
value=`addem 10 15 20`
echo $value
================================================
FILE: codes/shell/脚本函数/想函数传数组数据.sh
================================================
#!/usr/bin/env bash
# trying to pass an array variable
function testit {
echo "The parameters are : $@"
#函数只会读取数组变量的第一个值
thisarray=$1
echo "The received array is ${thisarray[*]}"
local newarray
newarray=( `echo "$@"` )
echo "The new array value is : ${newarray[*]}"
}
myarray=( 1 2 3 4 5 )
echo "The original array is : ${myarray[*]}"
#将数组变量当成一个函数参数,函数只会去函数变量第一个值
#testit $myarray
testit ${myarray[*]}
================================================
FILE: codes/shell/脚本函数/累加数组中的值.sh
================================================
#!/usr/bin/env bash
#adding values in the array
function addarray {
local sum=0
local newarray
newarray=( `echo "$@"` )
for value in ${newarray[*]}
do
sum=$[ $sum + $value ]
done
echo $sum
}
myarray=( 1 2 3 4 5 )
echo "The original array is : ${myarray[*]}"
arg1=`echo ${myarray[*]}`
result=`addarray $arg1`
echo "The result is $result"
================================================
FILE: codes/shell/脚本函数/默认退出状态码.sh
================================================
#!/usr/bin/env bash
# testing the exit status of a function
func1() {
echo "Trying to display a non-existent file"
ls -l badfile
}
#由于最后一条命令未执行成功,返回的状态码非0
echo "testing the function"
func1
echo "The exit status is : $?"
func2() {
ls -l badfile
echo "Another test to display a non-existent file"
}
#由于最后一条命令echo执行成功,返回的状态码为0
echo "Another test"
func2
echo "The exit status is : $?"
================================================
FILE: codes/shell/菜单/使用msgbox部件.sh
================================================
#!/usr/bin/env bash
dialog --title text --msgbox "This is a test" 10 20
================================================
FILE: codes/shell/菜单/使用select命令.sh
================================================
#!/usr/bin/env bash
# using select in the menu
function diskspace {
clear
df -k
}
function whoseon {
clear
who
}
function menusage {
clear
cat /proc/meminfo
}
PS3="Enter option:"
select option in "Display disk space" "Display logged on users" "Display memory usage" "Exit program"
do
case $option in
"Exit program")
break ;;
"Display disk space")
diskspace ;;
"Display logged on users")
whoseon ;;
"Display memory usage")
menusage ;;
*)
clear
echo "Sorry, wrong selection" ;;
esac
done
clear
================================================
FILE: codes/shell/菜单/使用脚本菜单.sh
================================================
#!/usr/bin/env bash
function menu {
clear
echo
echo -e "\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged on users"
echo -e "\t3. Display memory usage"
echo -e "\t0. Exit program\n\n"
echo -en "\t\tEnter option:"
read -n 1 option
}
function diskspace {
clear
df -k
}
function whoseon {
clear
who
}
function menusage {
clear
cat /proc/meminfo
}
while [ 1 ]
do
menu
case $option in
0)
break ;;
1)
diskspace ;;
2)
whoseon ;;
3)
menusage ;;
*)
clear
echo "Sorry, wrong selection" ;;
esac
echo -en "\n\n\t\tHit any key to continue"
read -n 1 line
done
clear
================================================
FILE: codes/shell/菜单/在脚本中使用dialog命令.sh
================================================
#!/usr/bin/env bash
# using dialog to create a menu
temp=`mktemp -t test.XXXXXX`
temp2=`mktemp -t test2.XXXXXX`
function diskspace {
df -k > $temp
dialog --textbox $temp 20 60
}
function whoseon {
who > $temp
dialog --textbox $temp 20 50
}
function menusage {
cat /proc/meminfo > $temp
dialog --textbox $temp 20 50
}
while [ 1 ]
do
dialog --menu "Sys Admin Menu" 20 30 10 1 "Display disk space" 2 "Display users" 3 "Display memory usage" 0 "Exit" 2> $temp2
if [ $? -eq 1 ]
then
break
fi
selection=`cat $temp2`
case $selection in
1)
diskspace ;;
2)
whoseon ;;
3)
menusage ;;
0)
break ;;
*)
dialog --msgbox "Sorry,invalid selection" 10 30
esac
done
rm -f $temp 2> /dev/null
rm -f $temp2 2> /dev/null
================================================
FILE: codes/shell/输入和输出/test
================================================
ls: cannot access badtest: No such file or directory
but this should go to the testerror file
================================================
FILE: codes/shell/输入和输出/test1
================================================
This is the end of the script
================================================
FILE: codes/shell/输入和输出/临时重定向.sh
================================================
#!/usr/bin/env bash
# testing STDERR messages
echo "This is an error " >&2
echo "This is another error"
echo "This is also an error" >&2
================================================
FILE: codes/shell/输入和输出/使用getopts.sh
================================================
#!/usr/bin/env bash
# simple demonstration of the getopts command
while getopts :ab:c opt
do
case "$opt" in
a) echo "Found the -a option" ;;
b) echo "Found the -b option, with value $OPTARG" ;;
c) echo "Found the -c option" ;;
*) echo "Unknown option:$opt" ;;
esac
done
================================================
FILE: codes/shell/输入和输出/使用getopts处理选项和参数.sh
================================================
#!/usr/bin/env bash
# processing options and parameters with getopts
while getopts :ab:cd opt
do
case "$opt" in
a) echo "Found the -a option" ;;
b) echo "Found the -b option,with value $OPTARG" ;;
c) echo "Found the -c option" ;;
d) echo "Found the -d option" ;;
*) echo "Unknown option: $opt" ;;
esac
done
shift $[ $OPTIND - 1 ]
count=1
for param in "$@"
do
echo "Parameter $count: $param"
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/使用getopt命令.sh
================================================
#!/usr/bin/env bash
#extracting command line options and values with getopt
# getopt command is not goot at dealing with space,we can use getopts
set -- `getopt -q ab:c "$@"`
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) param="$2"
echo "Found the -b option,with parameter value $param"
shift ;;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option" ;;
esac
shift
done
count=1
for param in "$@"
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/使用shift命令.sh
================================================
#!/usr/bin/env bash
# shift n 移动变量
count=1
while [ -n "$1" ]
do
echo "Parameter #$count = $1"
count=$[ $count + 1 ]
shift
done
echo -e "\n"
# demonstrating a multi-position shift
echo "The original parameters : $*"
shift 2
echo "Here's the new first parameter: $1"
================================================
FILE: codes/shell/输入和输出/免密码传输.sh
================================================
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# 免密码传输
# @author Zhang Peng
# @since 2020/4/8
# ------------------------------------------------------------------------------
REMOTE_HOST=192.168.0.2
# 如果本机没有公私钥对,可以执行以下命令生成 ssh 公私钥对
#ssh-keygen -t rsa
# 服务器 A 上执行以下命令
scp ~/.ssh/id_rsa.pub root@${REMOTE_HOST}:~/.ssh/id_rsa.pub.tmp
# 服务器 B 上执行以下命令
cat ~/.ssh/id_rsa.pub.tmp >> ~/.ssh/authorized_keys
rm ~/.ssh/id_rsa.pub.tmp
================================================
FILE: codes/shell/输入和输出/分离参数和选项.sh
================================================
#!/usr/bin/env bash
#extracting options and parameters
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b option" ;;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option" ;;
esac
shift
done
count=1
for param in $@
do
echo "Parameter #$count: $param"
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/列出当前脚本打开的文件描述符.sh
================================================
#!/usr/bin/env bash
# testing lsof with file descriptors
exec 3> test
exec 6> test
exec 7< test
lsof -a -p $$ -d0,1,2,3,6,7
================================================
FILE: codes/shell/输入和输出/创建自己的重定向/从以重定向的文件描述符中恢复.sh
================================================
#!/usr/bin/env bash
#storing STDOUT, then coming back to it
exec 3>&1
exec 1> test
echo "This should store in output file"
echo "along with this line"
exec 1>&3
echo "Now things should be back to normal"
================================================
FILE: codes/shell/输入和输出/创建自己的重定向/关闭文件描述符.sh
================================================
#!/usr/bin/env bash
# testing closing file descriptors
exec 3> test
echo "This is a test line of data" >&3
# closing file descriptor
exec 3>&-
echo "This won't work" >&3
cat test
#覆盖前一个test文件
exec 3> test
echo "This'll be bad" >&3
================================================
FILE: codes/shell/输入和输出/创建自己的重定向/创建读写文件描述符.sh
================================================
#!/usr/bin/env bash
# testing inpiut/output file descriptor
exec 3<> test
read line <&3
echo "Read: $line"
echo "This is the test line" >&3
================================================
FILE: codes/shell/输入和输出/创建自己的重定向/创建输入文件描述符.sh
================================================
#!/usr/bin/env bash
# redirecting input file descriptors
exec 3>&1
echo "This is the 3 file descriptor" >&3
exec 6>&0
exec 0< test
count=1
while read line
do
echo "Line #$count: $line"
count=$[ $count + 1 ]
done
exec 0<&6
read -p "Are you done now?" answer
case $answer in
Y | y) echo "Goodbye" ;;
N | n) echo "Sorry, this is the end" ;;
esac
================================================
FILE: codes/shell/输入和输出/创建自己的重定向/创建输出文件描述符.sh
================================================
#!/usr/bin/env bash
# using an alternative file descriptor
exec 3> test
echo "This should display on the monitor"
echo "and this should be stored in the file" >&3
echo "Then this should be back on the monitor"
================================================
FILE: codes/shell/输入和输出/参数计数.sh
================================================
#!/usr/bin/env bash
# getting the number of parameters
echo There were $# parameters supplied
#花括号里不能使用美元符号
params=$#
echo The last parameter is $params
echo The last parameter is ${!#}
================================================
FILE: codes/shell/输入和输出/在脚本中使用重定向输入.sh
================================================
#!/usr/bin/env bash
# redirecting the inpiut
# 从test中读取数据,而不是从STDIN中读取数据
exec 0< test
count=1
while read line
do
echo "Line #$count : $line "
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/处理带值的选项.sh
================================================
#!/usr/bin/env bash
# extracting command line options and values
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) param="$2"
echo "Found the -b option, with parameter value $param"
shift ;;
-c) echo "Found the -c option" ;;
--) shift
break ;;
*) echo "$1 is not an option" ;;
esac
shift
done
count=1
for param in "$@"
do
echo "Parameter #$count : $param"
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/处理简单选项.sh
================================================
#!/usr/bin/env bash
# extracting command line options as parameters
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option" ;;
-b) echo "Found the -b optins" ;;
-c) echo "Found the -c optins" ;;
*) echo "$1 is not a valid options" ;;
esac
shift
done
================================================
FILE: codes/shell/输入和输出/快速清除文件或日志.sh
================================================
#!/usr/bin/env bash
# 清除日志
cat /dev/null > [Logname]
================================================
FILE: codes/shell/输入和输出/抓取所有数据.sh
================================================
#!/usr/bin/env bash
# testing $* and $@
count=1
for param in "$*"
do
echo "\$* Parameter #$count = $param"
count=$[ $count + 1 ]
done
count=1
for param in "$@"
do
echo "\$@ Paramenter #$count = $param"
count=$[ $count + 1 ]
done
================================================
FILE: codes/shell/输入和输出/永久重定向.sh
================================================
#!/usr/bin/env bash
# testing STDERR messages
# redirecting all to a file
# 脚本执行期间,用exec命令告诉shell重定向某个特定文件描述符
exec 2> test
ls badtest
echo "This is test of redirecting all output"
echo "from a script to another file"
exec 1> test1
echo "This is the end of the script"
echo "but this should go to the testerror file" >&2
================================================
FILE: codes/shell/输入和输出/测试.txt
================================================
================================================
FILE: codes/shell/输入和输出/获取用户输入.sh
================================================
#!/usr/bin/env bash
# testing the reading command
echo -n "Enter your name:"
read name
echo "Hello $name, welcome to my program"
read -p "Please enter your age: " age
days=$[ $age * 365 ]
echo "That makes you over $days days old"
#指定多个变量,输入的每个数据值都会分配给表中的下一个变量,如果用完了,就全分配各最后一个变量
read -p "Please enter name:" first last
echo "Checking data for $last. $first..."
#如果不指定变量,read命令就会把它收到的任何数据都放到特殊环境变量REPLY中
read -p "Enter a number:"
factorial=1
for (( count = 1; count <= $REPLY; count ++ ))
do
factorial=$[ $factorial * $count ]
done
echo "The factorial of $REPLY is $factorial"
================================================
FILE: codes/shell/输入和输出/记录信息.sh
================================================
#!/usr/bin/env bash
# using the tee command for logging
#将输入一边发送到STDOUT,一边发送到日志文件
tempfile=test
echo "This is the start of the test" | tee $tempfile
echo "This is the second line of the test" | tee -a $tempfile
echo "This is the end line of the test" | tee -a $tempfile
================================================
FILE: codes/shell/输入和输出/读取参数.sh
================================================
#!/usr/bin/env bash
# using one command line parameter
factorial=1
for (( number = 1; number <= $1; number ++ ))
do
factorial=$[ $factorial * $number ]
done
echo The factor of $1 is $factorial
================================================
FILE: codes/shell/输入和输出/读取多个命令行参数.sh
================================================
#!/usr/bin/env bash
# handing lots of parameters
total=$[ ${10} * ${11} ]
echo The tenth parameter is ${10}
echo The eleventh parameter is ${11}
echo The total is $total
================================================
FILE: codes/shell/输入和输出/读取程序名.sh
================================================
#!/usr/bin/env bash
# testing the $0 parameter
echo The command entered is $0
#当传给$0变量的真实字符串是整个脚本的路径是,程序中就会使用整个路径,而不仅仅是程序名
name=`basename $0`
echo The command entered is $name
================================================
FILE: codes/shell/输入和输出/读取选择参数.sh
================================================
#!/usr/bin/env bash
##############################################################
# 很多场景下,我们需要在执行脚本时,输入指定的参数,脚本会
# 根据参数执行不同的行为。这就需要读取脚本参数并校验。
##############################################################
################### 读取脚本输入参数并校验 ###################
declare -a serial
serial=( start stop restart )
echo -n "请选择操作(可选值:start|stop|restart):"
read oper
if ! echo ${serial[@]} | grep -q ${oper}; then
echo "请选择正确操作(可选值:start|stop|restart)"
exit 1
fi
declare -a serial2
serial2=( dev test prod )
echo -n "请选择运行环境(可选值:dev|test|prod):"
read profile
if ! echo ${serial2[@]} | grep -q ${profile}; then
echo "请选择正确运行环境(可选值:dev|test|prod)"
exit 1
fi
================================================
FILE: codes/shell/输入和输出/超时和输入计数.sh
================================================
#!/usr/bin/env bash
# timing the data entry
if read -t 5 -p "Please enter your name:" name
then
echo "Hello, $name, welcome to my script"
else
#起到换行的作用
echo
#输入计数 -n1
read -n1 -p "Do you want to continue [Y/N]?" answer
case $answer in
Y | y) echo
echo "Fine, continue on..." ;;
N | n) echo
echo "OK,goodbye" ;;
*) echo
echo "OK, wrong, goodbye"
esac
echo "Sorry, this is the end of the script"
fi
================================================
FILE: codes/shell/输入和输出/隐藏方式读取数据.sh
================================================
#!/usr/bin/env bash
# hiding input data from monitor
read -s -p "Please enter your password: " pass
#添加了-s选项之后,不会自动换行,不添加-s 会自动换行
echo
echo "Is your password really $pass?"
================================================
FILE: codes/shell/进阶脚本/创建捕捉脚本.sh
================================================
#!/usr/bin/env bash
#
# Capture_Stats - Gather System Performance Statistics
#
#########################################################
#
# Set Script Variables
#
REPORT_FILE=/home/tiandi/Documents/capstats.csv
DATE=`date +%m/%d/%y`
TIME=`date +%k:%M:%S`
#
############################################################
#
USERS=`uptime | sed 's/user.*$//' | gawk '{print $NF}'`
LOAD=`uptime | gawk '{print $NF}'`
#
FREE=`vmstat 1 2 | sed -n '/[0-9]/p' | sed -n '2p' | gawk '{print $4}'`
IDLE=`vmstat 1 2 | sed -n '/[0-9]/p' | sed -n '2p' | gawk '{print $15}'`
#
##########################################
#
echo "$DATE,$TIME,$USERS,$LOAD,$FREE,$IDLE" >> $REPORT_FILE
#
================================================
FILE: codes/shell/进阶脚本/开启debug模式.sh
================================================
#!/usr/bin/env bash
# 开启 debug
set -x
for (( i = 0; i < 3; i ++ )); do
printf ${i}
done
# 关闭 debug
set +x
# Output:
# + (( i = 0 ))
# + (( i < 3 ))
# + printf 0
# 0+ (( i++ ))
# + (( i < 3 ))
# + printf 1
# 1+ (( i++ ))
# + (( i < 3 ))
# + printf 2
# 2+ (( i++ ))
# + (( i < 3 ))
# + set +x
for i in {1..5}; do
printf ${i};
done
printf "\n"
# Output: 12345
================================================
FILE: codes/shell/进阶脚本/查看uptime获取在线用户数.sh
================================================
#!/usr/bin/env bash
#
uptime | sed 's/user.*$//' | gawk '{print $NF}'
================================================
FILE: codes/shell/进阶脚本/生成报告脚本-基于创建捕捉脚本.sh
================================================
#!/usr/bin/env bash
#
# Report_Stats - Generates Rpt from Captured Perf Stats
#
############################################################
#
# Set Script Variables
#
REPORT_FILE=/home/tiandi/Documents/capstats.csv
TEMP_FILE=/home/tiandi/Documents/capstats.html
#
DATE=`date +%m/%d/%y`
#
MAIL=`which mutt`
MAIL_TO=tiandi
#
###############################################################3
#
# Create Report Header
#
echo "