常用脚本

2017-01-22

记录日常使用到的脚本

监控脚本持续运行,看门狗(每次只有一个脚本在执行)

使用方法:把文件命名cron.sh,放入crontab: */1 * * * * /app/cron.sh ws.py

#!/bin/bash
# 监测$1一直运行
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

function run_only_one(){
        snum=`ps -ef|grep $1|grep -v grep|grep -v $0|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process $1..."
        else
            echo "$1 runing....."
            exit
        fi
}
run_only_one $1

screen -dmS cron_$1 ./$1
screen -S cron_$1 -p 0 -X stuff 'exit\n'

防止脚本重复执行(每次只有一个脚本在执行)

#!/bin/bash
function run_only_one(){
        PID=$$
        snum=`ps -ef|grep $0|grep -v grep|grep -v " $PPID "|grep -v " $PID "|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process....."
        else
            echo "runing....."
            exit
        fi  
}
run_only_one

把桌面mp4,m4a文件到mp3

C:\auto_run\bin\mp4tomp3.sh

#!/bin/bash
# 转换桌面的mp4,m4a文件到mp3
cd ~/Desktop
# 不要用空格做为IFS,用于遍历文件名存在空格的情况
IFS=$(echo -en "\n\b")
function conversion_to_mp3(){
   files=$(ls *.$1 2> /dev/null | wc -l)
   if [ "$files" != "0" ] ; then
      myarr=($(ls *.$1))
      for i in "${myarr[@]}"
      do
         NAME=`basename $i .$1`
         echo "****************ffmpeg $NAME******************"
         ffmpeg -i $i -f mp3 $NAME.mp3
      done
   else
      echo "路径:"`pwd`
      echo "不存在$1"
   fi
}
conversion_to_mp3 mp4
conversion_to_mp3 m4a

从视频网站URL剪贴板直接下载MP4到桌面

C:\auto_run\bin\vurldown.ps1

$a = Get-Clipboard 
Write-Output $a
lux $a

.ps1,因为在此系统上禁止运行脚本解决方案

管理员打开PowerShell

执行:

# 默认Scope是LocalMachine
Set-ExecutionPolicy RemoteSigned
Set-ExecutionPolicy RemoteSigned -Scope Process
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
# 啰嗦写法:Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser -Confirm:$False

查看权限情况:

Get-ExecutionPolicy -List

C:\auto_run\bin\vurldown.sh

#!/bin/bash
cd ~/Desktop
powershell C:/auto_run/bin/vurldown.ps1

并行拉取远程仓库

C:\auto_run\bin\UPALL.sh

#!/bin/bash
list=(
    "C:/01_cloud/github/pingmalu"
)

svnlist=(
    "C:/01_cloud/SAE/pingmalu"
)

for i in "${list[@]}"; do
    echo "****************git -C $i pull******************"
    start bash -c "echo -en \"\033]0;git -C $i pull\a\";git -C $i pull"
done

for i in "${svnlist[@]}"; do
    echo "****************svn up $i******************"
    start bash -c "echo -en \"\033]0;svn up $i\a\";svn up $i"
done

同时推送到所有远程git分支上

C:\auto_run\bin\pushall

#!/bin/bash
myarr=($(git remote -v |grep "push"|awk '{print $1}'|grep -v "origin"))
for i in "${myarr[@]}"
do
   echo "****************git push $i******************"
   start bash -c "echo -en \"\033]0;git push $i\a\";git push $i"
done

指定终端的title

如何更改 xterm 的标题:https://tldp.org/HOWTO/Xterm-Title-3.html

printf '\e]0;%s\e\\' "My title here"

系统 Proxy切换开关

cat proxy

#!/bin/bash
CLASH='http://192.168.50.1:50003'
if [[ $1 == "off" ]];then
    unset ALL_PROXY
    unset HTTP_PROXY
    unset HTTPS_PROXY
else
    export ALL_PROXY=$CLASH
    export HTTP_PROXY=$CLASH
    export HTTPS_PROXY=$CLASH
fi

放入/usr/local/bin/proxy

source proxy      #开启代理
source proxy off  #关闭代理

Git Proxy切换开关

bash_aliases写法:

alias px='git config --global --replace-all http.proxy http://192.168.50.1:50003'
alias nopx='git config --global --unset http.proxy'

