Author Archives: duanzhihe

About duanzhihe

热爱思考,热爱生活,喜欢用文字记录心情,描绘所想

Mac 以及移动端 抓包工具 Charles 的使用

Charles 是个很牛逼的抓包工具写爬虫的同志们估计就很熟悉了,经常用这个干坏事!

首先,我们去下载Charles破解版http://pan.baidu.com/s/1jHFv0GI 里面带有破解包charles.jar,下载后按照提示安装,安装之后点击右键显示包内容进入Resource文件中的java文件替换charles.jar 。

替换完成后可以打开了,不过这里可能存在问题,提示类似“您需要安装旧 Java SE 6 运行环境才能打开charles”的文案,若是遇到的话,到苹果官网下载javaforosx.dmg并安装,然后在打开应该就可以了。

打开后界面如下:

为了能够抓到mac下的访问,我们要简单做一下这样的设置:

以上步骤都完事,理论上就可以抓到电脑上的代码了。下面看怎么抓到移动端的(必须令电脑和手机在同一个局域网段),这里和fiddler很像,若是对fiddler有了解的应该清除,首先应该安装证书,这里和fiddler有些不一样,直接利用charles提供的下载就可以,点击这里,点击完成之后安装。

这里提示一下,IOS高版本,安装完证书后还要启用一下,启用位置是 设置-》通用-》关于本机-》证书信任设置(最下面),打开后把charles打开就可以了。

然后,要做的就和fiddler一样要看本机的ip地址,本机ip地址查看可以利用终端输入ifconfig,也可以点开屏幕右上角的小苹果-》系统偏好设置-》网络-》选中自己的网络,然后点击左下角偏上一点的高级,随后切换到TCP/IP的tab就可以看到自己的ip地址了,看到ip地址后需要在手机上设置代理了哦!

打开手机,设置—》无线局域,选择和电脑同一网段的网络点击进入设置详情(这里每个手机情况可能不同,如IOS是一个被圈起来的蓝色感叹号),进入后滑动到下面,设置Http代理服务器地址填写你mac上的IP地址端口号填写8888 步骤如下:

填写完毕之后Charles窗口会弹出一个提示这时点击Allow按钮即可到这一步就说明配置成功,你手机访问的网络便可以被Charles捕获到了!

用手机打开浏览器或者打开一个App在Charles窗口上都会捕获到访问地址这时你就可以分析他们的请求数据格式进行数据爬取!

温馨提示:不用代理抓包的时候记得把手机上的代理关掉,省的造成代理设置还在,但charles关了造成无法访问网络的情况。

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

nodejs抓取网页邮箱

用到的正则匹配还是不太准确,也并未做到在全网去搜索邮箱地址,需要先限定位置,再去匹配,总之还有很多需要处理的问题,废话不多说了,直接上代码吧,以贴吧为例(其中用到的有些工具包需要自行安装):

var express = require('express');
var superagent = require('superagent');
var cheerio = require('cheerio');
var url = require('url');
var fs = require('fs');
var eventproxy = require('eventproxy');
var ep = new eventproxy();
var app = express();
 
var getUrl = 'http://tieba.baidu.com/p/3699247110?pid=66984513696&cid=0#66984513696';
var reg = new RegExp('[a-zA-Z_0-9-.]{1,}\@([a-zA-Z_0-9]{1,}\.){1}[a-zA-Z_0-9]{1,}', "gim");
superagent.get(getUrl)
.end(function (err, sres) {
    // 常规的错误处理
    if (err) {
        return next(err);
    }
    // sres.text 里面存储着网页的 html 内容,将它传给 cheerio.load 之后
    // 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
    // 剩下就都是 jquery 的内容了
    var arr = [];
    
    var $ = cheerio.load(sres.text);
    $('.d_post_content_main .j_d_post_content').each(function (idx, element) {
        while(tem=reg.exec($(this).text())){
            arr.push(tem[0]);
        }
    });
    fs.writeFile('getEmail.txt', arr, function (err) {
        if (err) throw err;
        console.log('It\'s saved!');
    });
});

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

将文件隐藏在图片中

工作中看到的内容,将文件隐藏在图片中:

#coding=utf-8

import zipfile
 
#创建zip文件,使用'a'追加模式,同时file指向一个已存在的非zip文件
zf = zipfile.ZipFile('g_e_index.jpg','a',zipfile.ZIP_DEFLATED)

 
#将文本文件附加到flower中
zf.write('host.txt')
 
#关闭zip文件
zf.close()

参考文章:http://zhujiangtao.com/?p=563
https://docs.python.org/3/library/zipfile.html#module-zipfile

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

利用window.onerror捕获并上报Js错误,具体到某一行

之前都是用try{}catch(){}来捕获监听js报错信息,具体文章可以看js报错信息,以及文件加载失败问题的log日志统计方式,但这个监听的报错信息只能到具体的文件,并不能定位到具体哪一行报错了,于是根据业务需求找了一下,发现还真有其他方式可以实现,那就是window.error函数,具体看示例代码。

<!DOCTYPE html>
<html>
<head>
    <title>Js错误捕获</title>
    <script type="text/javascript">
    /**
     * @param {String}  errorMessage   错误信息
     * @param {String}  scriptURI      出错的文件
     * @param {Long}    lineNumber     出错代码的行号
     * @param {Long}    columnNumber   出错代码的列号
     * @param {Object}  errorObj       错误的详细信息,Anything
     */
    window.onerror = function(errorMessage, scriptURI, lineNumber,columnNumber,errorObj) {
       console.log("错误信息:" , errorMessage);
       console.log("出错文件:" , scriptURI);
       console.log("出错行号:" , lineNumber);
       console.log("出错列号:" , columnNumber);
       console.log("错误详情:" , errorObj);
    }
    </script>
</head>
<body>
    <script type="text/javascript">
      console.log('s')
      console.log(df)
    </script>
</body>
</html>

运行之后报错信息全出来了,由于故意写错的代码直接放到了html里面,所以报错的文件就是当前的html文件,若是引入的js文件,那报错文件就会是引入的js文件了。不错不错,这个真的很好用啊。

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

mac下delete往后删除

以前用windows都知道backspace是从后往前删除,delete是从前往后删除,用了mac后发现就一个delete键了,没办法往后删除还真不方便,于是查了查,发现原来fn+delete就可以从前往后删除了。

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

mac下的chrome常用快捷键

打开新的标签页:⌘-T;
打开新的窗口:⌘-N;
打开新的隐身窗口:shift-⌘-N;

查看历史记录:⌘-Y;
下载内容:shift-⌘-J;
开发者工具:option-⌘-I;
查找:⌘-F;
保存页面:⌘-S;
清除浏览器数据:shift-⌘-Delete;
帮助中心:shift-⌘-?;
打开书签管理器:option-⌘-I;
显示隐藏书签栏:option-⌘-B;
查看网页源码:option-⌘-U;

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

node+express+multer+zbarimg实现图片上传识别二维码

环境windows,这里比较坑的原因是找识别二维码的工具,只知道了python下的zbarimg可以用,而zbarimg又是python2.6x的,找了半天才找到一个支持python2.7x的,不过是windows的exe文件,下载地址在这里 http://download.csdn.net/detail/cranes1224/9788139,需要python2.7的环境(也就是你的电脑需要安装python2.7,python3.x的版本是不行的),下载后在选择安装路径的时候选择安装在python2.7的安装路径,安装完成在python2.7的目录下就可以看到zbarimg.exe,然后cd到对应目录,zbarimg -q E:\python\zbarImg\test.png,test.png二维码就被识别出来显示在窗口了! 备注资源来自GitHub,地址:https://github.com/jacobvalenta/zbar-py27-msi,若是访问GitHub没障碍的话,也可以从GitHub上面下载!

python2.7和zbarimg,接着要准备node和express,以及multer,相关安装不熟悉请自行查找对应的参考文章或官方文档!

都准备好了,直接上代码,服务端代码:

var fs = require('fs');
var express = require('express');
var multer  = require('multer');

var app = express();
var exec = require('child_process').exec;
//创建文件夹函数
var createFolder = function(folder){
    try{
        fs.accessSync(folder); 
    }catch(e){
        fs.mkdirSync(folder);
    }  
};
var uploadFolder = 'upload/';

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, uploadFolder);    // 保存的路径,备注:需要自己创建
    },
    filename: function (req, file, cb) {
        // 将保存文件名设置为 字段名 + 时间戳,比如 logo-1478521468943
        cb(null, file.originalname);  
    }
});

var upload = multer({storage : storage });

app.get('/zbarcam',function(req,res,next){
  var form = fs.readFileSync('htmlViews/zbarcam.html', {encoding: 'utf8'});
    res.send(form);
});

app.post('/upload', upload.single('logo'), function(req, res, next){
    var file = req.file;
    var cmdStr = 'C:\\Python27\\zbarimg E:\\express\\myapp\\upload\\'+file.originalname; //此处请根据自己的实际情况来;
    exec(cmdStr, function(err,stdout,stderr){
      if(err) {
          res.send('get weather api error:'+stderr);
      } else {
        res.send(stdout)
      }
  })
});

app.listen(3001)

上述代码用到的zbarcam.html的代码:

<form action="/upload" method="post" enctype="multipart/form-data">
    <h2>单图上传</h2>
    <input type="file" name="logo">
    <input type="submit" value="提交">
</form>

参考文章:http://www.cnblogs.com/chyingp/p/express-multer-file-upload.html

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python小代码

为朋友写的简单统计考勤的小代码,分为python3.5.2版本和python2.7.11版本:

2.7.11版本代码如下(需要引用的库自己去引用):

#encoding=utf-8
import xlrd
import xlwt
from xlrd import xldate_as_tuple
import datetime
import sys

def getFirstNum(time):
	timeArray = time.split(':');
	return int(timeArray[0])*60 + int(timeArray[1]);

def getRowLine(file,index):
	row_content = []
	for j in range(file.ncols):
		ctype = file.cell(index, j).ctype  # 表格的数据类型
		cell = file.cell_value(index, j)
		if ctype == 2 and cell % 1 == 0:  # 如果是整形
			cell = int(cell)
		elif ctype == 3: # 转成datetime对象
			y,mm,d,h,m,s = xldate_as_tuple(cell, 0)
			cell = str(h)+':'+str(m)+':'+str(s);
		elif ctype == 4:
			cell = True if cell == 1 else False
		row_content.append(cell)
	return row_content;
#补全考勤缺勤部分
def queQinFill(copyItem,startDate,endDate,index):
	qDiffDays = (endDate - startDate).days;
	for i in range(0,qDiffDays):
		dayWeek = startDate.weekday();
		if(dayWeek != 5 and dayWeek != 6 and (startDate.strftime('%Y-%m-%d') not in noQueQin)):
			for j in range(0,4):
				writeSheet.write(index,j,str(copyItem[j]));
			writeSheet.write(index,j,startDate.strftime('%Y-%m-%d'));
			j+=1;
			writeSheet.write(index,j,u'缺勤');
			index+=1;
		startDate = startDate + datetime.timedelta(1);
	return index;


#打开读文件
readWorkBook = xlrd.open_workbook('kaoqin.xls');
readSheet = readWorkBook.sheet_by_index(0) #sheet索引从0开始
#打开写文件
writeWorkBook = xlwt.Workbook(encoding='utf-8');
writeSheet = writeWorkBook.add_sheet('kaoqin',cell_overwrite_ok=True) 
#获取要读取文件的行数
rows = readSheet.nrows;
#考勤日期列表
#当前操作人员
cUserName = getRowLine(readSheet,1)[1];
#读取考勤起始和结束月份,以及差值天数
beginDay = datetime.datetime.strptime('2017-09-26','%Y-%m-%d');
endDay = datetime.datetime.strptime('2017-10-26','%Y-%m-%d');
diffDay = (endDay - beginDay).days;
#出勤天数
cqDay = 0;
#餐补天数
cbDay = 0;
#当前函数
cRows = 0;
#上一个日期
lastDay = '';
lastTable = '';
#抛去不算加班的日期列表
noJiaBan = ['2017-10-14'];
#抛去异常考勤的日期列表
noQueQin = ['2017-10-02','2017-10-03','2017-10-04','2017-10-05','2017-10-06'];

#重置系统的默认编码
reload(sys)                      # reload 才能调用 setdefaultencoding 方法  
sys.setdefaultencoding('utf-8')

for i in range(1, rows): #根据行数建立循环
	#取出每一行的数据
	rowsTable = getRowLine(readSheet,i);
	#判断取出的人员是否和前一个一致
	userName = rowsTable[1]; #获取用户名称
	if cUserName != userName:
		#判断结束位置缺勤日期
		if(lastDay != '' and  (endDay - lastDay).days > 1):
			cRows = queQinFill(lastTable,(lastDay + datetime.timedelta(1)),endDay,cRows);
		writeSheet.write(cRows,0,str(cUserName));
		writeSheet.write(cRows,1,'出勤'+str(cqDay)+'天');
		writeSheet.write(cRows,2,'餐补'+str(cbDay)+'天');
		cqDay = 1;
		cbDay = 1;
		cUserName = userName;
		cRows+=1;
		lastDay = '';
		lastTable = '';
	else:
		#判断此日期是否在考勤指定日期内
		currentDay = datetime.datetime.strptime(rowsTable[3],'%Y-%m-%d');
		if(beginDay <= currentDay and  currentDay <= endDay):
			#判断起始位置的考勤缺
			if(lastDay == '' and currentDay > beginDay):
				cRows = queQinFill(rowsTable,beginDay,currentDay,cRows);
			#判断是否当前和上一个差值是一天
			if(lastDay != '' and  (currentDay - lastDay).days > 1):
				cRows = queQinFill(rowsTable,(lastDay + datetime.timedelta(1)),currentDay,cRows);
			#更新last标识
			lastDay = currentDay;
			lastTable = rowsTable;
			#加班统计
			if((currentDay.weekday() == 5 or currentDay.weekday() == 6) and (rowsTable[3] not in noJiaBan)):
				for i in range(0,len(rowsTable)):
					writeSheet.write(cRows,i,str(rowsTable[i]));
				writeSheet.write(cRows,i,'加班');
				cRows+=1;
				continue;
			#判断餐补天数和异常考勤
			cqDay+=1;
			kqDate = rowsTable[4:];
			kqDate = [x for x in kqDate if x != ''];
			if(len(kqDate) < 2):   #若是打开时间段小于2则说明是异常考勤存在漏打卡
				for i in range(0,len(rowsTable)):
					writeSheet.write(cRows,i,str(rowsTable[i]));
				writeSheet.write(cRows,i,'漏打卡');
				cRows+=1;
			else:  #判断时间段的第一个值和最后一个值,若是在7-19:30之间则属于正常考勤
				if(getFirstNum(kqDate[0]) > 7*60 and getFirstNum(kqDate[0]) < 10*60 and getFirstNum(kqDate[-1]) > 19.5*60):
					if(getFirstNum(kqDate[-1]) > 20*60): #大于晚上八点有一个餐补
						cbDay+=1;
				else:
					for i in range(0,len(rowsTable)):
						writeSheet.write(cRows,i,str(rowsTable[i]));
					writeSheet.write(cRows,i,'打卡异常');
					cRows+=1;
#最后一个人的数据存储
if(lastDay != '' and  (endDay - lastDay).days > 1):
	cRows = queQinFill(lastTable,(lastDay + datetime.timedelta(1)),endDay,cRows);
writeSheet.write(cRows,0,str(cUserName));
writeSheet.write(cRows,1,'出勤'+str(cqDay)+'天');
writeSheet.write(cRows,2,'餐补'+str(cbDay)+'天');
writeWorkBook.save('result.xls')

python3.5.2版本(需要引用的库自己引用,编码处理这块比2.7还是要方便很多啊)

import xlrd
import xlwt
from xlrd import xldate_as_tuple
import datetime

def getFirstNum(time):
	timeArray = time.split(':');
	return int(timeArray[0])*60 + int(timeArray[1]);

def getRowLine(file,index):
	row_content = []
	for j in range(file.ncols):
		ctype = file.cell(index, j).ctype  # 表格的数据类型
		cell = file.cell_value(index, j)
		if ctype == 2 and cell % 1 == 0:  # 如果是整形
			cell = int(cell)
		elif ctype == 3: # 转成datetime对象
			*year,h,m,s = xldate_as_tuple(cell, 0)
			cell = str(h)+':'+str(m)+':'+str(s);
		elif ctype == 4:
			cell = True if cell == 1 else False
		row_content.append(cell)
	return row_content;
#补全考勤缺勤部分
def queQinFill(copyItem,startDate,endDate,index):
	qDiffDays = (endDate - startDate).days;
	for i in range(0,qDiffDays):
		dayWeek = startDate.weekday();
		if(dayWeek != 5 and dayWeek != 6 and (startDate.strftime('%Y-%m-%d') not in noQueQin)):
			for j in range(0,4):
				writeSheet.write(index,j,str(copyItem[j]));
			writeSheet.write(index,j,startDate.strftime('%Y-%m-%d'));
			j+=1;
			writeSheet.write(index,j,'缺勤');
			index+=1;
		startDate = startDate + datetime.timedelta(1);
	return index;


#打开读文件
readWorkBook = xlrd.open_workbook('kaoqin.xls');
readSheet = readWorkBook.sheet_by_index(0) #sheet索引从0开始
#打开写文件
writeWorkBook = xlwt.Workbook();
writeSheet = writeWorkBook.add_sheet('kaoqin',cell_overwrite_ok=True) 
#获取要读取文件的行数
rows = readSheet.nrows;
#考勤日期列表
#当前操作人员
cUserName = getRowLine(readSheet,1)[1];
#读取考勤起始和结束月份,以及差值天数
beginDay = datetime.datetime.strptime('2017-09-26','%Y-%m-%d');
endDay = datetime.datetime.strptime('2017-10-26','%Y-%m-%d');
diffDay = (endDay - beginDay).days;
#出勤天数
cqDay = 0;
#餐补天数
cbDay = 0;
#当前函数
cRows = 0;
#上一个日期
lastDay = '';
lastTable = '';
#抛去不算加班的日期列表
noJiaBan = ['2017-10-14'];
#抛去异常考勤的日期列表
noQueQin = ['2017-10-02','2017-10-03','2017-10-04','2017-10-05','2017-10-06'];
for i in range(1, rows): #根据行数建立循环
	#取出每一行的数据
	rowsTable = getRowLine(readSheet,i);
	#判断取出的人员是否和前一个一致
	userName = rowsTable[1]; #获取用户名称
	if cUserName != userName:
		#判断结束位置缺勤日期
		if(lastDay != '' and  (endDay - lastDay).days > 1):
			cRows = queQinFill(lastTable,(lastDay + datetime.timedelta(1)),endDay,cRows);
		writeSheet.write(cRows,0,str(cUserName));
		writeSheet.write(cRows,1,'出勤'+str(cqDay)+'天');
		writeSheet.write(cRows,2,'餐补'+str(cbDay)+'天');
		cqDay = 1;
		cbDay = 1;
		cUserName = userName;
		cRows+=1;
		lastDay = '';
		lastTable = '';
	else:
		#判断此日期是否在考勤指定日期内
		currentDay = datetime.datetime.strptime(rowsTable[3],'%Y-%m-%d');
		if(beginDay <= currentDay and  currentDay <= endDay):
			#判断起始位置的考勤缺
			if(lastDay == '' and currentDay > beginDay):
				cRows = queQinFill(rowsTable,beginDay,currentDay,cRows);
			#判断是否当前和上一个差值是一天
			if(lastDay != '' and  (currentDay - lastDay).days > 1):
				cRows = queQinFill(rowsTable,(lastDay + datetime.timedelta(1)),currentDay,cRows);
			#更新last标识
			lastDay = currentDay;
			lastTable = rowsTable;
			#加班统计
			if((currentDay.weekday() == 5 or currentDay.weekday() == 6) and (rowsTable[3] not in noJiaBan)):
				for i in range(0,len(rowsTable)):
					writeSheet.write(cRows,i,str(rowsTable[i]));
				writeSheet.write(cRows,i,'加班');
				cRows+=1;
				continue;
			#判断餐补天数和异常考勤
			cqDay+=1;
			kqDate = rowsTable[4:];
			kqDate = [x for x in kqDate if x != ''];
			if(len(kqDate) < 2):   #若是打开时间段小于2则说明是异常考勤存在漏打卡
				for i in range(0,len(rowsTable)):
					writeSheet.write(cRows,i,str(rowsTable[i]));
				writeSheet.write(cRows,i,'漏打卡');
				cRows+=1;
			else:  #判断时间段的第一个值和最后一个值,若是在7-19:30之间则属于正常考勤
				if(getFirstNum(kqDate[0]) > 7*60 and getFirstNum(kqDate[0]) < 10*60 and getFirstNum(kqDate[-1]) > 19.5*60):
					if(getFirstNum(kqDate[-1]) > 20*60): #大于晚上八点有一个餐补
						cbDay+=1;
				else:
					for i in range(0,len(rowsTable)):
						writeSheet.write(cRows,i,str(rowsTable[i]));
					writeSheet.write(cRows,i,'打卡异常');
					cRows+=1;
#最后一个人的数据存储
if(lastDay != '' and  (endDay - lastDay).days > 1):
	cRows = queQinFill(lastTable,(lastDay + datetime.timedelta(1)),endDay,cRows);
writeSheet.write(cRows,0,str(cUserName));
writeSheet.write(cRows,1,'出勤'+str(cqDay)+'天');
writeSheet.write(cRows,2,'餐补'+str(cbDay)+'天');
writeWorkBook.save('result.xls')

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

利用python从大文本文件中获取含有特定字符的行

实现的内容如标题,其实也有一些软件能够实现上述效果,若是利用mac或者是linux直接用vim也可以,这里针对以上都不符合,又不想费太大劲去找其他方法的方法

很简单,先从python官网下载一个python软件,直接安装就可以,这里一般选择最新的就可以了

然后照着下面的代码根据自己要求进行改造,不懂的欢迎交流:

with open('access.log', 'r', buffering=163840, encoding='utf8') as srcFile:
	with open('result.txt','w',encoding='utf8') as resultFile:
		srcText = srcFile.readline();
		while srcText:
			if('za.biz.etcp.cn' in srcText):
				resultFile.write(srcText);
			srcText = srcFile.readline();

除了摘取,有些时候打不开切成几个小文件也可以,代码如下:

# -*- coding:utf-8 -*-
indata = open("access.log",'r')
global index;
index = 0;
fileIndex = 0;
def outPutFile(fileIndex):
	global index;
	with open(str(fileIndex)+".txt", 'w', buffering=163840, encoding='utf8') as out:
	    line = indata.readline();
	    index = index + 1;
	    while line:
	    	index = index + 1;
	    	line = indata.readline();
	    	out.write(line);
	    	if(index % 100000 == 0):
	    		fileIndex = fileIndex + 1;
	    		outPutFile(fileIndex)
	    		break;
	    	index = index + 1;
	    	line = indata.readline();
outPutFile(fileIndex)

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

Chrome浏览器所有页面全部崩溃!

简单但不是长远之际的解决方法:–no-sandbox,在软件属性的目标后面添加这个可以以沙箱形式运行。具体来讲就是找到应用图标,右键选择属性,打开的属性中有一个目标,在目标的最后加上–no-sandbox。

长远考虑要找到具体原因,我是用这个解决的:原因是百度的C:\Windows\System32\drivers\bd0001.sys这个文件冲突,直接删掉就可以,删掉的时候可能删不掉,那就进入到安全模式来删除,或者用第三方软件。

相关文章连接:https://www.zhihu.com/question/29305453

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python给HTML文件内的js和css加文件的md5版本号

python版本3.5:

准备工作:需要先安装bs4!!!

直接上代码:

from bs4 import BeautifulSoup
from hashlib import md5
import os
 
#让使用者输入需要执行的目录
exeDir = input('请输入执行目录',)
#切换到执行目录
os.chdir(exeDir)
#合并后的js文件目录,并创建该目录
#需要合并的js序列
#合并文件函数

def fileMd5(fileName):
    m = md5();
    with open(fileName,'rb') as fileContent:
        m.update(fileContent.read());
    return m.hexdigest()[0:8];

#主文件
#盛放需要合并js的列表
for fileItem in os.listdir():
    if(os.path.isfile(fileItem)):
        if(os.path.splitext(fileItem)[1] == '.html'):
            originList = [];
            replaceList = [];
            #寻找需要替换的文件内容
            with open(fileItem, 'r+', buffering=163840, encoding='utf8') as srcHtml:
                line = srcHtml.readline();
                while line:
                    bItem = BeautifulSoup(line,'html.parser');
                    try:
                        #判断外链的script标签
                        if(bItem.script != None and bItem.script['src'].find('//') == -1):
                            fileSrc = bItem.script['src'];
                            filePathName = fileSrc.split('?')[0];
                            fileMd5Value = fileMd5(filePathName);
                            originList.append(fileSrc);
                            replaceList.append(filePathName+'?v='+fileMd5Value)
                        #判断外链的link标签
                        if(bItem.link != None and bItem.link['href'].find('//') == -1):
                            fileSrc = bItem.link['href'];
                            filePathName = fileSrc.split('?')[0];
                            fileMd5Value = fileMd5(filePathName);
                            originList.append(fileSrc);
                            replaceList.append(filePathName+'?v='+fileMd5Value)
                    except KeyError:
                        pass
                    line = srcHtml.readline();
                #加入版本号后替换
                if len(originList) == len(replaceList):
                    srcHtml.seek(0, 0)
                    fileContent = srcHtml.read();
                    for index in range(len(originList)):
                        fileContent = fileContent.replace(originList[index],replaceList[index]);
                    srcHtml.seek(0, 0)
                    srcHtml.write(fileContent);

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

搭建私人的git仓库

试用场景:小团队或者个人,私密的内容,不适合放到github上面;

此处默认为centos操作系统!

第一步:安装git

$ sudo yum install git

第二步,创建一个git用户,用来运行git服务: $ sudo adduser git

第三步,创建证书登录: 收集所有需要登录的用户的公钥,就是他们自己的id_rsa.pub文件,把所有公钥导入到/home/git/.ssh/authorized_keys文件里,一行一个。 对于需要登录的用户采用ssh-keygen -t rsa -C “youremail@example.com”命令创建(windows需要打开git bash),创建的时候会提示你密钥生成的位置,以及让你生成对应的密码——一般来说,公钥会生成在.ssh路径下;

第四步,初始化仓库: 先选定一个目录作为Git仓库,假定是/srv/sample.git,在/srv目录下输入命令:

$ sudo git init --bare sample.git

执行完上面的命令,Git就会创建一个裸仓库,裸仓库没有工作区,因为服务器上的Git仓库纯粹是为了共享,所以不让用户直接登录到服务器上去改工作区,并且服务器上的Git仓库通常都以.git结尾。然后,把owner改为git:

$ sudo chown -R git:git sample.git

至此,一个私有的git仓库就创建好了,可以采用如下命令拉取内容了:

git clone git@server:/srv/sample.git

但若是我并不是创建新项目,而是想要把老项目放到git上面,~~~那么首先,你上面初始化仓库应该在你原有项目目录初始化,然后添加项目文件:

$ git add .

随后,将添加的文件提交到仓库(需要按照要求配置账户,同时也需要把帐号的公钥和上面一样放在/home/git/.ssh/authorized_keys):

$ git commit -m "Initial commit"

再然后将本地仓库关联到远端仓库:

git remote add origin git@server:/srv/sample.git

然后可以查看一下关联结果:

$ git remote -v

发现成功了,就可以把代码提交到仓库了:

$ git push origin master

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

iscroll在安卓高版本(6.0以上)某些机型上滑动卡顿处理

具体现象:在某些安卓机上利用iscroll滑动的列表卡的要死,这些手机的特性一般都是安卓版本比较高!除了在安卓高版本上,chrome模拟器上也没有办法滚动!

这个问题产生的原因,不太确定啊,估摸着简单说一下,是由于chrome的55版本新增了一些属性,具体新增属性可见连接https://developers.google.com/web/updates/2016/11/nic55

就是由于这个新增的pointermove属性导致了采用chrome做webview默认内核的机子出问题了,用了iscorll就卡顿的要死了,解决方法:

简单来说直接用fixed版本的iscroll就可以了,连接见,还标注了修改点:https://github.com/claydotio/iscroll/commit/be4973786cc0ae4402d1b4b74507528d474da681

若是打不开上面连接,或者不想了解改了什么地方,可以试下这个连接,这个是纯js文件:https://raw.githubusercontent.com/claydotio/iscroll/be4973786cc0ae4402d1b4b74507528d474da681/build/iscroll.js

问题解决来源:https://github.com/cubiq/iscroll/issues/1109

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

如何静默的利用schema尝试打开app,不存在的时候不会出现404(尤其是安卓)

废话不多说,直接上代码!

 

var isiOS = navigator.userAgent.match('iPad') || navigator.userAgent.match('iPhone') || navigator.userAgent.match('iPod');
var isAndroid = navigator.userAgent.match('Android');
//判断安卓还是IOS,其实主要就是利用iframe处理页面尝试打开的app时,app不存在报404的错误!
if(isiOS){
	location.href = 'xxxx://xxxxx'; //自己定义的schema值
}else{
	$('body').append('<iframe class="iframe-dom" src="etcp://splash"></iframe>');
}

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

MySQL性能调优my.cnf详解

原文地址:https://blog.linuxeye.com/379.html

提供一个MySQL 5.6版本适合在1GB内存VPS上的my.cnf配置文件

  • [client]
  • port = 3306
  • socket = /tmp/mysql.sock
  • [mysqld]
  • port = 3306
  • socket = /tmp/mysql.sock
  • basedir = /usr/local/mysql
  • datadir = /data/mysql
  • pid-file = /data/mysql/mysql.pid
  • user = mysql
  • bind-address = 0.0.0.0
  • server-id = 1 #表示是本机的序号为1,一般来讲就是master的意思
  • skip-name-resolve
  • # 禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,
  • # 则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求
  • #skip-networking
  • back_log = 600
  • # MySQL能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,
  • # 然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。
  • # 如果期望在一个短时间内有很多连接,你需要增加它。也就是说,如果MySQL的连接数据达到max_connections时,新来的请求将会被存在堆栈中,
  • # 以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。
  • # 另外,这值(back_log)限于您的操作系统对到来的TCP/IP连接的侦听队列的大小。
  • # 你的操作系统在这个队列大小上有它自己的限制(可以检查你的OS文档找出这个变量的最大值),试图设定back_log高于你的操作系统的限制将是无效的。
  • max_connections = 1000
  • # MySQL的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySQL会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。可以过’conn%’通配符查看当前状态的连接数量,以定夺该值的大小。
  • max_connect_errors = 6000
  • # 对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST。
  • open_files_limit = 65535
  • # MySQL打开的文件描述符限制,默认最小1024;当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个,
  • # 当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个。
  • table_open_cache = 128
  • # MySQL每打开一个表,都会读入一些数据到table_open_cache缓存中,当MySQL在这个缓存中找不到相应信息时,才会去磁盘上读取。默认值64
  • # 假定系统有200个并发连接,则需将此参数设置为200*N(N为每个连接所需的文件描述符数目);
  • # 当把table_open_cache设置为很大时,如果系统处理不了那么多文件描述符,那么就会出现客户端失效,连接不上
  • max_allowed_packet = 4M
  • # 接受的数据包大小;增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或MySQLd必须返回大的结果行时MySQLd才会分配更多内存。
  • # 该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。
  • binlog_cache_size = 1M
  • # 一个事务,在没有提交的时候,产生的日志,记录到Cache中;等到事务提交需要提交的时候,则把日志持久化到磁盘。默认binlog_cache_size大小32K
  • max_heap_table_size = 8M
  • # 定义了用户可以创建的内存表(memory table)的大小。这个值用来计算内存表的最大行数值。这个变量支持动态改变
  • tmp_table_size = 16M
  • # MySQL的heap(堆积)表缓冲大小。所有联合在一个DML指令内完成,并且大多数联合甚至可以不用临时表即可以完成。
  • # 大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。
  • # 如果某个内部heap(堆积)表大小超过tmp_table_size,MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说,如果调高该值,MySQL同时将增加heap表的大小,可达到提高联接查询速度的效果
  • read_buffer_size = 2M
  • # MySQL读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySQL会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。
  • # 如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能
  • read_rnd_buffer_size = 8M
  • # MySQL的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,
  • # MySQL会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySQL会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大
  • sort_buffer_size = 8M
  • # MySQL执行排序使用的缓冲大小。如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。
  • # 如果不能,可以尝试增加sort_buffer_size变量的大小
  • join_buffer_size = 8M
  • # 联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享
  • thread_cache_size = 8
  • # 这个值(默认8)表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,
  • # 如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,
  • # 增加这个值可以改善系统性能.通过比较Connections和Threads_created状态的变量,可以看到这个变量的作用。(–>表示要调整的值)
  • # 根据物理内存设置规则如下:
  • # 1G  —> 8
  • # 2G  —> 16
  • # 3G  —> 32
  • # 大于3G  —> 64
  • query_cache_size = 8M
  • #MySQL的查询缓冲大小(从4.0.1开始,MySQL提供了查询缓冲机制)使用查询缓冲,MySQL将SELECT语句和查询结果存放在缓冲区中,
  • # 今后对于同样的SELECT语句(区分大小写),将直接从缓冲区中读取结果。根据MySQL用户手册,使用查询缓冲最多可以达到238%的效率。
  • # 通过检查状态值’Qcache_%’,可以知道query_cache_size设置是否合理:如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况,
  • # 如果Qcache_hits的值也非常大,则表明查询缓冲使用非常频繁,此时需要增加缓冲大小;如果Qcache_hits的值不大,则表明你的查询重复率很低,
  • # 这种情况下使用查询缓冲反而会影响效率,那么可以考虑不用查询缓冲。此外,在SELECT语句中加入SQL_NO_CACHE可以明确表示不使用查询缓冲
  • query_cache_limit = 2M
  • #指定单个查询能够使用的缓冲区大小,默认1M
  • key_buffer_size = 4M
  • #指定用于索引的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,
  • # 系统将开始换页并且真的变慢了。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态值Key_read_requests和Key_reads,
  • # 可以知道key_buffer_size设置是否合理。比例key_reads/key_read_requests应该尽可能的低,
  • # 至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE ‘key_read%’获得)。注意:该参数值设置的过大反而会是服务器整体效率降低
  • ft_min_word_len = 4
  • # 分词词汇最小长度,默认4
  • transaction_isolation = REPEATABLE-READ
  • # MySQL支持4种事务隔离级别,他们分别是:
  • # READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE.
  • # 如没有指定,MySQL默认采用的是REPEATABLE-READ,ORACLE默认的是READ-COMMITTED
  • log_bin = mysql-bin
  • binlog_format = mixed
  • expire_logs_days = 30 #超过30天的binlog删除
  • log_error = /data/mysql/mysql-error.log #错误日志路径
  • slow_query_log = 1
  • long_query_time = 1 #慢查询时间 超过1秒则为慢查询
  • slow_query_log_file = /data/mysql/mysql-slow.log
  • performance_schema = 0
  • explicit_defaults_for_timestamp
  • #lower_case_table_names = 1 #不区分大小写
  • skip-external-locking #MySQL选项以避免外部锁定。该选项默认开启
  • default-storage-engine = InnoDB #默认存储引擎
  • innodb_file_per_table = 1
  • # InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间
  • # 独立表空间优点:
  • # 1.每个表都有自已独立的表空间。
  • # 2.每个表的数据和索引都会存在自已的表空间中。
  • # 3.可以实现单表在不同的数据库中移动。
  • # 4.空间可以回收(除drop table操作处,表空不能自已回收)
  • # 缺点:
  • # 单表增加过大,如超过100G
  • # 结论:
  • # 共享表空间在Insert操作上少有优势。其它都没独立表空间表现好。当启用独立表空间时,请合理调整:innodb_open_files
  • innodb_open_files = 500
  • # 限制Innodb能打开的表的数据,如果库里的表特别多的情况,请增加这个。这个值默认是300
  • innodb_buffer_pool_size = 64M
  • # InnoDB使用一个缓冲池来保存索引和原始数据, 不像MyISAM.
  • # 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.
  • # 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%
  • # 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.
  • # 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,
  • # 所以不要设置的太高.
  • innodb_write_io_threads = 4
  • innodb_read_io_threads = 4
  • # innodb使用后台线程处理数据页上的读写 I/O(输入输出)请求,根据你的 CPU 核数来更改,默认是4
  • # 注:这两个参数不支持动态改变,需要把该参数加入到my.cnf里,修改完后重启MySQL服务,允许值的范围从 1-64
  • innodb_thread_concurrency = 0
  • # 默认设置为 0,表示不限制并发数,这里推荐设置为0,更好去发挥CPU多核处理能力,提高并发量
  • innodb_purge_threads = 1
  • # InnoDB中的清除操作是一类定期回收无用数据的操作。在之前的几个版本中,清除操作是主线程的一部分,这意味着运行时它可能会堵塞其它的数据库操作。
  • # 从MySQL5.5.X版本开始,该操作运行于独立的线程中,并支持更多的并发数。用户可通过设置innodb_purge_threads配置参数来选择清除操作是否使用单
  • # 独线程,默认情况下参数设置为0(不使用单独线程),设置为 1 时表示使用单独的清除线程。建议为1
  • innodb_flush_log_at_trx_commit = 2
  • # 0:如果innodb_flush_log_at_trx_commit的值为0,log buffer每秒就会被刷写日志文件到磁盘,提交事务的时候不做任何操作(执行是由mysql的master thread线程来执行的。
  • # 主线程中每秒会将重做日志缓冲写入磁盘的重做日志文件(REDO LOG)中。不论事务是否已经提交)默认的日志文件是ib_logfile0,ib_logfile1
  • # 1:当设为默认值1的时候,每次提交事务的时候,都会将log buffer刷写到日志。
  • # 2:如果设为2,每次提交事务都会写日志,但并不会执行刷的操作。每秒定时会刷到日志文件。要注意的是,并不能保证100%每秒一定都会刷到磁盘,这要取决于进程的调度。
  • # 每次事务提交的时候将数据写入事务日志,而这里的写入仅是调用了文件系统的写入操作,而文件系统是有 缓存的,所以这个写入并不能保证数据已经写入到物理磁盘
  • # 默认值1是为了保证完整的ACID。当然,你可以将这个配置项设为1以外的值来换取更高的性能,但是在系统崩溃的时候,你将会丢失1秒的数据。
  • # 设为0的话,mysqld进程崩溃的时候,就会丢失最后1秒的事务。设为2,只有在操作系统崩溃或者断电的时候才会丢失最后1秒的数据。InnoDB在做恢复的时候会忽略这个值。
  • # 总结
  • # 设为1当然是最安全的,但性能页是最差的(相对其他两个参数而言,但不是不能接受)。如果对数据一致性和完整性要求不高,完全可以设为2,如果只最求性能,例如高并发写的日志服务器,设为0来获得更高性能
  • innodb_log_buffer_size = 2M
  • # 此参数确定些日志文件所用的内存大小,以M为单位。缓冲区更大能提高性能,但意外的故障将会丢失数据。MySQL开发人员建议设置为1-8M之间
  • innodb_log_file_size = 32M
  • # 此参数确定数据日志文件的大小,更大的设置可以提高性能,但也会增加恢复故障数据库所需的时间
  • innodb_log_files_in_group = 3
  • # 为提高性能,MySQL可以以循环方式将日志文件写到多个文件。推荐设置为3
  • innodb_max_dirty_pages_pct = 90
  • # innodb主线程刷新缓存池中的数据,使脏数据比例小于90%
  • innodb_lock_wait_timeout = 120
  • # InnoDB事务在被回滚之前可以等待一个锁定的超时秒数。InnoDB在它自己的锁定表中自动检测事务死锁并且回滚事务。InnoDB用LOCK TABLES语句注意到锁定设置。默认值是50秒
  • bulk_insert_buffer_size = 8M
  • # 批量插入缓存大小, 这个参数是针对MyISAM存储引擎来说的。适用于在一次性插入100-1000+条记录时, 提高效率。默认值是8M。可以针对数据量的大小,翻倍增加。
  • myisam_sort_buffer_size = 8M
  • # MyISAM设置恢复表之时使用的缓冲区的尺寸,当在REPAIR TABLE或用CREATE INDEX创建索引或ALTER TABLE过程中排序 MyISAM索引分配的缓冲区
  • myisam_max_sort_file_size = 10G
  • # 如果临时文件会变得超过索引,不要使用快速排序索引方法来创建一个索引。注释:这个参数以字节的形式给出
  • myisam_repair_threads = 1
  • # 如果该值大于1,在Repair by sorting过程中并行创建MyISAM表索引(每个索引在自己的线程内)
  • interactive_timeout = 28800
  • # 服务器关闭交互式连接前等待活动的秒数。交互式客户端定义为在mysql_real_connect()中使用CLIENT_INTERACTIVE选项的客户端。默认值:28800秒(8小时)
  • wait_timeout = 28800
  • # 服务器关闭非交互连接之前等待活动的秒数。在线程启动时,根据全局wait_timeout值或全局interactive_timeout值初始化会话wait_timeout值,
  • # 取决于客户端类型(由mysql_real_connect()的连接选项CLIENT_INTERACTIVE定义)。参数默认值:28800秒(8小时)
  • # MySQL服务器所支持的最大连接数是有上限的,因为每个连接的建立都会消耗内存,因此我们希望客户端在连接到MySQL Server处理完相应的操作后,
  • # 应该断开连接并释放占用的内存。如果你的MySQL Server有大量的闲置连接,他们不仅会白白消耗内存,而且如果连接一直在累加而不断开,
  • # 最终肯定会达到MySQL Server的连接上限数,这会报’too many connections’的错误。对于wait_timeout的值设定,应该根据系统的运行情况来判断。
  • # 在系统运行一段时间后,可以通过show processlist命令查看当前系统的连接状态,如果发现有大量的sleep状态的连接进程,则说明该参数设置的过大,
  • # 可以进行适当的调整小些。要同时设置interactive_timeout和wait_timeout才会生效。
  • [mysqldump]
  • quick
  • max_allowed_packet = 16M #服务器发送和接受的最大包长度
  • [myisamchk]
  • key_buffer_size = 8M
  • sort_buffer_size = 8M
  • read_buffer = 4M
  • write_buffer = 4M

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

javascript发现获取url后面参数用unescape处理后产生了乱码

javascript发现获取url后面参数用unescape处理后产生了乱码,原因很明显是遇到了中文,若是直接处理的话其实很简单,直接采用如下代码便可以了

unescape(decodeURI(location.search))

可若是我拿到的已经是乱码了,无法从原始数据中来获取了,那也不着急,先转回去再来,多套一层而已

unescape(decodeURI(escape('luan ma')))
//原谅我用的中文

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

javascript处理时间格式转换成XX时XX分XX秒的格式

老板要求把时间统一成XX时XX分XX秒,而由于一些原因,我从后台拿到的是后台拼接后的,后台拼接的时候,遇到2分1秒的时候,并未处理成02分01秒,这就造成了我这边难处理了,于是写了下面的代码……

function handleTime(time){
	time = time.replace(/([^\d])(\d)(?=[时分秒])/g,'$10$2')
	if(time.indexOf('时') == 1 ){
		time = '0' + time;
	}else if(time.indexOf('分') == 1){
		time = '0' + time;
	}else if(time.indexOf('秒') == 1){
		time = '0' + time;
	}
	return time;
}

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python3.x利用qrcode和Pillow(python2.x的PIL的派生版本)批量生成二维码

首先利用pip安装qrcode和Pillow
安装qrcode

pip install qrcode

安装Pillow

pip install Pillow

备注:第一次安装这两个pip包的时候,我这边出现了拉取不下来的情况,最后利用vpn翻墙后便装上了,有人说包的源在国外,所以会被墙,若是出现我的情况,试一下翻墙是否管用吧!

随后直接上源码吧

import qrcode
from PIL import Image
num = 1;
MaxNum = 30;
while 1:
	q=qrcode.main.QRCode()
	q.add_data('http://www.baidu.com?source='+str(num))
	m=q.make_image()
	m.save(str(num)+'.png')
	num += 1;
	if(num > MaxNum):
		break

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

mysql如何让一个存储过程定时执行

原文地址:http://www.myexception.cn/mysql/827875.html

mysql怎么让一个存储过程定时执行
查看event是否开启: show variables like ‘%sche%’;
将事件计划开启: set global event_scheduler=1;
关闭事件任务: alter event e_test ON COMPLETION PRESERVE DISABLE;
开户事件任务: alter event e_test ON COMPLETION PRESERVE ENABLE;

简单实例.
创建表 CREATE TABLE test(endtime DATETIME);

创建存储过程test
CREATE PROCEDURE test ()
BEGIN
update examinfo SET endtime = now() WHERE id = 14;
END;

创建event e_test
CREATE EVENT if not exists e_test
on schedule every 30 second
on completion preserve
do call test();

每隔30秒将执行存储过程test,将当前时间更新到examinfo表中id=14的记录的endtime字段中去

1) 首先来看一个简单的例子来演示每秒插入一条记录到数据表

USE test;
CREATE TABLE aaa (timeline TIMESTAMP);
CREATE EVENT e_test_insert
ON SCHEDULE EVERY 1 SECOND
DO INSERT INTO test.aaa VALUES (CURRENT_TIMESTAMP);
等待3秒钟后,再执行查询看看:

mysql> SELECT * FROM aaa;
+———————+
| timeline            |
+———————+
| 2007-07-18 20:44:26 |
| 2007-07-18 20:44:27 |
| 2007-07-18 20:44:28 |
+———————+
2) 5天后清空test表:

CREATE EVENT e_test
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY
DO TRUNCATE TABLE test.aaa;
3) 2007年7月20日12点整清空test表:

CREATE EVENT e_test
ON SCHEDULE AT TIMESTAMP ‘2007-07-20 12:00:00’
DO TRUNCATE TABLE test.aaa;
4) 每天定时清空test表:

CREATE EVENT e_test
ON SCHEDULE EVERY 1 DAY
DO TRUNCATE TABLE test.aaa;
5) 5天后开启每天定时清空test表:

