menu Chancel's Blog
rss_feed lightbulb_outline

我的笔记

Git - 忽略规则和.gitignore规则不生效解决方案

把某些目录或文件加入忽略规则,按照上述方法定义后发现并未生效,原因是.gitignore只能忽略那些原来没有被追踪的文件

如果某些文件已经被纳入了版本管理中,则修改.gitignore是无效的。那么解决方法就是先把本地缓存删除(改变成未被追踪状态)

最后再次提交即可

git rm -r --cached .
git add .
git commit -m 'update .gitignore'

Develop Base Git 2021-02-04 11:32:33 location_on

Git - "fatal: unable to auto-detect email address "

Git Push的时候出现警告“fatal: unable to auto-detect email address ”

只需要更改当前仓库下的.git/config文件,在其中加入

[user]
    email = xxx
    user = xxx

即可消除这个警告

Develop Base Git 2021-02-04 11:31:11 location_on

Python - 缓存字典到本地(支持多线程写入/读取)

缓存字典到本地(支持多线程写入/读取)

def GetIDTagDictByLocalTMP(id_tag: str):
    if ID_TAG_CACHE.get(id_tag):
        return ID_TAG_CACHE.get(id_tag)
    id_tag_dict = {'id': id_tag}
    SetIDTagDictToLocalTMP(id_tag, id_tag_dict)
    return id_tag_dict


def SetIDTagDictToLocalTMP(id_tag: str, id_tag_dict: dict):
    if not os.path.exists('tmp'):
        os.mkdir('tmp')
    ID_TAG_CACHE[id_tag] = id_tag_dict
    with open('cache/ID-TAG.json', 'w') as f:
        f.write(json.dumps(ID_TAG_CACHE, ensure_ascii=False))

def BuildIDTagCacheByLocalTmp():
    global ID_TAG_CACHE
    if not os.path.exists('cache'):
        os.mkdir('cache')
    if not os.path.exists('cache/ID-TAG.json'):
        return
    with open('cache/ID-TAG.json', 'r') as f:
        ID_TAG_CACHE = json.loads(f.read())

Develop Technology Python 2021-02-04 11:26:59 location_on

Python - 导出MySQL视图

import pymysql

'''
请按规则补充以下信息,并运行该脚本,即可获取按顺序导出的视图
    HOST:数据库IP地址
    PORT:数据库端口
    USER:用户名称
    PASSWD:用户密码
    DB_NAME:数据库名称
    CHARSET:编码格式(中文可默认 utf8mb4 )
'''

HOST = '192.168.11.214'
PORT = 3306
USER = 'root'
PASSWD = 'my_passwd'
DB_NAME = 'syncthing_manage'
CHARSET = 'utf8mb4'


conn = pymysql.connect(host=HOST, port=PORT, user=USER,
                       passwd=PASSWD, db=DB_NAME, charset=CHARSET)


def process_rely(parmas={}, rely_old=[]):
    _rely = []
    _keys = list(parmas.keys())
    for k in rely_old:
        for bl in _keys:
            if str(parmas[k]).find(bl) > -1:
                if bl not in _rely:
                    if k not in _rely:
                        _rely.append(bl)
                    else:
                        i = _rely.index(k)
                        _rely.insert(i, bl)
                else:
                    if k in _rely:
                        i = _rely.index(k)
                        j = _rely.index(bl)
                        if i < j:
                            del _rely[j]
                            _rely.insert(i, bl)
        if k not in _rely:
            _rely.append(k)
    return _rely


cur = conn.cursor()
cur.execute('select TABLE_NAME, VIEW_DEFINITION from  information_schema.VIEWS where TABLE_SCHEMA = %s ', DB_NAME)
rs = cur.fetchall()
cur.close()
conn.close()

ps = {}
for al in rs:
    ps['`' + al[0] + '`'] = al[1]

rely = process_rely(ps, list(ps.keys()))
# rely = process_rely(ps, rely1)

file_object = open('view.sql', 'w')
for al in rely:
    file_object.write('DROP VIEW IF EXISTS ' + al + ';\n')
    file_object.write('CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW ' + al +
                      ' AS ' + ps[al] + ';\n\n')

file_object.close()

Develop Technology Python 2021-03-20 15:51:35 location_on

Python - 登录二次验证实现

Python二次登录验证的实现,依赖于pyotp包

import pyotp

sec = pyotp.random_base32()
totp = pyotp.totp.TOTP(sec,interval=60)
qr_code_text = totp.provisioning_uri(name='Chancel.Yang', issuer_name='Secure App')
print('登录二次验证器创建成功,二维码数据->%s' % qr_code_text)

# 可选:生成验证码步骤
import qrcode
img = qrcode.make(qr_uri)
img.get_image().show()

```

Develop Technology Python 2021-02-04 11:19:20 location_on

Python - 命令行参数解析

命令行参数有两种

# 参数一
python3 main.py agrs1 agrs2 agrs3
# 参数二
python3 main.py -a aaa -b bbb

参数一的识别获取

import sys

print('输出的参数个数为:%d个参数' % len(sys.argv))
print('输出参数列表%s' % str(sys.argv))

调用输出如下

❯ python3 test.py a b c                                                    
输出的参数个数为:4个参数
输出参数列表['test.py', 'a', 'b', 'c']


参数二的识别获取

import argparse

parser = argpaimport argparse
rse.ArgumentParser(description='Test for argparse')
parser.add_argument('--port', '-p', help='端口参数', default='8220')
parser.add_argument('--config', '-c', help='配置文件路径', default='config.ini')
args = parser.parse_args()

print('port参数:%s,config参数:%s' % (args.port,agrs.config))

调用输出如下

❯ python3 test.py -p 20931 -c /home/apps/fuck                              
port参数:20931,config参数:/home/apps/fuck

Develop Technology Python 2021-02-01 17:17:10 location_on

Proxmox - 物理机Windows10如何虚拟化成虚拟机(P2V)

Windows10重装系统是非常简单的事情,但如何拷贝迁移旧系统数据是个难题,如果你有虚拟化的软件,那么把现有的Windows虚拟化成虚拟机是个保留资料的最佳方案

大意步骤

  1. 使用分区助手DiskGenius(免费版即有这个功能)热迁移当前操作系统成VMDK格式的虚拟机磁盘文件
  2. 创建一个硬件上类似于当前物理机器配置的虚拟机
  3. 将VMDK文件上传至你的PVE中,再转换VMDK磁盘文件成PVE能识别使用的QCOW2磁盘文件
  4. 导入磁盘文件到PVE的存储卷中,新建虚拟机并使用这个磁盘文件

首先,我们下载可以将当前操作系统热迁移成VMware磁盘格式的DiskGenius免费版

随后打开软件,在菜单栏-工具中选中 将当前操作系统迁移至VMware虚拟机中,选好输出格式与输出内容即可,这里假设输出文件名为 Windows10.vmdk

输出文件之后上传至PVE中,此步随意,可以用scp/smb等方式上传,上传成功之后,使用如下方法转换文件格式

qemu-img convert -O qcow2 Windows10.vmdk ../sdd/Windows10.qcow2

创建一个硬件上类似于当前物理机器配置的虚拟机,无需创建虚拟机硬盘(光驱也不需要)

最后,导入已转换完成的文件到存储卷中,102是新创建的虚拟机ID, local-Thin为卷名

qm importdisk 102 Windows10.qcow2 local-Thin

注:部分Windows10是UEFI方式启动,在PVE中要设置好以UEFI方式启动,否则可能识别不到硬盘

Virtualization Technology Windows 2021-01-26 13:04:06 location_on

Python - 版本管理Pyenv使用指南

pyenv lets you easily switch between multiple versions of Python. It's simple, unobtrusive, and follows the UNIX tradition of single-purpose tools that do one thing well.

官方仓库 - https://github.com/pyenv/pyenv

pyenv是目前管理Python版本的流行方案,对于一台PC上存在多个Python版本的最佳管理方案之一,以下安装基于 Debian10

安装pyenv

sudo apt -y install git gcc libgdbm-dev make patch zlib1g.dev libssl-dev libsqlite3-dev libbz2-dev libreadline-dev

curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

配置环境变量,这里设定是在当前用户下(Shell环境是ZSH,如果是Bash环境请修改对应 bashrc文件)

vim ~/.zshrc

export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

以下是常用命令

# 所有可安装的版本列表
pyenv install -list    

# 下载制定版本的Python
pyenv install 3.6.9

# 查看当前已下载的版本
pyenv versions

# 设置系统的Python版本
pyenv global 3.6.9

# 设置当前目录为某个Python版本
pyenv local 3.6.9

# 更新pyenv
pyenv update

注:Visual Studio Code会自动识别当前目录的pyenv指定的版本,在Terminal进入该目录时也会自动切换到该目录的Python版本

如果你希望的是在同一机器上同一个Pyhon版本不同项目的环境不相同,可参考 virtualenv的使用

Develop Base Python 2021-01-25 00:05:42 location_on

Debian - 休眠设置(无需调整swap分区)

如果在创建Debian操作系统的时候没有勾选需要休眠的话,那么swap分区大小一般为1G,远小于物理内存,休眠所需的swap空间通常略小于实际物理内存

为了确保休眠成功,一般会保证swap分区大小略大于实际物理内存,这个时候我们只需要创建swap分区文件即可

首先,创建一个swap分区文件,并添加开机挂载

sudo fallocate -l 32g /swapfile

sudo mkswap /swapfile

sudo echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab

暂停操作系统使用交换区

sudo sysctl -w vm.swappiness=1

创建内核变量文件

sudo echo 'vm.swappiness=1'/etc/sysctl.d/ local.conf

启动操作系统使用交换区

sudo swapon /swapfile

安装uswsusp工具调整休眠,根据前面的操作回答uswsusp工具的问题

sudo apt install uswsusp

sudo dpkg-reconfigure -pmedium uswsusp

设置完成后,查看你的uswsusp.conf配置文件,这是我的配置文件输出,可以使用 swap-offset /swap 校验swapfile文件偏移量是否准确

cat /etc/uswsusp.conf

# /etc/uswsusp.conf(5) -- Configuration file for s2disk/s2both 
resume device = /dev/nvme0n1p2
compress = y
early writeout = y
image size = 2147483647
RSA key file = /etc/uswsusp.key
shutdown method = platform
resume offset = 274432
encrypt = y

运行 update-initramfs -u 使上述所有设置生效,最后使用以下指令可测试休眠是否成功

s2disk

参考资料

Operating System Linux 2021-01-24 22:39:39 location_on

Inno Setup - Windows打包程序配置文件指南

Inno Setup是Jordan Russell和Martijn Laan的Windows程序的免费安装程序

Inno Setup is a free installer for Windows programs by Jordan Russell and Martijn Laan. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.

下面是仅供参考的配置文件,请注意时效性,随着Inno Setup版本更迭配置文件中的部分信息可能失效

; Script generated by the Inno Setup Script Wizard.
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!

#define MyAppName "HelloWorld"
#define MyAppVersion "0.9"
#define MyAppPublisher "chancel's company"
#define MyAppURL "https://www.chancel.ltd/"
#define MyAppExeName "helloworld.exe"

[Setup]
; NOTE: The value of AppId uniquely identifies this application.
; Do not use the same AppId value in installers for other applications.
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
AppId={{8435E930-A931-4967-8844-46X547X3BD8D}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
;AppVerName={#MyAppName} {#MyAppVersion}
AppPublisher={#MyAppPublisher}
AppPublisherURL={#MyAppURL}
AppSupportURL={#MyAppURL}
AppUpdatesURL={#MyAppURL}
DefaultDirName={userappdata}\{#MyAppName}
DisableProgramGroupPage=yes
DisableDirPage=no
;安装包的输出目录
OutputDir=D:\inno\output\{#MyAppName}
OutputBaseFilename={#MyAppName}_v{#MyAppVersion}
; 安装包的图标
;SetupIconFile=D:\inno\input\ico\_logo.ico
Compression=lzma
SolidCompression=yes
;此处 限制Windows最低版本为Windows 7
MinVersion=0.0,6.0


[Languages]
;安装语言许选择
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"

[Tasks]
;创建桌面快捷键
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: checkablealone

[Files]
;打包源文件与要安装的目标文件夹,DestDir需要参考官网文档,有多个枚举可选择
Source: "D:\inno\input\Release\*"; DestDir: "{app}\"; Flags: recursesubdirs ignoreversion
; NOTE: Don't use "Flags: ignoreversion" on any shared system files

[Icons]
;图标选择
Name: "{commonprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon

[Run]
;程序安装成功后入口执行程序
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent

Develop Base 2021-01-20 16:02:28 location_on

4 of 13 | A total of 128