redis是个很有趣的k-v数据库,它很好的照顾到了轻量级和速度两方面,今天试了一下redis的python客户端,看起来好像比mysql更简单的样子,因垂丝汀。
首先安装redis,可以从官网上下载后make,因为我的ubuntu源自带redis,所以直接apt install redis-server就好了,然后

vim /etc/redis/redis.conf

requirepass设置成你的密码,listenaddress改成0.0.0.0以便于我在宿舍访问我实验室的服务器。
这里要提醒一下,redis默认开启了安全模式,如果没有密码是只能接受来自loop这个interface的连接的,所以还是推荐设置一下密码。
然后安装python下的redis客户端,根据官方的指引,推荐我们安装redis-py客户端,于是

pip install redis

刷刷刷装完,然后试一下

import redis
r = redis.StrictRedis(host=’IP_ADDR’, port=6379, db=0, password=’MY_PASSWORD’)
r.set(‘foo’, ‘bar’)

True

r.get(‘foo’)

‘bar’
成功,这表明我们的redis服务器和客户端已经正常通讯了,然后我们开始写flask==
find.html

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8”>
<title>FIND</title>
</head>
<body>
<a href=”/“>插入数据</a><br>
<form action=”show”, method=”post”>
Key:<br>
<input type=”text” name=”key”><br>
<input type=”submit” value=”Submit”><br>
</form>
{% block result %} {% endblock %}
</body>
</html>

index.html

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8”>
<title>TEST WEBSITE</title>
</head>
<body>
<a href=”find”>查询数据</a>
<form action=”submit” method=”POST”>
Key:<br>
<input type=”text” name=”key”><br>
Value:<br>
<input type=”text” name=”value”><br>
<input type=”submit” value=”Submit”>
</form>
{{ status }}
</body>
</html>

show.html



{% extends "find.html" %}
{% block result %} result is:<br> {{ value_from_query }}<br> {% endblock %}
{% raw %}

main_website_controler.py

#coding=utf-8
from flask import Flask
from flask import render_template
from flask import request
import redis

conn_pool=redis.ConnectionPool(host=’10.19.14.242’, port=6379, db=0, password=’MY_PASSWORD’)
app = Flask(name)

@app.route(‘/‘)
def hello_world():
return render_template(‘index.html’)

@app.route(‘/find’)
def find():
return render_template(‘find.html’)

@app.route(‘/submit’, methods=[‘POST’])
def insert_data():
a=dict(request.form)
r = redis.Redis(connection_pool=conn_pool)
status=’Success!’
try:
r.set(a.get(‘key’)[0], a.get(‘value’)[0])
except Exception as err:
status=str(err)

return render_template('index.html', status=status)

@app.route(‘/show’, methods=[‘POST’])
def show(value=None):
a = dict(request.form)
r = redis.Redis(connection_pool=conn_pool)
value=r.get(a.get(‘key’)[0])
return render_template(‘show.html’, value_from_query=value)

if name == ‘main‘:
app.run()

运行一下

成功
今天的试用到此结束==

今天很羞愧,写了一坨屎一样的脚本,能跑起来的拉粪车,真TM的臭,挂出来,什么时候又要写狗屎代码了就翻出来看一看,有奇效

# coding=utf-8
from win32com.client import Dispatch
from docx import Document
from selenium import webdriver
from selenium.webdriver.common import keys
# from selenium.webdriver.common.action_chains import ActionChains
import time
import os

connection=webdriver.Chrome()
connection.get("http://***.***.***.***/index.php?title="+u"首页")
connection.find_element_by_xpath('//*[@id="pt-login"]/a').click()
time.sleep(2)
username=connection.find_element_by_xpath('//*[@id="wpName1"]')
username.click()
username.send_keys("************")
password=connection.find_element_by_xpath('//*[@id="wpPassword1"]')
password.click()
password.send_keys("************")
connection.find_element_by_xpath('//*[@id="wpLoginAttempt"]').click()
connection.find_element_by_xpath('//*[@id="ca-ve-edit"]').click()
time.sleep(50)
# connection.get("http://***.***.***.***/index.php?title=" + 'test'+ "&amp;veaction=edit")
# time.sleep(20)

def readAndUpload(rootDir):
    list_dirs = os.walk(rootDir)
    for root, dirs, files in list_dirs:
        for f in files:
            if 'doc' in os.path.join(root,f):
                try:
                    document = Document(str(os.path.join(root, f)))
                    tables = document.tables
                    title = tables[0].rows[0].cells[2].text
                    print(title)
                except Exception as e:
                    print(e)
                connection.get("http://***.***.***.***/index.php?title=" + title + "&amp;veaction=edit")
                try:
                    word = win32com.client.Dispatch("Word.Application")
                    word.Application.Run("selectAndCopy", os.path.join(root, f))
                except Exception as e:
                    print('word处理出错!')

                time.sleep(5)
                time.sleep(20)
                #
                # try:
                #     textBox = connection.find_element_by_xpath('//*[@id="bodyContent"]/div[5]/div[1]')
                # except Exception:
                #     print('获取输入框爆炸')
                # textBox.click()
                # textBox=connection.find_element_by_xpath('//*[@id="searchInput"]')

                try:
                    connection.find_element_by_xpath(
                        '//*[@id="content"]/div/div[1]/div/div[1]/div[1]/div/div[1]/div[1]/div/span[2]/div/div[1]/div[1]/div/a/span[1]').click()
                except Exception:
                    print('关闭弹框爆炸')
                shell = win32com.client.Dispatch("WScript.Shell")
                shell.AppActivate("Chrome")
                shell.SendKeys("^v", 0)
                time.sleep(2)
                connection.find_element_by_xpath('//*[@id="content"]/div/div[1]/div/div[1]/div[2]/a').click()
                time.sleep(2)
                connection.find_element_by_xpath('cml/body/div[7]/div/div/div[1]/div[2]/div[2]/div/div[1]/div[2]/textarea').send_keys('ROBOT EDITED')
                connection.find_element_by_xpath('cml/body/div[7]/div/div/div[1]/div[2]/div[1]/div/div[1]/div/a').click()
                time.sleep(3)
                shell = win32com.client.Dispatch("WScript.Shell")
                shell.AppActivate("Chrome")
                shell.SendKeys("~", 0)
                time.sleep(5)
                # connection.find_element_by_xpath('cml/body/div[7]/div/div/div[1]/div[2]/div[1]/div/div[1]/div/a').click()
                # time.sleep(1)
                # except Exception as e:
                #     print(os.path.join(root,f)+u"不能被处理,文档错误")
                #     print(e)

readAndUpload(unicode("C:\Users\********\Desktop\upload",'utf-8'))

至于为什么有那么多time.sleep,而且都这么久,原因很简单,公司的网1Mbps,打开这个网页一分钟,,调试一次5分钟起步,心态爆炸

最近发现,戴尔的iDrac卡非常好用

iDrac是作为独立于服务器的主机部分存在的,即使是在主机关机的情况下,它仍然会保持运行,并时刻监控服务器的状态,比如热备电源状态和服务器顶盖的开启记录、电源消耗状况、剩余电源容量、风扇阵列状态、主机内部及环境温度等等信息,在IDC上架之后,顶盖开启检测可以有效防止IDC和一些不明人员对机器做出什么不正当的举动,另外,服务器前面板的那个小屏幕也是由iDrac控制的,在小屏幕上可以即时显示当前主机的状态、设置主机iDrac网卡的IP地址、故障告警,上次阵列有一块盘坏了,就是这玩意儿背光灯变成橙色发现的。

戴尔从poweredgeR5x0以上级别服务器默认配备了iDrac卡和默认的普通版lic,5xx以下服务器需要单独购买iDrac卡,普通版lic只支持使用网卡1作为共享模式的iDrac端口,另外由企业版lic可以另外购买,价格随服务器不同也不同,我某宝买的R830的许可居然黑了我300多块钱,生气.jpg。

好处还是显而易见的,购买企业版lic以后支持了远程KVM显示,支持虚拟介质挂载,远程安装系统啥的都是轻轻松松,妈妈再也不用担心我的KVM服务器爆炸了 2333,iDrac可以与服务器操作系统的驱动程序联动进行服务器状态的评估和报警,已经支持的系统有一票linux、windows、ESXi等等;它还能远程升级系统固件,实际用户体验良好,不过戴尔官网那个驱动下载页面是真的乱,我翻了一下午才找齐各种固件和驱动;购买企业版以后还有一个好处就是那个默默无闻在服务器后面板左下角的iDrac专用端口解禁了,可以建设一个专门用来iDrac的内网,增强安全性。

人傻钱多戴还是美滋滋啊==

vultr全面降价,512M10GSSD只要2.5刀啦!妖兽啦!虽然线路比不上财大气粗的aliyun但是已经很好用了有没有!有!没!有!

最近一直在帮人写刷课脚本/爬虫用了很多自动化工具/JS工具/爬虫工具,今天把他们总结下来,方便以后使用

 

selenium
一个浏览器自动化工具,对Firefox和chrome浏览器都有很好的适配,同时可用phantomJS,可以操控浏览器进行模拟人类的操作,特点有:

1.元素查找相当方便,可以通过ID/className/布局查找,支持多种定位方式

2.支持原生的键盘事件只要import Keys一下,就可以直接sendkeys(),相当方便,有的时候可以直接sendkeys(Keys.ENTER),省去了很多元素查找的操作

3.通过一个bridge程序工作,这个bridge程序将监听某个端口,也就是说我们可以将他部署到服务器上,本地写好了脚本直接连接服务器上的phantomJS/浏览器进行操作,对于一些不可言说/404的网站,省了在本地开代理的麻烦(笑)

4.坏处是不能操控鼠标,在一些引用了鼠标位置检测的网页中,会触发验证

5.不支持或者我还没发现直接定位位置并点击的功能,对于一些flash之类的内容,不能通过元素的相对位置定位相当灾难

 

================================================================================================

待更新

1038642664080245020
这张图是ESP8266的引脚图,我们可以看到,这块标准的核心板是有8个脚被固定引出来的。ESP8266内部有一个STM8的核心,速度相当可观,还有高达2M的flash,这么强的片子,只要18块钱,真值

缺点当然是有的,那就是,发热太大,大的超乎想像,稍微一搞就过热了,需要给它加一点降温的东西来保证他的正常运行,另外,据某神说,这个片子特别吃电源,功耗巨大,而且对电压要求出奇的高,功耗不足就会自动重启,不过我一直用电脑USB转了3.3V供的电,好像并没有什么大问题。所以,应该不作死还是能撑得住的吧。

首先说的是这个芯片的一些技术资料 带有1个ADC,GPIO最多能引出来18个,3.3V供电,可以自己写闪存

接下来就是最关键的地方,也是它的主要卖点了,它的SDK固件内置了802.11协议栈,支持网络透传,GET/Post方法,AP/Station模式,使用ATcommand进行操控,很好用,而且这个小块块有很多第三方固件可以刷,还提供了完整的SDK,你可以自己制作属于你的固件,这样就大大方便了我这种生来喜欢折腾的人

下面说一下它自带的开发工具的使用感受

自带的开发工具自带了toolchain,很好用,从coding到编译打包固件的流程一气呵成,比某飞凌的那些开发版高到不知哪里去了,刷写该芯片需要用到官方的刷写工具,短接两脚上电,串口下载固件进去,我自己做了一个关于一个类似sensorHub的固件,将串口信息简单处理一下用HTTP/POST发送到服务器上,期间遇到了一个Bug,串口数据大量错误,后来发现是串口缓冲区的问题,修了一下,几乎无痛地就搞完了整个流程。

后来又发现它有一个神奇的固件叫NodeMCU,使用Lua脚本来进行单片机编程,将脚本上传到单片机里头,他会自动运行main这个脚本,同样内置了协议栈,编程更加简化,比起Arduino来不遑多让,项目地址在这里NodeMCU

以上就是ESP8266的使用感受

======================================================================
10/17更新
8266支持刷入特殊的固件以支持arduino 无敌了

今天,被人拉上了贼船= =
只能看看这是什么了,不过据说是窝工自己开发的某个牛X平台= =
SiPESC全称叫Software Integration Platform for Engineering and Scientific Computation中文名叫工程与科学集成化计算平台,我们看他给的安装包可以发现,这是一个mingw based的程序,根据之前群里人说,这个可以用Py写程序,可以用QT画界面,我们可以大胆猜测,这是一个从linux上进行了蜜汁移植过来的平台
给的安装包是一个MinGW的安装程序,但是被修改过了,还送了一个软件源的镜像,据说是在线的源挂掉了。。。。。
经过一波折腾终于装上了,有一个问题就是32位的minGW并不好用,手动选择64位的程序包才能正确安装,原因是源里好像大部分程序都没有32位的。。。。。
这。。真的迷,我过几天就要用它做一个计算软件了,先熟悉一下吧,总之,这个光安装就能BUG百出的平台,我莫名地慌张了起来,害怕。。
接下来要做的有:
1.QT程序的编写
2.教组里两个不会Py的孩纸学习Py程序的编写
3.学习结构力学。。。这个力学分析早就听说难得掉渣,会不会被虐炸,萌新在瑟瑟发抖

/**
  ******************************************************************************
  * @file    USART/DMA_Interrupt/main.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  */ 

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "platform_config.h"

/** @addtogroup STM32F10x_StdPeriph_Examples
  * @{
  */

/** @addtogroup USART_DMA_Interrupt
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;

/* Private define ------------------------------------------------------------*/
#define TxBufferSize1   (countof(TxBuffer1) - 1)
#define TxBufferSize2   (countof(TxBuffer2) - 1)

/* Private macro -------------------------------------------------------------*/
#define countof(a)   (sizeof(a) / sizeof(*(a)))

/* Private variables ---------------------------------------------------------*/
USART_InitTypeDef USART_InitStructure;
uint8_t TxBuffer1[] = "USART DMA Interrupt: USARTy -> USARTz using DMA Tx and Rx Flag";
uint8_t TxBuffer2[] = "USART DMA Interrupt: USARTz -> USARTy using DMA Tx and Rx Interrupt";
uint8_t RxBuffer1[TxBufferSize2];
uint8_t RxBuffer2[TxBufferSize1];
uint8_t NbrOfDataToRead = TxBufferSize1;
uint32_t index = 0;
volatile TestStatus TransferStatus1 = FAILED, TransferStatus2 = FAILED;

/* Private function prototypes -----------------------------------------------*/
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength);

/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     

  /* System Clocks Configuration */
  RCC_Configuration();

  /* NVIC configuration */
  NVIC_Configuration();

  /* Configure the GPIO ports */
  GPIO_Configuration();

  /* Configure the DMA */
  DMA_Configuration();

/* USARTy and USARTz configuration -------------------------------------------*/
  /* USARTy and USARTz configured as follow:
        - BaudRate = 230400 baud  
        - Word Length = 8 Bits
        - One Stop Bit
        - No parity
        - Hardware flow control disabled (RTS and CTS signals)
        - Receive and transmit enabled
  */

  USART_InitStructure.USART_BaudRate = 230400;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  /* Configure USARTy */
  USART_Init(USARTy, &USART_InitStructure);

  /* Configure USARTz */
  USART_Init(USARTz, &USART_InitStructure);

  /* Enable USARTy DMA TX request */
  USART_DMACmd(USARTy, USART_DMAReq_Tx, ENABLE);

  /* Enable USARTz DMA TX request */
  USART_DMACmd(USARTz, USART_DMAReq_Tx, ENABLE);

  /* Enable the USARTz Receive Interrupt */
  USART_ITConfig(USARTz, USART_IT_RXNE, ENABLE);

  /* Enable USARTy */
  USART_Cmd(USARTy, ENABLE);

  /* Enable USARTz */
  USART_Cmd(USARTz, ENABLE);

  /* Enable USARTy DMA TX Channel */
  DMA_Cmd(USARTy_Tx_DMA_Channel, ENABLE);

  /* Enable USARTz DMA TX Channel */
  DMA_Cmd(USARTz_Tx_DMA_Channel, ENABLE);

  /* Receive the TxBuffer2 */
  while(index < TxBufferSize2)
  {
     while(USART_GetFlagStatus(USARTy, USART_FLAG_RXNE) == RESET)
     {
     }
     RxBuffer1[index++] = USART_ReceiveData(USARTy);  
  }

  /* Wait until USARTy TX DMA1 Channel  Transfer Complete */
  while (DMA_GetFlagStatus(USARTy_Tx_DMA_FLAG) == RESET)
  {
  }
  /* Wait until USARTz TX DMA1 Channel Transfer Complete */
  while (DMA_GetFlagStatus(USARTz_Tx_DMA_FLAG) == RESET)
  {
  }

  /* Check the received data with the send ones */
  TransferStatus1 = Buffercmp(TxBuffer2, RxBuffer1, TxBufferSize2);
  /* TransferStatus1 = PASSED, if the data transmitted from USARTz and  
     received by USARTy are the same */
  /* TransferStatus1 = FAILED, if the data transmitted from USARTz and 
     received by USARTy are different */
  TransferStatus2 = Buffercmp(TxBuffer1, RxBuffer2, TxBufferSize1);
  /* TransferStatus2 = PASSED, if the data transmitted from USARTy and  
     received by USARTz are the same */
  /* TransferStatus2 = FAILED, if the data transmitted from USARTy and 
     received by USARTz are different */

  while (1)
  {
  }
}

/**
  * @brief  Configures the different system clocks.
  * @param  None
  * @retval None
  */
void RCC_Configuration(void)
{    
  /* DMA clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable GPIO clock */
  RCC_APB2PeriphClockCmd(USARTy_GPIO_CLK | USARTz_GPIO_CLK | RCC_APB2Periph_AFIO, ENABLE);

#ifndef USE_STM3210C_EVAL
  /* Enable USARTy Clock */
  RCC_APB2PeriphClockCmd(USARTy_CLK, ENABLE); 
#else
  /* Enable USARTy Clock */
  RCC_APB1PeriphClockCmd(USARTy_CLK, ENABLE); 
#endif
  /* Enable USARTz Clock */
  RCC_APB1PeriphClockCmd(USARTz_CLK, ENABLE);  
}

/**
  * @brief  Configures the different GPIO ports.
  * @param  None
  * @retval None
  */
void GPIO_Configuration(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;

#ifdef USE_STM3210C_EVAL
  /* Enable the USART3 Pins Software Remapping */
  GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);

  /* Enable the USART2 Pins Software Remapping */
  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);  
#elif defined(USE_STM3210B_EVAL) || defined(USE_STM32100B_EVAL)
  /* Enable the USART2 Pins Software Remapping */
  GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);
#endif

  /* Configure USARTy Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = USARTy_RxPin;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);

  /* Configure USARTz Rx as input floating */
  GPIO_InitStructure.GPIO_Pin = USARTz_RxPin;
  GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);  

  /* Configure USARTy Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = USARTy_TxPin;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(USARTy_GPIO, &GPIO_InitStructure);

  /* Configure USARTz Tx as alternate function push-pull */
  GPIO_InitStructure.GPIO_Pin = USARTz_TxPin;
  GPIO_Init(USARTz_GPIO, &GPIO_InitStructure);  
}

/**
  * @brief  Configures the nested vectored interrupt controller.
  * @param  None
  * @retval None
  */
void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;

  /* Enable the USARTz Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = USARTz_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  Configures the DMA.
  * @param  None
  * @retval None
  */
void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;

  /* USARTy_Tx_DMA_Channel (triggered by USARTy Tx event) Config */
  DMA_DeInit(USARTy_Tx_DMA_Channel);
  DMA_InitStructure.DMA_PeripheralBaseAddr = USARTy_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer1;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = TxBufferSize1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_Init(USARTy_Tx_DMA_Channel, &DMA_InitStructure);

  /* USARTz_Tx_DMA_Channel (triggered by USARTz Tx event) Config */
  DMA_DeInit(USARTz_Tx_DMA_Channel);
  DMA_InitStructure.DMA_PeripheralBaseAddr = USARTz_DR_Base;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)TxBuffer2;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = TxBufferSize2;
  DMA_Init(USARTz_Tx_DMA_Channel, &DMA_InitStructure);
}

/**
  * @brief  Compares two buffers.
  * @param  pBuffer1, pBuffer2: buffers to be compared.
  * @param  BufferLength: buffer's length
  * @retval PASSED: pBuffer1 identical to pBuffer2
  *         FAILED: pBuffer1 differs from pBuffer2
  */
TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint16_t BufferLength)
{
  while(BufferLength--)
  {
    if(*pBuffer1 != *pBuffer2)
    {
      return FAILED;
    }

    pBuffer1++;
    pBuffer2++;
  }

  return PASSED;
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}

#endif

/**
  * @}
  */ 

/**
  * @}
  */ 

今天搭一个LAMP的网站,我准备用phpmyadmin初始化一下表的结构,就把之前放在笔记本上压缩好的tar给scp上去了,结果顿时GG,访问php页面,返回一片空白,然后发现是selinux在作怪,上传的tar里的文件被标记成了不可运行的文件导致无法使用,那么,selinux到底是什么,能干什么呢
selinux目前在各大发行版上均已内置,它是由NSA最先开发并置入linux系统的,从2.6版内核起,selinux作为linux内核的一部分,逐渐走进了各种linux主机里,安卓系统在4.2开始也提供了selinux的可选项,5.0之后更是将其直接默认打开。
selinux基于最小权限原则设计,也就是在维持程序运行的情况下,赋予其尽可能少的权限。也正是因为这种设计思想,导致经常会有某些软件更新后权限需求发生变化,系统boolen策略没有跟上,导致程序无法运行,还有很多由自己开发的驱动,在开启了selinux的系统中无法运行的情况。还有最恶心的就是oracle的软件在安装时都会让你把selinux给关掉,于是,不会配置的人直接关了一了百了,会配置的人嫌麻烦也关了一了百了。
在个人用户的层面,selinux的存在应该是纯粹的累赘,因为他们根本不需要selinux提供的强权限管理,反而selinux给他们带来了很多乱七八糟的麻烦,所以,建议普通用户,对于自己信息安全要求不太高时,完全可以将其一关了之。
selinux将grant模型分成两大组 subject 和 object ,也就是主客体,主客体可以是文件、网络端口、用户等等,selinux就是提供了一种他们之间的交互权限的控制功能,而且这个控制是非常细粒度的,他可以针对各个不同的对象之间的互相访问分别作出限制规则。
关于规则的配置,过几天春季学期结束了,我要好好谈一谈,现在先说说怎么关掉它
selinux有三种状态:enforcing,permissive,disabled可通过sestatus命令查看当前状态
通过setenforce 0;
或者修改/etc/selinux/config里面的SELINUX=enforcing改为SELINUX=disabled即可