CREATE EVENT e_test
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_TIMESTAMP + INTERVAL 5 DAY
DO TRUNCATE TABLE test.aaa;
6) 每天定时清空test表,5天后停止执行:

CREATE EVENT e_test
ON SCHEDULE EVERY 1 DAY
ENDS CURRENT_TIMESTAMP + INTERVAL 5 DAY
DO TRUNCATE TABLE test.aaa;
7) 5天后开启每天定时清空test表,一个月后停止执行:

CREATE EVENT e_test
ON SCHEDULE EVERY 1 DAY
STARTS CURRENT_TIMESTAMP + INTERVAL 5 DAY
ENDS CURRENT_TIMESTAMP + INTERVAL 1 MONTH
DO TRUNCATE TABLE test.aaa;
[ON COMPLETION [NOT] PRESERVE]可以设置这个事件是执行一次还是持久执行,默认为NOT PRESERVE。
8) 每天定时清空test表(只执行一次,任务完成后就终止该事件):

CREATE EVENT e_test
ON SCHEDULE EVERY 1 DAY
ON COMPLETION NOT PRESERVE
DO TRUNCATE TABLE test.aaa;
[ENABLE | DISABLE]可是设置该事件创建后状态是否开启或关闭,默认为ENABLE。
[COMMENT ‘comment’]可以给该事件加上注释。

三、修改事件(ALTER EVENT)
ALTER EVENT event_name
[ON SCHEDULE schedule]
[RENAME TO new_event_name]
[ON COMPLETION [NOT] PRESERVE]
[COMMENT ‘comment’]
[ENABLE | DISABLE]
[DO sql_statement]
1) 临时关闭事件

ALTER EVENT e_test DISABLE;
2) 开启事件

ALTER EVENT e_test ENABLE;
3) 将每天清空test表改为5天清空一次:

ALTER EVENT e_test
ON SCHEDULE EVERY 5 DAY;
四、删除事件(DROP EVENT)
语 法很简单,如下所示:

DROP EVENT [IF EXISTS] event_name
例如删除前面创建的e_test事件

DROP EVENT e_test;
当然前提是这个事件存在,否则会产生ERROR 1513 (HY000): Unknown event错误,因此最好加上IF EXISTS

DROP EVENT IF EXISTS e_test;

create event test
ON SCHEDULE AT ‘2007-09-01 12:00:00’ + INTERVAL 1 DAY
on completion not preserve
do insert into yyy values(‘hhh’,’uuu’);

解释:从2007-09-01开始,每天对表yyy在12:00:00进行一个插入操作。而且只执行一次(on completion not preserve )

我的计划任务为:

create event sysplan
ON SCHEDULE AT ‘2010-05-22 23:00:00’ + INTERVAL 1 DAY
on completion not preserve
do truncate table bjproj.ae_tmp;

三、通过设定全局变量event_scheduler 的值即可动态的控制事件调度器是否启用。
查看是否event_scheduler开启mysql> SHOW VARIABLES LIKE ‘%event%’;
设置开启mysql> SET GLOBAL event_scheduler=ON;
四、例子:
每分钟插入一条日志:DELIMITER //CREATE EVENT `user_log_event` ON SCHEDULE EVERY 1 MINUTE STARTS ‘2010-12-27 00:00:00’ ON COMPLETION NOT PRESERVE ENABLE DO BEGIN INSERT INTO log SET addtime=NOW();END//
调用存储过程:DELIMITER //CREATE EVENT `user_log_event` ON SCHEDULE EVERY 1 DAY STARTS ‘2010-00-00 00:00:00’ ON COMPLETION NOT PRESERVE ENABLE DO BEGIN        CALL user_log_prov();END//

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

用python写的简单的前端js代码合并方法

用python写的简单的前端js代码合并方法,直接上源码:

from bs4 import BeautifulSoup
import os
import shutil

#让使用者输入需要执行的目录
exeDir = input('请输入执行目录',)
#切换到执行目录
os.chdir(exeDir)
#拼接需要输出的目录,这里不同系统需要更改一下
outDir = 'E:\\release' + os.sep + exeDir.split(os.sep)[-1]

#判断根目录是否存在,存在则清空
if(os.path.exists(outDir)):
	shutil.rmtree(outDir)
#判断根目录是否存在,存在则清空
os.mkdir(outDir)

#合并后的js文件目录,并创建该目录
mergeJsDir = 'mergeJs' + os.sep;
mergeJsBaseDir = outDir + os.sep + mergeJsDir;
os.mkdir(mergeJsBaseDir)
#需要合并的js序列
noMergeJs = ['comitem','comEnd'];
#合并文件函数
def mergeJs(fileList):
	fileListStr = '_'.join([os.path.splitext(os.path.split(i)[1])[0] for i in fileList]) + '.js';
	mergeJsFile = mergeJsBaseDir + fileListStr;
	with open(mergeJsFile, 'w', buffering=163840, encoding='utf8') as cJs:
		for fileName in filelist:
			with open(fileName, 'r', buffering=163840, encoding='utf8') as jsItem:
				cJs.write(jsItem.read()+'\n')
	return '<script src="'+ mergeJsDir + fileListStr+'"></script>';

#主文件
#盛放需要合并js的列表
for fileItem in os.listdir():
	if(os.path.isfile(fileItem)):
		if(os.path.splitext(fileItem)[1] == '.html'):
			filelist = [];
			with open(fileItem, 'r', buffering=163840, encoding='utf8') as srcHtml:
				with open(outDir+os.sep+fileItem, 'w', buffering=163840, encoding='utf8') as outHtml:
					line = srcHtml.readline();
					while line:
						bItem = BeautifulSoup(line,'html.parser');
						if(bItem.script == None or bItem.script['class'][0] not in noMergeJs):
							outHtml.write(line)
						else:
							filelist.append(bItem.script['src'])
							if(bItem.script['class'][0] == 'comEnd'):
								outHtml.write(mergeJs(filelist)+'\n')
						line = srcHtml.readline();
		else:
			shutil.copyfile(fileItem,outDir+os.sep+fileItem)
	elif(fileItem != outDir):
		shutil.copytree(fileItem,outDir+os.sep+fileItem)

原始的html文件:

<!DOCTYPE html>
<html>
<head>
	<title>合并js文件测试</title>
	<style type="text/css">
		h2{
			text-align: center;
			margin-top: 20px;
		}
	</style>
</head>
<body>
<h2>合并js文件测试</h2>
<p>可以看到,comitem是需要合并的文件,comEnd是标志合并的结束,此文件会进入合并文件,class未赋值的不会进行合并,强调,目前的方案必须写上class</p>
<script src="js\a.js" class="comitem"></script>
<script src="js\b.js" class="comitem"></script>
<script src="js\c.js" class="comitem"></script>
<script src="js\d.js" class="comEnd"></script>
<script src="js\e.js" class=""></script>
<script src="js\f.js" class=""></script>
</body>
</html>

合并后的HTML文件:

<!DOCTYPE html>
<html>
<head>
	<title>合并js文件测试</title>
	<style type="text/css">
		h2{
			text-align: center;
			margin-top: 20px;
		}
	</style>
</head>
<body>
<h2>合并js文件测试</h2>
<p>可以看到,comitem是需要合并的文件,comEnd是标志合并的结束,此文件会进入合并文件,class未赋值的不会进行合并,强调,目前的方案必须写上class</p>
<script src="mergeJs\a_b_c_d.js"></script>
<script src="js\e.js" class=""></script>
<script src="js\f.js" class=""></script>
</body>
</html>

备注:可以看到合并的js文件被放在了一个mergeJs的目录下,这个目录是新建的文件夹!

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python3.x利用淘宝的ip地址查询接口批量查询地理位置

直接上代码

#!/usr/bin/python
#coding:utf-8
 
import urllib.request
import json
 
url = 'http://ip.taobao.com/service/getIpInfo.php?ip='
srcFile = 'ip.txt';
outFile = 'result.txt';

