【翻译】编写一个小型静态网站生成器

Python 【翻译】编写一个小型静态网站生成器 大概有一百多种用 Python 编写的静态站点生成器(甚至还有其他语言编写的静态站点生成器)。 所以我决定写我自己的。为什么?好吧,我只是想。我希望将自己的博客从Ghost移开,并且希望保持真正的简约性。我决定使用 GitHub Pages 托管,因为他们最近宣布支持 自定义域的SSL。 渲染内容 每个静态网站生成器都需要采用某种源格式(例如 Markdown 或 ReStructuredText)并将其转换为 HTML。自从我离开 Ghost 以来,我决定坚持 Markdown。 自从我最近将 Github风格的Markdown渲染 集成到 Warehouse 中以来,我决定使用 cmarkgfm 。使用以下方式将 Markdown 渲染为 HTML: import cmarkgfm def render_markdown(content: str) -> str: content = cmarkgfm.markdown_to_html_with_extensions( content, extensions=['table', 'autolink', 'strikethrough']) return content cmarkgfm 确实有一个名为 github_flavored_markdown_to_html 的便捷方法,但是它使用 GitHub 的 tagfilter 扩展名,当我要将脚本和内容嵌入到帖子中时,这是不希望的。因此,我只是选择了我想使用的扩展。 收集资源(所有文档) 好的,我们有一种渲染 Markdown 的方法,但是我们还需要一种收集所有源文件的方法。我决定将所有来源存储在 ./src。我们可以pathlib用来收集它们: import pathlib from typing import Iterator def get_sources() -> Iterator[pathlib.Path]: return pathlib.Path('.').glob('srcs/*.md') 头部元数据 许多静态网站生成器都有 “前题” 的概念-一种为每个源文件设置元数据等的方法。我想支持 frontmatter,让我为每个帖子设置日期和标题。看起来像这样: --- title: Post time date: 2018-05-11 --- # Markdown content here. 对于 frontmatter 有一个非常好的和简单的现有库,称为 python-frontmatter。我可以用它来提取前题和原始内容: ...

【转载】Linux Locale 设置

Linux 【转载】Linux Locale 设置 说明: Locale是根据计算机用户所使用的语言,所在国家或者地区,以及当地的文化传统所定义的一个软件运行时的语言环境。 如果 Linux 机器上出现字符乱码的问题,可以优先确定是否因为 Locale 设置不对而导致的,其次再去排查文件本身编码问题。 Locale 分类 - LC_CTYPE:语言符号及其分类 - LC_NUMERIC:数字 - LC_COLLATE:比较和排序习惯 - LC_TIME:时间显示格式 - LC_MONETARY:货币单位 - LC_MESSAGES:信息主要是提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等 - LC_NAME:姓名书写方式 - LC_ADDRESS:地址书写方式 - LC_TELEPHONE:电话号码书写方式 - LC_MEASUREMENT:度量衡表达方式 - LC_PAPER:默认纸张尺寸大小 - LC_IDENTIFICATION:Locale 对自身包含信息的概述 $ locale LANG=en_US.UTF-8 LC_CTYPE="en_US.UTF- 8" #用户所使用的语言符号及其分类 LC_NUMERIC="en_US.UTF- 8" #数字 LC_TIME="en_US.UTF-8" #时间显示格式 LC_COLLATE="en_US.UTF-8" #比较和排序习惯 LC_MONETARY="en_US.UTF-8" #LC_MONETARY LC_MESSAGES="en_US.UTF- 8" #信息主要是提示信息,错误信息, 状态信息, 标题, 标签, 按钮和菜单等 LC_PAPER="en_US.UTF- 8" #默认纸张尺寸大小 LC_NAME="en_US.UTF-8" #姓名书写方式 LC_ADDRESS="en_US.UTF-8" #地址书写方式 LC_TELEPHONE="en_US.UTF-8" #电话号码书写方式 LC_MEASUREMENT="en_US.UTF-8" #度量衡表达方式 LC_IDENTIFICATION="en_US.UTF-8" #对自身包含信息的概述 LC_ALL= Locale 文件位置 Locale 定义文件在 /usr/share/i18n/locales Locale 用户定义文件在 /usr/lib/locale/ Locale 设定的优先级关系 设定 Locale 就是设定 12 大类的 Locale 分类属性,即12个LC_*。 ...

