最后附上一些我常用的脚本: 软件安装完成之后设置为linux开机启动 大多数linux发行版本提供了一个本地开机文件专门让系统管理员添加开机时候运行的脚本。脚本必须绝对路径。debian的本地开机文件是/etc/init.d/rc.local,redhat是/etc/rc.local。 除此之外还能用chkconfig
来做:
我自用的apache安装脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 #!/bin/bash # 需要sudo执行 dir=`pwd` #要安装pcre先要安装gcc, g++ if [[ `ls /etc|grep redhat-release` != "" ]] then yum -y install gcc gcc-c++ elif [[ `ls /etc|grep debian_version` != "" ]] then apt-get -y install gcc gcc-c++ fi if [[ `ls|grep apr` == "" ]] then wget http://mirrors.cnnic.cn/apache//apr/apr-1.5.2.tar.gz fi tar -zxvf apr-1.5.2.tar.gz mkdir /usr/local/lib/apr-1.5.2 cd $dir/apr-1.5.2 ./configure --prefix=/usr/local/lib/apr-1.5.2 make make install cd $dir if [[ `ls|grep apr-util` == "" ]] then wget http://mirrors.cnnic.cn/apache//apr/apr-util-1.5.4.tar.gz fi tar -zxvf apr-util-1.5.4.tar.gz mkdir /usr/local/lib/apr-util-1.5.4.tar.gz cd $dir/apr-util-1.5.4 ./configure --prefix=/usr/local/lib/apr-util-1.5.4 --with-apr=/usr/local/lib/apr-1.5.2 make make install cd $dir if [[ `ls|grep pcre` == "" ]] then wget http://ncu.dl.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz fi tar -zxvf pcre-8.37.tar.gz mkdir /usr/local/lib/pcre-8.37 cd $dir/pcre-8.37 ./configure --prefix=/usr/local/lib/pcre-8.37 make make install cd $dir if [[ `ls|grep httpd` == "" ]] then wget http://www.apache.org/dist/httpd/httpd-2.4.12.tar.gz fi tar -zxvf httpd-2.4.12.tar.gz mkdir /usr/local/lib/httpd-2.4.12 cd $dir/httpd-2.4.12 ./configure --prefix=/usr/local/lib/httpd-2.4.12 --with-apr=/usr/local/lib/apr-1.5.2 --with-apr-util=/usr/local/lib/apr-util-1.5.4 --with-pcre=/usr/local/lib/pcre-8.37 --enable-so make make install #解决httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message sed -i 's/^#ServerName www.example.com:80/ServerName localhost/g' /usr/local/lib/httpd-2.4.12/conf/httpd.conf /usr/local/lib/httpd-2.4.12/bin/apachectl start #启动apache if [[ `curl -s localhost:80|grep "It works"` != "" ]] then echo "----------------------安装成功-------------------------------------" cd $dir rm -rf apr-1.5.2/ apr-util-1.5.4/ pcre-8.37/ httpd-2.4.12/ fi #设置apache开机启动 echo "/usr/local/lib/httpd-2.4.12/bin/apachectl start" >> /etc/rc.local
编码转换: 我的脚本就这么一行代码,所以直接上代码: 转换的命令为iconv
,把hello.txt文本当中的gb2312编码转为utf-8编码:
1 iconv -c -f gb2312 -t utf-8 hello.txt > world.txt
或者使用-o
的参数:
1 iconv -c -f gb2312 -t utf-8 hello.txt -o hello.txt
查看CPU和内存的使用情况,并打印日志: 这个脚本要配合crontab
一起使用:monitor.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #!/bin/bash # 首先监控服务器的CPU和内存 # 查看服务器CPU的核数 model_count() { echo `grep -c 'model name' /proc/cpuinfo` } # 查看服务器15分钟内的平均负载情况 CPU_load() { echo `uptime | awk '{print $10}'` } # 查看服务器的ip地址 ip_address() { echo `ifconfig | grep "192." | awk '{print substr($2,6)}'` } # 查看内存使用情况 memory_used() { echo `free -hm | grep Mem | awk '{print $4}'` } # 查看系统磁盘空间 disk_used() { echo `df -h | awk -vfield=$1 '{if($6==field) print $5}'` } # 根据进程名查找进程id process_id() { echo `ps aux | grep $1 | awk '{print $2}'` } # 查看进程id的CPU使用率 process_CPU_used() { echo `ps -p $1 -o pcpu --no-headers` } # 查看进程id的内存使用率 process_memory_used() { memory=`ps -p $1 -o vsz --no-headers` result=$[$memory/1000] echo $result } server_monitor() { # 打日志,日志文件为每天 mkdir -p ./server_log/ server_log=server_load.`date +"%y-%m-%d"`.log date >> ./server_log/$server_log echo "server's ip address is " `ip_address` >> ./server_log/$server_log echo "CPU's core number is " `model_count` >> ./server_log/$server_log echo "CPU's load is " `CPU_load` >> ./server_log/$server_log echo "Memory used is " `memory_used` >> ./server_log/$server_log #查看根目录的磁盘使用空间 echo "disk used is " `disk_used "/"` >> ./server_log/$server_log processId=`process_id "chrome"` echo "chrome process CPU used " `process_CPU_used $processId` >> ./server_log/$server_log echo "chrome process memory used " `process_memory_used $processId` "M" >> ./server_log/$server_log echo "===============================" >> ./server_log/$server_log } server_monitor
从xml当中读取redis的ip地址和端口号: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/bin/bash # 获取当前地址 CMD=$0 if [[ ${CMD} == /* ]]; then CDIR=${CMD%/*} else CDIR=`pwd`"/"${CMD%/*} fi # 根据当期地址找到全局的配置文件 GLOBALCONF="${CDIR}/../conf/DeployConfig.xml" # 拿到redis的ip和端口 REDIS_SERVER_IP=`cat ${GLOBALCONF} | tr -s '\r\n' ' ' | sed 's/^.*REDIS<\/type>\s*<ip>\(\w*\.\w*\.\w*\.\w*\)<\/ip>.*$/\1/'` REDIS_SERVER_PORT=`cat ${GLOBALCONF} | tr -s '\r\n' ' ' | sed 's/^.*REDIS<\/type>\s*<ip>\(\w*\.\w*\.\w*\.\w*\)<\/ip>\s*<port>\(\w*\)<\/port>.*$/\2/'` #echo ${GLOBALCONF} #echo ${REDIS_SERVER_IP} #echo ${REDIS_SERVER_PORT}
生成安全秘钥用于验证登陆: 在写这个脚本之前先介绍一下openssl
命令,我就是用这个命令进行加密和解密的,算法使用的是aes
只要利用openssl help
就可以看到更多的安全算法了
对字符串‘abc’进行aes
加密,使用密钥123,输出结果以base64编码格式给出:
1 echo abc | openssl aes-128-cbc -k 123 -base64
生成的密码为:
1 U2FsdGVkX198JFSRzZGVS+pY+egLZO+vbHQeMDJ/Qv4=
可以对密码进行解密来查看生成密码的正确性:
1 2 echo U2FsdGVkX198JFSRzZGVS+pY+egLZO+vbHQeMDJ/Qv4= | openssl aes-128-cbc -d -k 123 -base64
可以看到输出为
这里要说一下我遇到的有关-A参数的问题。openssl基于enc(symmetric cipher routines)的加密解密时command里要添加-A 选项。这个选项的作用是对于一串字符加密或解密时,所有内容在一行内输出。在需要加密的字符串长度超过40时(今在我的电脑上测试的数据,fedora 20),如果没有加入-A选项,解密时会出现”error reading input file” 以及 “bad magic number” 这两种错误提示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #!/bin/bash #====================================== # Author: xiongjun #====================================== if [ $# -lt 2 ] then echo -ne "\033[31m" echo "genKey.sh doesn't get enough arguments" echo -ne "\033[0m" echo -ne "\033[32m" echo "./genKey.sh <UserName> <password> " echo "example : ./genKey.sh baidu official " echo "example : ./genKey.sh baidu try" echo -ne "\033[0m" exit fi CompanyName=$1 Password=$2 mark="###==###==#" line=$UserName$mark$Password echo $line | openssl enc -aes-128-cbc -k KEY -base64 -A > ${UserName}_key
释放所有共享内存: 1 2 3 4 5 6 7 8 username=`whoami` # 显示所有的共享内存 shmids=`ipcs -m | grep $username | awk '{print $2}'` for shmid in `echo $shmids`; do # 释放所有的共享内存 ipcrm -m $shmid; done
写接口用的代码生成器: 我写C++代码的后端接口的增删改查我直接都是用这个代码生成器来完成的,这里用了很多awk
的函数。 说是代码生成器,其实是代码修改器,就是先拷贝一个以前的工程目录下来,然后在这个拷贝的目录当中执行这段脚本来修改接口名称:由于这里使用了awk
指定了下划线,所以接口名必须是有下划线:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 #!/bin/bash #这是个代码生成器, 函数都是使用echo来返回 #首字母大写, 就是把list_db改成List_Db first_upper() { result=""; count=`echo $1 | awk -F_ '{print NF}'` for ((i=0;i<count;i++)) do #根据下划线取出被分隔的字符串 #由于awk的原因,不能在awk的print当中直接使用i,所以要在这里先把外部的一个变量field设为和比i大1的值,再用awk的-v参数传给print temp=$[$i+1] word=`echo $1 | awk -vfield=$temp -F_ '{print $field}'` result_word=`echo $word | awk '{printf "%s%s", toupper(substr($0, 1, 1)), tolower(substr($0, 2))}'` if (( i==0 )) then result=$result_word; else #让result后增加下划线 result=`echo $result"_"$result_word` fi done echo $result } #用awk -F_ 的原因是我写的JAVA代码的很多接口名称都是有下划线的 all_upper() { echo $1 | awk -F_ '{print toupper($0)}' } all_lower() { echo $1 | awk -F_ '{print tolower($0)}' } #去掉下划线 erase_symbol() { echo $1 | awk -F_ '{for(i=1;i<=NF;i++) printf "%s", $i}' } main() { STR_SRC=$1 STR_DST=$2 # list_db LOWER_SRC=`all_lower $1` LOWER_DST=`all_lower $2` # LIST_DB UPPER_SRC=`all_upper $1` UPPER_DST=`all_upper $2` # List_Db FIRST_UPPER_SRC=`first_upper $LOWER_SRC` FIRST_UPPER_DST=`first_upper $LOWER_DST` # 驼峰命名法ListDb HUMP_SRC=`erase_symbol $FIRST_UPPER_SRC` HUMP_DST=`erase_symbol $FIRST_UPPER_DST` for src_file in `ls $1.{cpp,h}` do dst_file=`echo $src_file | sed "s/$STR_SRC/$STR_DST/g"` # 复制文件名 cp $src_file $dst_file # 替换文件当中的字符串 sed -i "s/$UPPER_SRC/$UPPER_DST/g" $dst_file sed -i "s/$LOWER_SRC/$LOWER_DST/g" $dst_file sed -i "s/$FIRST_UPPER_SRC/$FIRST_UPPER_DST/g" $dst_file sed -i "s/$HUMP_SRC/$HUMP_DST/g" $dst_file done } show_help() { echo -ne "\033[31m" echo "code_machine.sh doesn't get enough arguments" echo -ne "\033[0m" echo -ne "\033[32m" echo "./code_machine.sh <src> <dst> " echo "example : ./genKey.sh list_db just_test " echo "example : ./genKey.sh list_db this_just_test" echo -ne "\033[0m" exit } # 使用while循环是为了将来可能会扩展参数 while [ -n "$1" ] do case "$1" in -h) show_help ;; --) shift #使用shift将当前的参数双破折线移除 break ;; *) main $1 $2 shift #这里要再移动一下,因为这里使用了2个参数 ;; esac shift done
我们来测试一下: 比如我有一个接口:list_db.h
和list.db.cpp
list.cpp
也是一样的内容:
在命令行下执行
1 ./code_machine.sh list_db this_just_test
可以看到在目录下生成了this_just_test.h
和this_just_test.cpp
:just_test.h
:
this_just_test.h
this_just_test.cpp
用shell脚本和crontab
自动在豆瓣上顶贴: 这个在我的CSDN博客上利用linux shell自动顶贴 也用过了: