SyntaxError: unqualified exec is not allowed in function 'xxx' it is a nested function

遇到问题

如同标题,我遇到了这样的错误

1
SyntaxError: unqualified exec is not allowed in function 'call_plugin_func' it is a nested function

很纳闷的是我同样在别的机器上远行代码没有遇到这样的问题,完全相同的代码为什么会出现语法错误?

解决

查阅资料后得知,这应该是Python版本兼容性的问题,低于2.7.9版本的Python会遇到这样的问题。具体原理就不多赘述了,升级过版本如果能解决你遇到的问题,我会很开心!

升级版本2.7.9

ImportError: libsybdb.so.5: cannot open shared object file: No such file or directory

遇到的问题

ImportError: libsybdb.so.5

今天安装pymssql,众所周知,这个库依赖FreeTDS,所以我通过下载源码的方式安装了它,但问题也出现了,运行后报了以下错误

1
2
ImportError: libsybdb.so.5: cannot open shared object file: No such file or
directory

这让我很苦恼,本来对linux系统就不是特别熟悉,多方查阅资料,搜索技术博客。很多人写的都不能解决我的问题。直到后来,这里不得不说说搜索引擎的影响了。同样的搜索条件,百度给的大多是百度知道,新浪博客和一些不知道什么奇奇怪怪的一大堆广告的类似于CSDN这种博客或者学习网站的结果,这很影响心情!!!还是用了谷歌,令人欣慰,结果大都来自知名的github,或者Stack Overflow。看起来很靠谱,没想到,结果也很靠谱!

解决

分析原因为使用源码安装FreeTDS时,其产生的文件也在自己指定的文件夹中,这就导致程序不一定能找到它。从而导致 ImportError!症结所在找到了,解决自然就比较流畅了,最方便的方法,创建软连接,使用sudo find / -name libsybdb.so.5找到我的libsybdb.so.5文件坐在位置比如,我的文件在/home/pcw/Downloads/freetds-0.91/src/dblib/.libs/libsybdb.so.5使用命令创建软链接

1
sudo ln -s /home/pcw/Downloads/freetds-0.91/src/dblib/.libs/libsybdb.so.5 /usr/lib/libsybdb.so.5

当然,你需要把路径换成你自己的!

参考链接 github

mac终端切换用户

1、mac终端切换用户到root

sudo -i 即可

2、mac终端切换成普通用户

su - test(test为用户名)即可

3、mac可以设置命令别名

如ll,正常情况下,mac终端不识别ll命令,但是alias 命令设置别名后,终端即可以设别ll命令:alias ll=’ls -la’;但是没有修改系统文件,则该命令只能临时生效,下次再打开终端,还是不能识别ll命令,永久生效办法,请修改系统文件,方法有多种,请自行百度(如果不是ll命令,其他命令同理)

mac设置环境变量PATH

理论篇

Mac系统的环境变量,加载顺序为:

/etc/profile

/etc/paths

~/.bash_profile

~/.bash_login

~/.profile

~/.bashrc

/etc/profile和/etc/paths是系统级别的,系统启动就会加载,后面几个是当前用户级的环境变量。后面3个按照从前往后的顺序读取,如果/.bash_profile文件存在,则后面的几个文件就会被忽略不读了,如果/.bash_profile文件不存在,才会以此类推读取后面的文件。~/.bashrc没有上述规则,它是bash shell打开的时候载入的。

PATH的语法为如下

1
2
#中间用冒号隔开
export PATH=$PATH:<PATH 1>:<PATH 2>:<PATH 3>:------:<PATH N>

上述文件的科普

  • /etc/paths (全局建议修改这个文件 )
    编辑 paths,将环境变量添加到 paths文件中 ,一行一个路径
    Hint:输入环境变量时,不用一个一个地输入,只要拖动文件夹到 Terminal 里就可以了。
  • /etc/profile (建议不修改这个文件 )
    全局(公有)配置,不管是哪个用户,登录时都会读取该文件。
  • /etc/bashrc (一般在这个文件中添加系统级环境变量)
    全局(公有)配置,bash shell执行时,不管是何种方式,都会读取此文件
  • .profile 文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置
    使用注意:如果你有对/etc/profile有修改的话必须得重启你的修改才会生效,此修改对每个用户都生效。
  • ./bashrc 每一个运行bash shell的用户执行此文件.当bash shell被打开时,该文件被读取.
    使用注意 对所有的使用bash的用户修改某个配置并在以后打开的bash都生效的话可以修改这个文件,修改这个文件不用重启,重新打开一个bash即可生效。
  • ./bash_profile 该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该文件被读取.(每个用户都有一个.bashrc文件,在用户目录下)
    使用注意 需要需要重启才会生效,/etc/profile对所有用户生效,~/.bash_profile只对当前用户生效。

source ./.bash_profile 或者 ./.profile 环境信息生效

操作篇

全局设置

创建一个文件:

1
sudo touch /etc/paths.d/mysql

用 vim 打开这个文件(如果是以 open -t 的方式打开,则不允许编辑):

1
sudo vim /etc/paths.d/mysql

编辑该文件,键入路径并保存(关闭该 Terminal 窗口并重新打开一个,就能使用 mysql 命令了)

1
/usr/local/mysql/bin

$ source 相应的文件 生效配置环境

单个用户设置

cd ~

vim ~/.bash_profile (任意一个文件中添加用户级环境变量)

1
export PATH=/opt/local/bin:/opt/local/sbin:$PATH

把上述代码添加到~/.bash_profile上。

source 相应的文件 生效配置环境

查看PATH

1
echo $PATH

python使用schedule定时任务

python中的轻量级定时任务调度库:schedule

定时任务可以使用celery或crontab等,Python中有一个轻量级的定时任务调度的库:schedule。

安装

pip install schedule

简单例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import schedule
import time

def job():
print("I'm working...")

schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).days.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)

while True:
schedule.run_pending()
time.sleep(1)

多任务运行

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
import datetime
import schedule
import time

def job1():
print("I'm working for job1")
time.sleep(2)
print("job1:", datetime.datetime.now())

def job2():
print("I'm working for job2")
time.sleep(2)
print("job2:", datetime.datetime.now())

def run():
schedule.every(10).seconds.do(job1)
schedule.every(10).seconds.do(job2)

while True:
schedule.run_pending()
time.sleep(1)


if __name__ == '__main__':
run()

由于上面这种方法会导致job2运行延迟,所以这时候需要使用多线程运行。

多线程运行

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
import datetime
import schedule
import threading
import time

def job1():
print("I'm working for job1")
time.sleep(2)
print("job1:", datetime.datetime.now())

def job2():
print("I'm working for job2")
time.sleep(2)
print("job2:", datetime.datetime.now())

def job1_task():
threading.Thread(target=job1).start()

def job2_task():
threading.Thread(target=job2).start()

def run():
schedule.every(10).seconds.do(job1_task)
schedule.every(10).seconds.do(job2_task)

while True:
schedule.run_pending()
time.sleep(1)


if __name__ == '__main__':
run()

Python实现RPC微型服务器

RPC

先说说什么是RPC,RPC(Remote Procedure Call)——远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

说白了,就是一种远程调用函数接口的方式,客户端和服务端之间约定一种契约(函数接口),然后服务端一直等待客户端的调用。有点像平常的WEB网络请求,不过这种方式非常轻量,不涉及HTTP这些东西,待会可以看到实现很简单。

上面说了,一种用途是在多台服务器之间互相进行调用,另一个用途则在于,不同编程语言之间都支持这种方式,像Python更是内置对其的支持,不需要额外安装什么库,所以可以直接在多语言的服务器之间互相进行调用,很简单。

xmlrpc库

在Python2(网上大部分是Python2使用RPC的资料)中,服务端需要用到SimpleXMLRPCServer库,客户端需要用到ServerProxy库,而在Python3中,两者被整合到了同一个xmlrpc库中,分为xmlrpc.server和xmlrpc.client两部分。所以如果在Python3下使用,就需要导入这个库了。

简单版

  • 服务器端
1
2
3
4
5
6
7
8
9
10
11
12
13
from xmlrpc.server import SimpleXMLRPCServer


# 调用函数
def respon_string(str):
return "get string:%s" % str


if __name__ == '__main__':
server = SimpleXMLRPCServer(('localhost', 8888)) # 初始化
server.register_function(respon_string, "get_string") # 注册函数
print("Listening for Client")
server.serve_forever() # 保持等待调用状态
  • 客户端
1
2
3
4
5
from xmlrpc.client import ServerProxy

if __name__ == '__main__':
server = ServerProxy("http://localhost:8888") # 初始化服务器
print(server.get_string("cloud")) # 调用函数并传参

多线程版

  • 服务器端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from xmlrpc.server import SimpleXMLRPCServer
from socketserver import ThreadingMixIn


class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
pass


# 调用函数1
def respon_string(str):
return "get string:%s" % str


# 调用函数2
def add(x, y):
return x + y


if __name__ == '__main__':
server = ThreadXMLRPCServer(('localhost', 8888)) # 初始化
server.register_function(respon_string, "get_string") # 注册函数1
server.register_function(add, 'add') # 注册函数2
print("Listening for Client")
server.serve_forever() # 保持等待调用状态
  • 客户端
1
2
3
4
5
6
from xmlrpc.client import ServerProxy

if __name__ == '__main__':
server = ServerProxy("http://localhost:8888") # 初始化服务器
print(server.get_string("cloud")) # 调用函数1并传参
print(server.add(8, 8)) # 调用函数2并传参

文件上传下载

  • 服务器端
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
from xmlrpc.server import SimpleXMLRPCServer
from socketserver import ThreadingMixIn
import xmlrpc.client


class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
pass


# 供客户端下载文件
def image_get():
handle = open("boy.jpg", 'rb')
return xmlrpc.client.Binary(handle.read())


# 供客户端上传文件
def image_put(data):
handle = open("get_girl.jpg", 'wb')
handle.write(data.data)
handle.close()


if __name__ == '__main__':
server = ThreadXMLRPCServer(('localhost', 8888), allow_none=True) # 初始化
server.register_function(image_put, 'image_put')
server.register_function(image_get, 'image_get')
print("Listening for Client")
server.serve_forever() # 保持等待调用状态
  • 客户端
1
2
3
4
5
6
7
8
9
10
11
12
13
from xmlrpc.client import ServerProxy
import xmlrpc.client

if __name__ == '__main__':
server = ServerProxy("http://localhost:8888", allow_none=True)
# 上传文件
put_handle = open("girl.jpg", 'rb')
server.image_put(xmlrpc.client.Binary(put_handle.read()))
put_handle.close()
# 下载文件
get_handle = open("get_boy.jpg", 'wb')
get_handle.write(server.image_get().data)
get_handle.close()

Markdown语法

Markdown语法

1
2
3
4
5
6
# 这是一级标题
## 这是二级标题
### 这是三级标题
#### 这是四级标题
##### 这是五级标题
###### 这是六级标题

这是一级标题

这是二级标题

这是三级标题

这是四级标题

这是五级标题
这是六级标题
1
2
3
4
**这是加粗的文字**
*这是倾斜的文字*`
***这是斜体加粗的文字***
~~这是加删除线的文字~~

这是加粗的文字
这是倾斜的文字`
这是斜体加粗的文字
这是加删除线的文字

1
2
3
>这是引用的内容
>>这是引用的内容
>>>>>>>>>>这是引用的内容

这是引用的内容

这是引用的内容

这是引用的内容

1
2
3
4
--- 分割线
----
***
*****

1
2
3
4
5
加入图片
![]()
示例:
![blockchain](https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/
u=702257389,1274025419&fm=27&gp=0.jpg "区块链")
1
2
[简书](http://jianshu.com)
[百度](http://baidu.com)

简书
百度

1
2
3
4
<a href="超链接地址" target="_blank">超链接名</a>

示例
<a href="https://www.jianshu.com/u/1f5ac0cf6a8b" target="_blank">简书</a>

简书

1
2
3
4
5
- 列表内容
+ 列表内容
* 列表内容

注意:- + * 跟内容之间都要有一个空格
  • 列表内容
  • 列表内容
  • 列表内容
1
2
3
4
5
1.列表内容
2.列表内容
3.列表内容

注意:序号跟内容之间要有空格
  1. 列表内容
  2. 列表内容
  3. 列表内容
  • 列表嵌套

上一级和下一级之间敲三个空格即可

    • 2.1

screen的相关用法笔记

参考链接

screen

screen就是开启一个新的终端,利用这个工具可以确保任务不会因为退出某个终端而终止。

1
2
3
4
5
6
7
8
9
screen  # 输入命令screen会打开一个终端,ctrl+a然后ctrl+d会退出该终端。

[detached from 17799.pts-1.cent01]

screen

[detached from 17834.pts-1.cent01]

screen -ls # 列出有哪些screen终端以及他们的编号
1
2
3
4
5
6
7
8
9
10
11
There are screens on: 

17834.pts-1.cent01 (Detached)

17799.pts-1.cent01 (Detached)

14030.pts-1.cent01 (Detached)

13942.pts-1.cent01 (Detached)

4 Sockets in /var/run/screen/S-root.

进入某个screen

1
screen -r 13942 //进入screen 13942

创建新的screen

1
2
screen -S "abc" # 使用-S为一个screen终端命名,避免弄不清哪个终端是什么作用。
[detached from 17928.abc]

列举所有screen

1
screen -ls
1
2
3
4
5
6
7
8
9
10
11
12
13
There are screens on: 

17928.abc (Detached)

17834.pts-1.cent01 (Detached)

17799.pts-1.cent01 (Detached)

14030.pts-1.cent01 (Detached)

13942.pts-1.cent01 (Detached)

5 Sockets in /var/run/screen/S-root.

关闭某个screen

1
screen -X -S 21778 quit

退出某个screen

ctrl+a然后ctrl+d会退出该终端。

清除dead 会话

如果由于某种原因其中一个会话死掉了(例如人为杀掉该会话),这时screen -list会显示该会话为dead状态。使用screen -wipe命令清除该会话:

批量结束进程

1
pkill -9 chromedriver

使用github创建自己的博客

一、创建github项目

  • 创建仓库

    访问:https://github.com 注册账号并登陆

    登陆后创建新的仓库,如图:

    创建仓库

    输入地址

    我这里因为我已经创建了,会提示已经存在,你只需要在这里填上你自己的域名即可,必须以 github.io 结尾,前面写上自己的用户名。

    tips:可以同时创建readme,用于介绍项目,也可以不创建。

  • 相关设置

    进入setting

    setting

    发布

​ 看到这里就能访问域名了,但显示的是404,因为你还没有配置文件。这里介绍使用hexo创建博客。

二、配置ssh

1、按照如下命令创建ssh密钥对
1
2
3
4
5
6
7
8
9
10
cd ~/.ssh
ls
#此时会显示一些文件
mkdir key_backup
cp id_rsa* key_backup
rm id_rsa*
#以上三步为备份和移除原来的SSH key设置
ssh-keygen -t rsa -C "邮件地址@youremail.com" #生成新的key文件,邮箱地址填你的Github地址
#Enter file in which to save the key (/Users/your_user_directory/.ssh/id_rsa):<回车就好>
#接下来会让你输入密码
2、添加SSH Key到Github

setting

ssh

newssh

copy

做到这一步就可以测试一下是否配置成功了:

1
2
ssh -T git@github.com
#之后会要你输入yes/no,输入yes就好了。

设置账号信息:

1
2
git config --global user.name "你的名字"     #真实名字不是github用户名
git config --global user.email "邮箱@邮箱.com" #github邮箱

三、安装Hexo

​ 要使用Hexo,需要安装Nodejs以及Git

安装Node.js

下载Node.js

​ 参考:安装Node.js

安装git

下载git

安装Hexo

1
2
3
4
5
npm install hexo-cli -g   
hexo init #初始化网站
npm install
hexo g #生成或 hexo generate
hexo s #启动本地服务器 或者 hexo server,这一步之后就可以通过http://localhost:4000 查看了

详细命令参考Hexo文档

1
2
hexo new "文章名" #新建文章
hexo new page "页面名" #新建页面

常用简写命令

1
2
3
4
hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy

新建一篇文章后就可以预览了,在hexo new之后执行一次生成hexo g再执行hexo s启动本地服务器,如果之前还在hexo s 按Ctrl + C 结束.

四、添加主题

安装主题

官网等渠道选择主题,下载或clone到本地,放入theme文件夹下

启动主题

找到主目录_config.yml文件,打开并设置属性 theme: <你的主题名字>

theme

使用命令生成页面并发布

1
2
hexo g  # 生成
hexo s # 本地访问

发布需要配置_config.yml文件

1
2
3
4
deploy:
type: git
repo: git@github.com:pcw1993/pcw1993.github.io.git #这里的网址填你自己的
branch: master

保存后需要提前安装一个扩展:

1
npm install hexo-deployer-git --save

发布:

1
hexo d  # 发布

访问域名即可看到已生成的博客页面

mysql8.0.12重置root密码方法

@TOC

问题

mysql登录无法连接,问题未知,就是连接不上,报错:

1
2
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

解决办法

重置root密码,网上很多错误方法

1
2
update user set Password=password("新密码") where User='root';
update user set authentication_string=password("新密码") where User='root';

以上这些,都是错的!!!错的!!!但搜索很多结果都这么写,诚然,以前的版本是这样,但你们标着大大的8.0以后的版本写着这些错误的方法是干嘛?一个个复制粘贴党!!!

经过多次试验,终于找到症结所在,以前的password()函数已经不用了,正确的语句应该是

1
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';

完整步骤

打开终端

1
2
3
mysqld_safe --user=mysql --skip-grant-tables --skip-networking 
// 下面的也是不行的
mysqld -nt --skip-grant-tables

再另外打开一个终端窗口

1
2
3
4
use mysql;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密码';
flush privileges;
\q; //退出

搞定!