【转载】Linux Useradd 命令基本用法

Linux 【转载】Linux Useradd 命令基本用法 在 Linux 中 useradd 是个很基本的命令,但是使用起来却很不直观。以至于在 Ubuntu 中居然添加了一个 adduser 命令来简化添加用户的操作。本文主要描述笔者在学习使用 useradd 命令时的一些测试结果。 说明:本文中的所有试验都是在 Ubuntu14.04 上完成。 功能 在 Linux 中 useradd 命令用来创建或更新用户信息。 useradd 命令属于比较难用的命令 (low level utility for adding users),所以 Debian 系的发行版中建议管理员使用 adduser 命令。其实 adduser 命令只是一个调用了 useradd 命令的脚本文件。 本文将详细分析群组和家目录相关的选项。并且以实例的方式介绍常用的 useradd 命令写法。 语法和基本选项 注意:本文并不是一个完整的文档,所以仅列出部分常用的选项进行说明。 useradd [option] username [option]: -d, --home-dir HOME_DIR 指定用户登入时的目录 -g, --gid GROUP 设置初始群组 -G, --groups GROUPS 添加用户到已有群组 -m, --create-home 自动创建用户的家目录 -M, --no-create-home 不要创建用户的家目录 -N, --no-user-group 不要创建以用户名称为名的群组 -s, --shell SHELL 指定用户登入后所使用的shell -u, --uid UID 指定用户ID -p, --password PASSWORD 设置密码 细说用户组 首先我们要搞清楚,什么是初始群组?简单来说在 /etc/passwd 文件中,每行的第四个字段指定的就是用户的初始群组。用户登录后立即就拥有了初始群组中的权限。 ...

【转载】Linux 中 apt 与 apt-get 命令的区别与解释

Linux 【转载】Linux 中 apt 与 apt-get 命令的区别与解释 Ubuntu 16.04 发布时,一个引人注目的新特性便是 apt 命令的引入。其实早在 2014 年,apt 命令就已经发布了第一个稳定版,只是直到 2016 年的 Ubuntu 16.04 系统发布时才开始引人关注。 随着 apt install package 命令的使用频率和普遍性逐步超过 apt-get install package,越来越多的其它 Linux 发行版也开始遵循 Ubuntu 的脚步,开始鼓励用户使用 apt 而不是 apt-get。 那么,apt-get 与 apt 命令之间到底有什么区别呢?如果它们有类似的命令结构,为什么还需要新的 apt 命令呢?是否 apt 真的比 apt-get 更好?普通用户应该使用新的 apt 命令还是坚持旧有习惯继续使用 apt-get 呢? apt 与 apt-get 在开始对比 apt 与 apt-get 命令的区别之前,我们先来看看这两个命令的背景,以及它们要试图达到的目的。 Debian 作为 Ubuntu、Linux Mint 和 elementary OS 等 Linux 操作系统的母板,其具有强健的「包管理」系统,它的每个组件和应用程序都内置在系统中安装的软件包中。Debian 使用一套名为 Advanced Packaging Tool(APT)的工具来管理这种包系统,不过请不要把它与 apt 命令混淆,它们之间是其实不是同一个东西。 ...

【转载】Linux 防火墙:关于 iptables 和 firewalld 的那些事