cat git-proxy

#!/bin/bash
if [[ $1 == "no" ]];then
    git config --global --unset https.proxy
else
    git config --global https.proxy socks5://192.168.2.2:10808
fi

放入/usr/local/bin/git-proxy

git-proxy     #开启代理
git-proxy no  #关闭代理

本地hosts模拟实现DNS轮询脚本

cat auto_change_hosts.sh

#!/bin/bash
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

F='iplist'
F2=`cat ${F}|grep -A 1 '|1|'`
F3=`echo $F2|grep '|0|'`
if [[ $F3 == '' ]];then
	# 到最后一行的话取第一行
	F4=`head $F -n 1`
else
	F2=`echo $F3|awk '{print $1}'`
	F4=`echo $F3|awk '{print $2}'`
fi
IPOLD=`echo $F2|awk -F '|' '{print $1}'`
NUMOLD=`echo $F2|awk -F '|' '{print $3}'`
IPNEW=`echo $F4|awk -F '|' '{print $1}'`
NUMNEW=`echo $F4|awk -F '|' '{print $3}'`
if [[ $1 == 'error' ]];then
	NUMOLD=$[NUMOLD+1]
fi
sed -i "s/${IPOLD}.*/${IPOLD}\|0\|${NUMOLD}/;s/${IPNEW}.*/${IPNEW}\|1\|${NUMNEW}/" $F
cp -f /etc/hosts ~/hosts.new
sed -i "s/^[0-9].* malu\.me/$IPNEW malu\.me/" ~/hosts.new
cp -f ~/hosts.new /etc/hosts
cat /etc/hosts|grep 'malu.me'

cat iplist

11.5.100.200|1|0
11.5.100.201|0|0
11.5.200.202|0|0
11.5.200.203|0|0
11.5.300.204|0|0

cat /etc/hosts

11.5.100.200 malu.me

使用方法:

auto_change_hosts.sh [error]

如果加参数error,则iplist最后一列数值会累加,用于调用次数统计。

创建低权限用户脚本

首先添加用户boy并修改sshd_config文件

useradd boy
passwd boy

如果遇到无法找到/bin/sh的提示,则修改/etc/passwd文件中boy的shell

把 /bin/sh 改成 /bin/bash

vim /etc/ssh/sshd_config

Match User boy
ChrootDirectory /home/test

cat create_low_user.sh

#!/bin/bash
CHROOT_PATH='/home/test'
mkdir -p ${CHROOT_PATH}/dev/      
cd ${CHROOT_PATH}/dev/
mknod -m 666 null c 1 3
mknod -m 666 tty c 5 0
mknod -m 666 zero c 1 5
mknod -m 666 random c 1 8

chown root:root ${CHROOT_PATH}
chmod 0755 ${CHROOT_PATH}
ls -ld ${CHROOT_PATH}

mkdir -p ${CHROOT_PATH}/bin
cp -v /bin/bash ${CHROOT_PATH}/bin/

ldd /bin/bash
mkdir -p ${CHROOT_PATH}/lib64
cp -v /lib64/ld-linux-x86-64.so.2 ${CHROOT_PATH}/lib64/
mkdir -p ${CHROOT_PATH}/lib/x86_64-linux-gnu/
cp -v /lib/x86_64-linux-gnu/{libtinfo.so.5,libdl.so.2,libc.so.6} ${CHROOT_PATH}/lib/x86_64-linux-gnu/

mkdir ${CHROOT_PATH}/etc
cp -vf /etc/{passwd,group} ${CHROOT_PATH}/etc/

把本地文件夹备份至远程服务器

1.通过scp拷贝目录

#!/bin/bash
dd=`date '+%Y-%m-%d-%H%M%S'`
scp -i /root/.ssh/id_rsa -P 22 -r /local root@malu.me:/backup/${dd}

2.拷贝目录至windows共享 (如果有防火墙,需允许445, 135, 137, 138, 139 UDP和TCP)

#!/bin/bash
dd=`date '+%Y-%m-%d-%H%M%S'`
smbclient -c "mkdir ${dd};prompt OFF;recurse ON;lcd /local;cd ${dd};mput *" //IP/share -U username%password

切换到当前目录执行脚本

#!/bin/bash
MY_PATH=$(cd "$(dirname "$0")"; pwd)
cd $MY_PATH

scp拷贝最近3天日期命名的tar.z文件,并删除本地6天前的tar.z文件

#!/bin/bash
for((i=0;i<=3;i++)); do
	datefile=`date -d"$i day ago" +%Y%m%d`.tar.z
	if [ ! -f "$datefile" ]; then
		scp malu.me:/backup/$datefile /home/backup/
	fi
done
find ./ -mtime +6 -type f -name "*.tar.z"|xargs rm -f

防止脚本重复执行(每次只有一个脚本在执行)

#!/bin/bash
function run_only_one(){
        PID=$$
        snum=`ps -ef|grep $0|grep -v grep|grep -v " $PPID "|grep -v " $PID "|wc -l`
        if [ $snum -lt 1 ]; then
            echo "start process....."
        else
            echo "runing....."
            exit
        fi  
}
run_only_one

合并指定目录下的所有文本,并去除重复行,并过滤^M字符 (生成超级字典)

#!/bin/bash
if [ $# != 1 ] ; then 
echo "USAGE: $0 FLODER" 
exit 1;  
fi
root_dir=$1
NEWFILE=newfile_dic.txt
NEWFILE_TMP=newfile_dic.txt.tmp
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
function getdir(){
    for element in `ls $1`
    do  
        dir_or_file=$1"/"$element
        if [ -d $dir_or_file ]
        then 
            getdir $dir_or_file
        else
            echo -n $dir_or_file
            cat $dir_or_file |sed 's/^M//g'>> $NEWFILE_TMP
            echo '              ok'
        fi  
    done
}
getdir $root_dir
IFS=$SAVEIFS
sort $NEWFILE_TMP|uniq > $NEWFILE
rm -f $NEWFILE_TMP

注意:^M的输入方式是 Ctrl + v ,然后Ctrl + m

杀死进程及其所有子进程

pstree -p PID | grep -oP '(?<=\()[0-9]+(?=\))'|xargs kill -9

杀死包含关键字的进程,及其所有子进程

#!/bin/bash
PID=`ps -ef|grep [n]ame|awk '{print $2}'`
expr 1 + $PID > /dev/null 2>&1
if [[ $? -eq 0 ]]; then
	pstree -p $PID | grep -oP '(?<=\()[0-9]+(?=\))'|xargs kill -9
fi

将目录下所有文件名改成小写

for i in `find ./`;do mv $i `echo $i |tr [A-Z] [a-z]`;done

防御CC攻击脚本

#!/bin/sh
status=`netstat -na|awk '$5 ~ /[0-9]+:[0-9]+/ {print $5}' |awk -F ":" -- '{print $1}' |sort -n|uniq -c |sort -n|tail -n 1`
NUM=`echo $status|awk '{print $1}'`
IP=`echo $status|awk '{print $2}'`
result=`echo "$NUM > 150" | bc`
if [ $result = 1 ]
then
  echo IP:$IP is over $NUM, BAN IT!
  /sbin/iptables -I INPUT -s $IP -j DROP
fi

向进程发送按键指令

其实用C写的,算不上脚本。需要先编译:

gcc key.c -o key.bin

运行:

./key.bin PID cmd

#include <sys/ioctl.h>
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

void stackchar(int fd,char c)
{
        if (ioctl(fd, TIOCSTI, &c) < 0) {
                perror("ioctl");
                exit(1);
        }
}

int main(int argc, char *argv[])
{
        int i, j;
        char c;
        char proc_file[20];
        int mixer_fd=0;

        strcpy(proc_file,"/proc/");
        strcat(proc_file,argv[1]);
        strcat(proc_file,"/fd/1");

        if ((mixer_fd = open(proc_file,O_WRONLY))){
                for (i = 2; i < argc; i++) {
                        if (i > 1) stackchar(mixer_fd,' ');
                        for (j=0; (c = argv[i][j]); j++) {
                                stackchar(mixer_fd,c);
                        }
                }
        }

        stackchar(mixer_fd,'\n');
        exit(0);
}

向本地监听的所有匹配端口发送curl请求

netstat -lnt4p|grep sshd|grep -v ':22 '|awk -F '0.0.0.0:' '{print $2}'|awk '{print $1}'|xargs -t -i curl localhost:{}