def checkTaobaoIP(ip):
    try:
        re = urllib.request.urlopen(url + ip, timeout=1000).read().decode('utf-8')
        data = json.loads(re);
        return "%15s: %s-%s-%s-%s" % (ip,data['data']['country'],data['data']['isp'],data['data']['region'],data['data']['city'])
    except:
    	return "%15s: timeout" % ip
 
if __name__ == "__main__":
 	with open(srcFile, 'r', buffering=163840, encoding='utf8') as srcData:
 		with open(outFile,'w',buffering=163840, encoding='utf8') as outData:
	 		line = srcData.readline();
	 		while line:
	 			outData.write(checkTaobaoIP(line.strip())+'\n');
	 			line = srcData.readline();
	 		else:
	 			print("Done!");

ip.txt内的示例格式:

116.216.30.3
116.216.30.2
61.164.212.246
106.39.1.31
124.205.63.221
183.195.254.178
36.5.117.190
113.161.29.81
113.89.30.181

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

js判断版本号大小

js代码:

/**
 * 判断两个版本字符串的大小
 * @param  {string} v1 原始版本
 * @param  {string} v2 目标版本
 * @return {number}    如果原始版本大于目标版本,则返回大于0的数值, 如果原始小于目标版本则返回小于0的数值。0当然是两个版本都相等拉。
 */

function compareVersion(v1, v2) {
	var _v1 = v1.split("."),
		_v2 = v2.split("."),
		_r = _v1[0] - _v2[0];

	return _r == 0 && v1 != v2 ? compareVersion(_v1.splice(1).join("."), _v2.splice(1).join(".")) : _r;
}

console.log(compareVersion("1.2.33.6", "1.2.33.6.7")); //-7
console.log(compareVersion("1.0", "1.0.1")); //-1
console.log(compareVersion("1.0", "0.0.5")); //1

原文:https://gist.github.com/puterjam/8518259

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python倒着读取指定行数

代码(python版本3.x):

import linecache
srcFile = 'scrfile.txt';
#结果文件,最终是倒叙写入进来,将源文件的最后一行当作第一行来写入
outFile = 'result.txt';
#读取文件到变量fileContent中
fileContent = linecache.getlines(srcFile)
#计算源文件的行数
lineLength = len(fileContent);
#设置计算器count的值,和倒着读取文件的行数
count = 1;
maxCount = 10;
#输出文件的行数
print('line number:%d' % lineLength);
#以写的方式打开文件
with open(outFile, 'w', buffering=163840, encoding='utf8') as out:
	#循环判断的条件,若是maxCount大于文件行数,lineLength会在程序运行中被减成0,此时程序以应该终止
	while(lineLength > 0):
		#倒着将读取到的行内容写入输出文件(outFile)
		out.write(fileContent[lineLength - 1]);
		#读取文件行数的游标递减,行数计数器递增
		lineLength = lineLength - 1;
		count = count + 1;
		#若是到达了设定的读取行数,终止循环
		if(count > maxCount):
			break;

#清除读取文件的缓存
linecache.clearcache()

参考文章:http://wangwei007.blog.51cto.com/68019/1246214

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

python 在不用第三方软件打开文件的前提下判断文件编码

linux下文件编码可以有比较方便的方法确认,在window下仿佛都需要打开文件,但有些文件太大,于是想到用python来处理下,就找到了python的一个库chardet,准确率还是比较高的,安装完chardet库,代码如下:

import chardet
f = open('test.txt','rb')
data = f.readline();
print(chardet.detect(data))

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址

yum groupinstall “Development Tools” 批量安装软件 linux

转自:http://yuhaitao.blog.51cto.com/3930555/1277382

注:可以通过 yum grouplist 来查看可能批量安装哪些列表

从Windows转到Linux下面,一个不习惯的地方就是在图形界面下安装和删除软件的时候非常缓慢。但是如果你掌握了用yum的命令行模式进行 配置程序,你肯定会从心底喜欢上这个强大的工具。因为yum提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁而又好记。

yum的命令形式一般是如下:yum [options] [command] [package …]
其中的[options]是可选的,选项包括-h(帮助),-y(当安装过程提示选择全部为”yes”),-q(不显示安装的过程)等等。[command]为所要进行的操作,[package …]是操作的对象。

概括了部分常用的命令包括:

自动搜索最快镜像插件:yum install yum-fastestmirror
安装yum图形窗口插件:yum install yumex

1 安装
yum install 全部安装
yum install package1 安装指定的安装包package1
yum groupinsall group1 安装程序组group1
2 更新和升级

yum update 全部更新
yum update package1 更新指定程序包package1
yum check-update 检查可更新的程序
yum upgrade package1 升级指定程序包package1
yum groupupdate group1 升级程序组group1
3 查找和显示
yum info package1 显示安装包信息package1
yum list 显示所有已经安装和可以安装的程序包
yum list package1 显示指定程序包安装情况package1
yum groupinfo group1 显示程序组group1信息yum search string 根据关键字string查找安装包
4 删除程序
yum remove &#124; erase package1 删除程序包package1
yum groupremove group1 删除程序组group1
yum deplist package1 查看程序package1依赖情况
5 清除缓存
yum clean packages 清除缓存目录下的软件包
yum clean headers 清除缓存目录下的 headers
yum clean oldheaders 清除缓存目录下旧的 headers
yum clean, yum clean all (= yum clean packages; yum clean oldheaders) 清除缓存目录下的软件包及旧的headers

比如,要安装游戏程序组,首先进行查找:
#:yum grouplist
可以发现,可安装的游戏程序包名字是”Games and Entertainment“,这样就可以进行安装:
#:yum groupinstall “Games and Entertainment”
所 有的游戏程序包就自动安装了。在这里Games and Entertainment的名字必须用双引号选定,因为linux下面遇到空格会认为文件名结束了,因此必须告诉系统安装的程序包的名字是“Games and Entertainment”而不是“Games”。

此外,还可以修改配置文件/etc/yum.conf选择安装源。可见yum进行配置程序有多方便了吧。更多详细的选项和命令,当然只要在命令提示行下面:man yum

yum groupinstall “KDE (K Desktop Environment)”

yum install pirut k3b mikmod

yum groupinstall “Server Configuration Tools”

yum groupinstall “Sound and Video”

#yum groupinstall “GNOME Desktop Environment”

yum groupinstall “Legacy Software Support”

yum groupinstall “Development Libraries”

yum groupinstall “Development Tools”

#yum groupinstall “Windows File Server”

yum groupinstall “System Tools”

yum groupinstall “X Window System”

yum install php-gd
yum install gd-devel
yum groupinstall “Chinese Support”
#yum install samba-common  (此一動作會一起安裝samba-client)
#yum install samba

yum install gcc
yum install cpp
yum install gcc-c++
yum install ncurses
yum install ncurses-devel
yum install gd-devel php-gd
yum install gd-devel
yum install gcc
yum install cpp
yum install gcc-c++
yum install ncurses
yum install ncurses-devel
yum install gd-devel php-gd
yum install gd-devel
yum install zlib-devel
yum install freetype-devel freetype-demos freetype-utils
yum install libpng-devel libpng10 libpng10-devel
yum install libjpeg-devel
yum install ImageMagick
yum install php-gd
yum install flex
yum install ImageMagick-devel
#yum install system-config-bind
#yum groupinstall “DNS Name Server”      //安裝 bind 及 bind-chroot 套件
yum groupinstall “MySQL Database”‘

yum clean all

感谢看完指鹤文章,希望指鹤的文章对您有所帮助。

闲暇时,指鹤喜欢写一些文章,部分发表在了豆瓣网与17K中文网,若是您对此感兴趣,您可以点击下面连接支持下指鹤,指鹤在此表示感谢了

绝命笔记 一封匿名信引发的追寻 迷案追凶 量子危机 玄冥石 神魔序曲 杂集地址