Linux [[iptables]] 【转载】Linux 防火墙:关于 iptables 和 firewalld 的那些事 作者: David Clinton 译者: LCTT heguangzhi 2018-10-03 17:18 以下是如何使用 iptables 和 firewalld 工具来管理 Linux 防火墙规则。 这篇文章摘自我的书《Linux in Action》,尚未发布的第二个曼宁出版项目。 防火墙 防火墙是一组规则。当数据包进出受保护的网络区域时,进出内容(特别是关于其来源、目标和使用的协议等信息)会根据防火墙规则进行检测,以确定是否允许其通过。防火墙可以根据协议或基于目标的规则过滤请求。 一方面, iptables 是 Linux 机器上管理防火墙规则的工具。 另一方面,firewalld 也是 Linux 机器上管理防火墙规则的工具。 你有什么问题吗?如果我告诉你还有另外一种工具,叫做 nftables,这会不会糟蹋你的美好一天呢? 好吧,我承认整件事确实有点好笑,所以让我来解释一下。这一切都从 Netfilter 开始,它在 Linux 内核模块级别控制访问网络栈。几十年来,管理 Netfilter 钩子的主要命令行工具是 iptables 规则集。 因为调用这些规则所需的语法看起来有点晦涩难懂,所以各种用户友好的实现方式,如 ufw 和 firewalld 被引入,作为更高级别的 Netfilter 解释器。然而,ufw 和 firewalld 主要是为解决单独的计算机所面临的各种问题而设计的。构建全方面的网络解决方案通常需要 iptables,或者从 2014 年起,它的替代品 nftables (nft 命令行工具)。 iptables 没有消失,仍然被广泛使用着。事实上,在未来的许多年里,作为一名管理员,你应该会使用 iptables 来保护的网络。但是 nftables 通过操作经典的 Netfilter 工具集带来了一些重要的崭新的功能。 从现在开始,我将通过示例展示 firewalld 和 iptables 如何解决简单的连接问题。 ...

【转载】Linux(Ubuntu)网络流量实时监控(iftop)

Linux Network Monitoring 【转载】Linux(Ubuntu)网络流量实时监控(iftop) 在类 Unix 系统中可以使用 top 查看系统资源,进程,内存占用等信息。查看网络状态可以使用netstat、nmap 等工具。 若要查看实时的网络流量,监控 TCP/IP 连接,反向解析 IP,显示端口信息等,则可以使用 iftop。 1、安装 $ sudo apt-get install iftop 2、命令说明 语法: iftop -h | [-npblNBP] [-i interface] [-f filter code] [-F net/mask] [-G net6/mask6] -h 显示本帮助(Help)信息 -n 不进行主机名(hostName)查找 -N 不将端口号(port Number)转换成对应的服务 to services -p 混合(Promiscuous)模式(显示网络相关的其他主机信息) -b 不显示流量图形条(Bar) -B 以字节(Byte)为单位,显示带宽(Bandwidth);默认以比特(bit)显示的 -i interface 监控的网卡接口(interface) -f filter code 包统计时,使用过滤码;默认:无,只统计IP包 -F net/mask 显示特定IPv4网段的进出流量(Flow);如# iftop -F 10.10.1.0/24 -G net6/mask6 显示特定IPv6网段的进出流量(Flow) -l 显示并统计IPv6本地(Local)链接的流量(默认:关) -P 显示端口(Port) -m limit 设置显示界面上侧的带宽刻度(liMit) -c config file 指定配置(Config)文件 -t 使用不带窗口菜单的文本(text)接口 排序: -o 2s Sort by first column (2s traffic average) -o 10s Sort by second column (10s traffic average) [default] -o 40s Sort by third column (40s traffic average) -o source Sort by source address -o destination Sort by destination address The following options are only available in combination with -t -s num print one single text output afer num seconds, then quit -L num number of lines to print 3、界面说明 204Mb 407Mb 611Mb 814Mb 0.99Gb └─────────────────────────┴─────────────────────────┴──────────────────────────┴─────────────────────────┴────────────────────────── bond-test => 192.168.1.103 1.44Mb 1.38Mb 0.99Mb <= 336Mb 327Mb 315Mb bond-test => 192.168.1.101 0b 0b 0b <= 295Mb 218Mb 244Mb bond-test => 192.168.1.140 10.1Kb 11.0Kb 10.8Kb <= 0b 0b 0b bond-test => 192.168.1.102 0b 0b 703Kb <= 0b 0b 0b bond-test => xxxxxxxxx 0b 0b 31b <= 0b 0b 31b ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── TX: cum: 12.3MB peak: 2.87Mb rates: 1.45Mb 1.39Mb 1.68Mb RX: 3.52GB 692Mb 631Mb 545Mb 560Mb TOTAL: 3.53GB 694Mb 632Mb 546Mb 561Mb 界面上面显示的是类似刻度尺的刻度范围,为显示流量图形的长条作标尺用的。 ...

【转载】Mac 上制作 Linux 系统 U 盘安装盘

Linux 【转载】Mac 上制作 Linux 系统 U 盘安装盘 Mac 下将 iso 镜像写入 U 盘可使用命令行工具 dd,操作如下: 找出 U 盘挂载的路径,使用如下命令:diskutil list 将 U 盘 unmount(将 N 替换为挂载路径):diskutil unmountDisk /dev/disk[N] 写入 U 盘:sudo dd if=iso_path of=/dev/rdisk[N] bs=1m,rdisk 中加入 r 可以让写入速度加快 查看所有的disk $ diskutil list /dev/disk2 (external, physical): #: TYPE NAME SIZE IDENTIFIER 0: Apple_partition_scheme *15.7 GB disk2 1: Apple_partition_map 4.1 KB disk2s1 2: Apple_HFS 2.6 MB disk2s2 解除其挂载 $ diskutil unmountDisk /dev/disk2 Unmount of all volumes on disk2 was successful 用 dd 命令将 iso 写入 $ sudo dd if=/Users/light/media/CentOS-7-x86_64-DVD-1908.iso of=/dev/rdisk2 bs=1m 利用 pv 监控克隆进度 使用 homebrew 安装 pv 工具,之后使用以下的命令来实现进度条的显示: ...

【转载】Nginx是什么以及简单使用

[[Nginx]] 【转载】Nginx是什么以及简单使用 Nginx是一款轻量级的Web服务器、反向代理服务器,由于它的内存占用少,启动极快,高并发能力强,在互联网项目中广泛应用。 常用功能 Http 代理 正向代理:由于防火墙的原因,我们并不能直接访问谷歌,那么我们可以借助VPN来实现,这就是一个简单的正向代理的例子。这里你能够发现,正向代理“代理”的是客户端,而且客户端是知道目标的,而目标是不知道客户端是通过VPN访问的。 反向代理:当我们在外网访问百度的时候,其实会进行一个转发,代理到内网去,这就是所谓的反向代理,即反向代理“代理”的是服务器端,而且这一个过程对于客户端而言是透明的。 负载均衡 Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的啦,你可以参照所有的负载均衡算法,给他一一找出来做下实现。 Ip hash算法,对客户端请求的ip进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。 web缓存 Nginx可以对不同的文件做不同的缓存处理,配置灵活,并且支持FastCGI_Cache,主要用于对FastCGI的动态程序进行缓存。配合着第三方的ngx_cache_purge,对制定的URL缓存内容可以的进行增删管理。 源码安装 yum -y install gcc gcc-c++ make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel ./configure make sudo make install 默认情况下,Nginx 会被安装在 /usr/local/nginx。通过设定编译选项,你可以改变这个设定。 运行结构 Master-Worker模式:启动Nginx后,其实就是在80端口启动了Socket服务进行监听。 Master进程的作用是? 读取并验证配置文件nginx.conf;管理worker进程; Worker进程的作用是? 每一个Worker进程都维护一个线程(避免线程切换),处理连接和请求;注意Worker进程的个数由配置文件决定,一般和CPU个数相关(有利于进程切换),配置几个就有几个Worker进程。 热部署的实现 修改配置文件nginx.conf后,重新生成新的worker进程,当然会以新的配置进行处理请求,而且新的请求必须都交给新的worker进程,至于老的worker进程,等把那些以前的请求处理完毕后,kill掉即可。 高并发的处理 Nginx采用了Linux的epoll模型,epoll模型基于事件驱动机制,它可以监控多个事件是否准备完毕,如果OK,那么放入epoll队列中,这个过程是异步的。worker只需要从epoll队列循环处理即可。 多个模型可以参考优化 Nginx。 配置 Nginx配置文件主要分成四部分: main(全局设置) server(主机设置) upstream(上游服务器设置,主要为反向代理、负载均衡相关配置) location(URL 匹配特定位置后的设置) 每部分包含若干个指令。 main 部分设置的指令将影响其它所有部分的设置; server 部分的指令主要用于指定虚拟主机域名、IP 和端口 upstream 的指令用于设置一系列的后端服务器,设置反向代理及后端服务器的负载均衡 location 部分用于匹配网页位置(比如,根目录“/”,“/images”,等等) 他们之间的关系式: ...

【转载】Python 包管理工具解惑

Python 【转载】Python 包管理工具解惑 一、困惑 作为一个 Python 初学者,我在包管理上感到相当疑惑(嗯,是困惑)。主要表现在下面几个方面: 这几个包管理工具有什么不同? distutils setuptools distribute disutils2 distlib pip 什么时候该用pip,什么时候该用 setup.py ,它们有关系么? easy_install、ez_setup.py、setup.py、setup.cfg 分别都是干啥的? wheel 和 pip 的关系? Egg 和 whl 的关系? 如何发布自己的模块(发布到PyPI)? 如何进行模块的私有发布(不发布到PyPI)? 为了弄清这些问题,我找了许多资料。最后发现最好的资料还是 python 的官方文档。 下面是阅读了所有我找到的资料后的一个总结,希望能帮到几个月后又把这些全部忘光的那个自己。 二、python 包管理工具大乱斗 我用时间顺序来描述乱斗过程。 1. distutils distutils 是 python 标准库的一部分,2000年发布。使用它能够进行 python 模块的 安装 和 发布。 setup.py 就是利用 distutils 的功能写成,我们可以看一个简单的 setup.py 的例子。 在这里可以看到关于 setupt.py 格式的所有详细描述:Writing the Setup Script。 要安装一个模块到当前的 python 环境中,可以使用这个模块提供的 setup.py 文件: python setup.py install 下面的代码会发布一个 python 模块,将其打包成 tar.gz 或者 zip 压缩包: ...

【转载】shell 生成指定范围随机数与随机字符串

Linux Shell 【转载】shell 生成指定范围随机数与随机字符串 使用系统的 $RANDOM 变量 $ echo $RANDOM 17617 $RANDOM 的范围是 [0, 32767] 如需要生成超过 32767 的随机数,可以用以下方法实现。 例:生成 400000~500000 的随机数 #!/bin/bash function rand(){ min=$1 max=$(($2-$min+1)) num=$(($RANDOM+1000000000)) #增加一个10位的数再求余 echo $(($num%$max+$min)) } rnd=$(rand 400000 500000) echo $rnd exit 0 或许可以使用:shuf -i 400000-500000 -n 1 使用date +%s%N 例:生成 1~50 的随机数 #!/bin/bash function rand(){ min=$1 max=$(($2-$min+1)) num=$(date +%s%N) echo $(($num%$max+$min)) } rnd=$(rand 1 50) echo $rnd exit 0 使用 /dev/random 和 /dev/urandom /dev/random 存储着系统当前运行环境的实时数据,是阻塞的随机数发生器,读取有时需要等待。 /dev/urandom 非阻塞随机数发生器,读取操作不会产生阻塞。 例:使用 /dev/urandom 生成 100~500 的随机数,使用 urandom 避免阻塞。 ...