使用 click 构造漂亮的Python命令行程序

Click 是 Python 下一款命令行库,可以用来快速轻松实现Python命令行程序。之前也介绍过一个 argparse ,但是要比 click 复杂很多,至少从代码上看。但是 click 其实也说了1 argparse 在标准库中,click 是依赖于 optparse 的,至于不基于 argparse 是因为 argparse 不支持嵌套,并且在 POSIX 兼容上有问题。

Click 被设计用来快速构建命令行程序,因此缺乏一些扩展性,比如他不允许高度定制help介绍。Click 是用来支持 Flask 开发框架的。

官网地址: http://click.pocoo.org

基本使用

# hello.py
import click
@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()

然后可以这样运行该脚本 python hello.py --count=3,并且 Click 还会自动生成 help 信息。

Option 参数

Click 使用基本可以归纳为

  • 使用 @click.command() 装饰一个函数,使之成为命令行接口;
  • 使用 @click.option() 等装饰函数,为其添加命令行选项等。

最基础的用法, option 接受一个变量

@click.command()
@click.option('--n', default=1)
def hello(n):
    click.echo('hello' * n)

使用 --n=2 输出两遍

接受多个变量,需要使用 nargs 指定数量

@click.command()
@click.option('--pos', nargs=2, type=float)
def cal(pos):
    click.echo('%s / %s' % pos)

使用 --pos 5.0 4.0

如果参数是固定的几个值,可以使用可选项

@click.command()
@click.option('--hash-type', type=click.Choice(['md5', 'sha1']))
def digest(hash_type):
    click.echo(hash_type)

使用 --hash-type=md5 参数只能为 md5 或者 sha1,否则报错。

option 还有其他一些参数,比如 prompt 当用户忘记该参数时,将错误报出来,hide_input 可以隐藏输入,常用于密码输入,confirmation_prompt 验证输入等等。

Click 封装了

@click.password_option()
@click.confirmation_option(prompt='Are you sure you want to drop the db?')

argument 参数

和 Option 一样,Argument 最基础的应用就是传递一个简单变量值

@click.command()
@click.argument('input', type=click.File('rb'))
@click.argument('output', type=click.File('wb'))
def inout(input, output):
    while True:
        chunk = input.read(1024)
        if not chunk:
            break
        output.write(chunk)

reference

  1. http://click.pocoo.org/6/why/ 


2018-03-27 python , flask , click , command

每天学习一个命令:vnstat 统计服务器网卡流量

vnStat 是一款开源的网络流量统计工具,可以方便的查看当天,当月流量统计。官网地址:

https://humdi.net/vnstat/

安装

在 Debian/Ubuntu 下非常简单

sudo apt install vnstat vnstati

假设网卡名为 eth0,该配置在 /etc/vnstat.conf 中,安装结束后初始化数据库

sudo vnstat -u -i eth0

添加为开机启动

sudo update-rc.d vnstat enable

使用

直接输入 vnstat

vnstat -l  # 或者 `--live` 实时流量
vnstat -h  # 按小时查询流量
vnstat -d  # 按日显示流量信息
vnstat -w  # 按周显示流量信息
vnstat -m  # 按月显示流量信息
vnstat -t  # 显示流量最高top10天

图形化输出可以使用 vnstati ,将月流量统计图输出到图片

vnstati -i eth0 - -months - -output /dir/month.png

获取每月用量

#!/bin/bash
# 绑定网卡,一般默认eth0, 根据实际情况填写
interface="eth0"

# 定义阈值,单位GiB
traffic_limit="14"

# 获取每月用量 $11:进站+出站;$10是:出站;$9是:进站
traffic="$(vnstat --oneline -i "${interface}" | awk -F ';' '{print $11}')"

if [[ "${traffic}" =~ ^.+GiB$ ]] && [[ "${traffic%.*}" -ge ${traffic_limit} ]]; then
     echo "当前流量超过限制:${traffic}"
# 执行后续操作
#    sudo halt
else
     echo "当前流量未超过限制:${traffic}"
fi

脚本

#!/bin/bash
# 定义阈值(以GB为单位) 执行 vnstat --json 命令并将输出保存到变量中
THRESHOLD_GIB=1700

vnstat_output=$(vnstat --json)
# 提取当前年份和月份
current_year=$(echo "$vnstat_output" | jq -r '.interfaces[0].traffic.month[0].date.year')
current_month=$(echo "$vnstat_output" | jq -r '.interfaces[0].traffic.month[0].date.month')


# 在"month"部分找到相应的"rx"和"tx"值
rx_value_bytes=$(echo "$vnstat_output" | jq -r '.interfaces[0].traffic.month[0].rx') 
rx_value_gb=$(echo "scale=2; $rx_value_bytes / 1024 / 1024 / 1024" | bc) 
tx_value_bytes=$(echo "$vnstat_output" | jq -r '.interfaces[0].traffic.month[0].tx') 
tx_value_gb=$(echo "scale=2; $tx_value_bytes / 1024 / 1024 / 1024" | bc) 

# 计算总流量
total_traffic=$(echo "$rx_value_gb + $tx_value_gb" | bc)


echo "当前月份接收流量 : $rx_value_gb GB" 
echo "当前月份发送流量 : $tx_value_gb GB"
echo "当前月份流量总计 : $total_traffic GB"

# 检查是否大于阈值
if (( $(echo "$total_traffic > $THRESHOLD_GIB" | bc -l) )); then 
    echo "流量超过阈值,正在执行关机操作..."
#   如果要执行重启就把下面的#去掉	
#     sudo halt
else 
    echo "本月流量充足" 
fi

发送 Telegram 通知

## 流量超过阈值就发送消息提醒

### config.json
# {
#   "telegram_bot_token": "xxxxx:xxxxxxx",
#   "chat_id": "xxxx",
#   "monthly_limit_gb": 100
# }

import json
import requests
import schedule
import time
import psutil
from datetime import datetime

def load_config():
    with open("config.json", "r") as file:
        return json.load(file)

def log_initial_traffic_usage():
    today = datetime.now()
    if today.day == 1:  # Check if it is the first day of the month
        net_io = psutil.net_io_counters(pernic=True).get('ens5')
        if net_io:
            total_bytes_initial = net_io.bytes_sent + net_io.bytes_recv
            print(f'{total_bytes_initial}')
            with open("traffic_usage.txt", "w") as file:
                file.write(f"{total_bytes_initial}\n")

def get_current_month_usage():
    try:
        with open("traffic_usage.txt", "r") as file:
            initial_bytes = int(file.readline().strip())
            net_io = psutil.net_io_counters(pernic=True).get('ens5')
            if net_io:
                current_total_bytes = net_io.bytes_sent + net_io.bytes_recv
                used_bytes = current_total_bytes - initial_bytes
                used_gb = used_bytes / (1024**3)  # Convert to GB
                return used_gb
    except FileNotFoundError:
        print("Initial traffic usage file not found. Make sure it's generated at the beginning of the month.")
        return None

def send_telegram_message(message, config):
    url = f"https://api.telegram.org/bot{config['telegram_bot_token']}/sendMessage"
    data = {
        "chat_id": config["chat_id"],
        "text": message
    }
    requests.post(url, data=data)

def check_traffic_and_notify(config):
    used_gb = get_current_month_usage()
    print(f'Already used: {used_gb} GB')
    if used_gb is not None and used_gb > config["monthly_limit_gb"]:
        send_telegram_message(f"Attention: Monthly traffic limit exceeded. Used: {used_gb:.2f} GB", config)

config = load_config()

schedule.every().day.at("00:01").do(log_initial_traffic_usage)
schedule.every(15).seconds.do(check_traffic_and_notify, config)

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

总结

有了 vnstat 就可以自己写脚本来定时完成流量监控,比如在 AWS 上,如果发现流量超出了阈值,可以写 Telegram Bot 通知,也可以直接禁用相关的端口。


2018-03-26 linux , vnstat , network , bandwidth , traffic

Jigsaw Outline 部署和使用

官方主页: https://getoutline.org/en/home 项目地址: https://github.com/Jigsaw-Code

Outline 细分有三部分,分别是 Outline Manager, Outline Server 和 Outline Client。

  • Outline Manager:方便用户管理所有的 Outline Server,可以使用图形化界面快捷部署 Outline Server ,然后为每一位用户生成连接秘钥,使得用户可以安全连接 Outline Server 。
  • Outline Server:用来提供安全代理的服务,响应、验证 Outline Client 的所有请求,仅此而已。
  • Outline Client:用来向 Outline Server 发起请求,或接受其返回的数据,仅此而已。

部署服务端

在安装 Docker 之后安装

wget -qO- https://raw.githubusercontent.com/Jigsaw-Code/outline-server/master/src/server_manager/install_scripts/install_server.sh | bash

在脚本安装结束后会生成一段配置,复制并保存该配置,在客户端配置中需要使用。

客户端使用

先下载 Outline Manager,地址

https://github.com/Jigsaw-Code/outline-releases

下载其中的 Outline-Manager.AppImage ,这是 Linux 下的客户端,不同系统中下载不同客户端。然后在 Manager 中粘贴上面服务端配置,完成 Manager 配置。然后在 Manager 中点击 ADD KEY 生成可用的 KEY。点击分享将生成一个托管在 Amazon S3 上的静态网页,其中有 Shadowsocks 客户端的配置,将该字符串发送给客户端即可。

然后再下载 client 客户端,目前暂时 Jigsaw 还没提供 iOS 和 Mac 版本,但是 Windows 和 Android 客户端可以在 GitHub 和 Play Store 链接 找到。

在手机上输入上面 Manager 生成的 SS 配置即可连接。安装配置过程将 Shadowsocks 的部署配置流程完全简化了。期待Google Jigsaw 能够将这个项目继续维护下去吧。


2018-03-26 linux , docker , socks , google , vpn

使用 Python 下载抖音无水印视频

抖音 APP 中保存到本地就是无水印版本的,所以头条的服务器肯定是保存有无水印版本的抖音视频的,所以只要找到接口地址就可以搞定。先在网上搜罗了一圈,确实有人已经做了解析,还提供了收费解析服务

搜索之后发现又发现了同类型的其他

  • http://douyin.iiilab.com/
  • http://www.dyapp.cc/
  • https://app886.cn/douyin_video

分析接口

分析这几个页面就会发现他们通过分享的链接就能够拿到视频的直接链接肯定是通过接口获取的,所以通过 Android 抓包能找到类似下面的接口

https://aweme.snssdk.com/aweme/v1/play/?
video_id=v0200fd80000bejku38697aj8tin1brg
&line=0
&ratio=720p
&watermark=1
&media_type=4
&vr_type=0
&test_cdn=None
&improve_bitrate=0
&version_code=270

这个请求返回状态码是 302,返回的 response header 中 Location 标示了该视频的真实地址。

后来分析抖音的 Feed 流设计,又发现了另外一个接口

https://api.amemv.com/aweme/v1/play/?video_id=v0200fd80000bejhsoir863vmi5add60&line=0&ratio=720p&media_type=4&vr_type=0&test_cdn=None&improve_bitrate=0

也类似于上面的接口不过域名不同,参数也类似。

入手

入手的几个页面,分享页

https://www.iesdouyin.com/share/video/6604280853952466190/?region=CN&mid=6601014204340275975&u_code=df31b2ff&titleType=title
http://v.douyin.com/dqv3dv/

第二条是短链接,展开就是上面的长链接了。

在分享页面获取视频的 id,然后使用上面的链接获取视频的播放地址。

大致的思路如下

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import re
from urllib.request import urlopen

import requests
from tqdm import tqdm


class DouyinVideoInfo:
    def __init__(self, vid, title='', nickname=''):
        self.video_id = vid
        self.title = title
        self.nickname = nickname


def download(url, filename, name):
    """
    :param url: 视频直接链接
    :param filename: 保存文件名
    :param name: 进度条内容
    :return:
    """
    file_size = int(urlopen(url).info().get('Content-Length', -1))

    if os.path.exists(filename):
        first_byte = os.path.getsize(filename)
    else:
        first_byte = 0
    if first_byte >= file_size:
        return file_size
    header = {"Range": "bytes=%s-%s" % (first_byte, file_size),
              'User-Agent': 'okhttp/3.10.0.1'}
    pbar = tqdm(total=file_size, initial=first_byte,
                unit='B', unit_scale=True,
                desc=name)
    req = requests.get(url, headers=header, stream=True)
    with(open(filename, 'wb')) as f:
        for chunk in req.iter_content(chunk_size=1024):
            if chunk:
                f.write(chunk)
                pbar.update(1024)
    pbar.close()
    return file_size


def down_by_vid(info: DouyinVideoInfo):
    r = requests.get('https://api.amemv.com/aweme/v1/play/', params={
        'video_id': info.video_id,
        'line': 0,
        'ratio': '720p',
        'watermark': 0,
        'media_type': 4,
        'vr_type': 0,
        'test_cdn': 'None',
        'improve_bitrate': 0,
        'logo_name': 'aweme'
    }, headers={
        'Host': 'api.amemv.com',
        'sdk-version': '1',
        'X-SS-TC': '0'
    }, allow_redirects=False)
    print(r.headers['Location'])
    download(r.headers['Location'], '{}.mp4'.format(info.video_id), info.title)


def get_video_info(long_url) -> DouyinVideoInfo:
    Headers = {
        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'zh-CN,zh;q=0.9',
        'cache-control': 'max-age=0',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; MI 4S Build/LMY47V) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/53.0.2785.146 Mobile Safari/537.36 XiaoMi/MiuiBrowser/9.1.3',
    }
    r = requests.get(long_url, headers=Headers)
    video_id = re.findall("(?<=video_id=).+?(?=&amp)", r.text)[0]
    title_name = re.findall("(?<=desc\">).+?(?=</p>)", r.text)[0]
    nick_name = re.findall("(?<=bottom-user\">).+?(?=</p>)", r.text)[0]
    info = DouyinVideoInfo(video_id, title_name, nick_name)
    return info


if __name__ == '__main__':
    d1 = 'https://www.iesdouyin.com/share/video/6604280853952466190/?region=CN&mid=6601014204340275975&u_code=df31b2ff&titleType=title'
    d2 = 'https://www.douyin.com/share/video/6536906252729978119/?region=CN&mid=6441083920867035918&titleType=title&timestamp=1522052360&utm_campaign=client_share&app=aweme&utm_medium=ios&iid=27151889375&utm_source=copy'
    info = get_video_info(d2)
    down_by_vid(info)

2018-03-25 douyin , 抖音 , python

使用 netlify 托管静态网站

netlify 是一个提供静态网站托管的服务,提供 CI 服务,能够将托管 GitHub,GitLab 等网站上的 Jekyll,Hexo,Hugo 等静态网站。

Netlify is a unified platform that automates your code to create high-performant, easily maintainable sites and web apps.

Netlify 有如下的功能:

  • 能够托管服务,免费 CDN
  • 能够绑定自定义域名,支持 SSL 证书
  • 支持自动构建
  • 提供 Webhooks 和 API

使用

Netlify 的使用非常直观和简单,和网站的自我介绍和定位一样简答,使用 GitHub 登录,然后获取公开项目的授权,让其获取源码,然后指定编译命令,比如我的网站使用 Jekyll,那么编译命令就是

jekyll build

将生成的静态网站放到

_site

这个目录下,接下来的事情就是等着 Netlify 自动编译部署,默认情况下 Netlify 会分配一个随机的子域名 https://《随机字符》.netlify.com 这样的地址,可以在设置中设置为自己想要的域名,或者在设置中绑定自己的域名。

那接下来就是 Netlify 会在每一次提交 commit 时自动编译部署静态网站。最后来访问下 https://blog.einverne.info

联想

同类型的静态网站托管服务, GitHub Page 原生支持,绝大部分常用的功能 GitHub Page 也都支持,不过是 GitHub 在国内的访问一般。另外 Pancake.io 可以将 Dropbox 中的静态内容映射成网站也同样支持绑定域名,Postach.io 能够将 Evernote 作为 blog 发布的源。

其他一些同类型的服务,now 同样能够托管静态网站,不过也支持托管 Node.js。Firebase Hosting 随同 Firebase 一同提供,更加推荐作为产品介绍静态页面来托管,不要将其作为博客内容托管。Surge 静态网站托管,支持命令行上传代码。


2018-03-24 github , git , ci , website

Linux 下使用命令获取硬盘信息

本文主要是一些和硬盘相关的命令,包括如何查看硬盘的型号,容量,还有硬盘上的分区情况,来详细了解本机硬盘的状态。

hdparm

如果想要在 Linux 下查看硬盘信息,可以使用命令 hdparm 。这个命令可以用来查看硬盘制造商,序列号等等有用信息。man hdparm 中告诉我, hdparm 命令是用来查看或者设置 SATA/IDE 设备参数的。

查看设备信息

假设本地有设备 /dev/sda 那么可以使用

hdparm -I /dev/sda

来查看该设备的信息

/dev/sda:

ATA device, with non-removable media
        Model Number:       Netac SSD  240G
        Serial Number:      5002B725438XXXX
        Firmware Revision:  O1217A
        Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0
Standards:
        Supported: 9 8 7 6 5
        Likely used: 9
Configuration:
        Logical         max     current
        cylinders       16383   16383
        heads           16      16
        sectors/track   63      63
        --
        CHS current addressable sectors:   16514064
        LBA    user addressable sectors:  268435455
        LBA48  user addressable sectors:  468862128
        Logical  Sector size:                   512 bytes
        Physical Sector size:                   512 bytes
        Logical Sector-0 offset:                  0 bytes
        device size with M = 1024*1024:      228936 MBytes
        device size with M = 1000*1000:      240057 MBytes (240 GB)
        cache/buffer size  = unknown
        Nominal Media Rotation Rate: Solid State Device
Capabilities:
        LBA, IORDY(can be disabled)
        Queue depth: 32
        Standby timer values: spec'd by Standard, no device specific minimum
        R/W multiple sector transfer: Max = 2   Current = 2
        DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6
             Cycle time: min=120ns recommended=120ns
        PIO: pio0 pio1 pio2 pio3 pio4
             Cycle time: no flow control=120ns  IORDY flow control=120ns
Commands/features:
        Enabled Supported:
           *    SMART feature set
                Security Mode feature set
           *    Power Management feature set
           *    Write cache
           *    Look-ahead
           *    Host Protected Area feature set
           *    WRITE_BUFFER command
           *    READ_BUFFER command
           *    NOP cmd
           *    DOWNLOAD_MICROCODE
                SET_MAX security extension
           *    48-bit Address feature set
           *    Device Configuration Overlay feature set
           *    Mandatory FLUSH_CACHE
           *    FLUSH_CACHE_EXT
           *    SMART error logging
           *    SMART self-test
           *    General Purpose Logging feature set
           *    WRITE_{DMA|MULTIPLE}_FUA_EXT
           *    {READ,WRITE}_DMA_EXT_GPL commands
           *    Segmented DOWNLOAD_MICROCODE
           *    Gen1 signaling speed (1.5Gb/s)
           *    Gen2 signaling speed (3.0Gb/s)
           *    Gen3 signaling speed (6.0Gb/s)
           *    Native Command Queueing (NCQ)
           *    Host-initiated interface power management
           *    Phy event counters
           *    READ_LOG_DMA_EXT equivalent to READ_LOG_EXT
           *    DMA Setup Auto-Activate optimization
                Device-initiated interface power management
           *    Software settings preservation
                Device Sleep (DEVSLP)
           *    SMART Command Transport (SCT) feature set
           *    SCT Write Same (AC2)
           *    SCT Features Control (AC4)
           *    SCT Data Tables (AC5)
           *    DOWNLOAD MICROCODE DMA command
           *    WRITE BUFFER DMA command
           *    READ BUFFER DMA command
           *    Data Set Management TRIM supported (limit 8 blocks)
           *    Deterministic read ZEROs after TRIM
Security:
        Master password revision code = 65534
                supported
        not     enabled
        not     locked
                frozen
        not     expired: security count
                supported: enhanced erase
        2min for SECURITY ERASE UNIT. 2min for ENHANCED SECURITY ERASE UNIT.
Device Sleep:
        DEVSLP Exit Timeout (DETO): 40 ms (drive)
        Minimum DEVSLP Assertion Time (MDAT): 31 ms (drive)
Checksum: correct

测试读取速度

hdparm 提供了一个简单的读速度测试参数

hdparm -Tt /dev/sda

结果

/dev/sda:
 Timing cached reads:   25572 MB in  2.00 seconds = 12798.56 MB/sec
 Timing buffered disk reads: 800 MB in  3.01 seconds = 266.08 MB/sec

能够看到 2 秒内读取了 25572M 缓存,而在 3 秒内从磁盘上物理读 800M 数据。

fdisk

fdisk 主要用来查看和修改硬盘分区表,它能够识别 GPT,MBR,BSD 等等分区表。设备可以被划分为一个或者若干逻辑磁盘,这些逻辑磁盘叫做分区。这些分区信息被包含在分区表 (partition table) 中,通常在硬盘的 sector 0 中保存。

设备名通常叫做 /dev/sda/dev/sdb 等等,设备的名字通常指整块硬盘,分区名字通常是设备名后面加上分区的序号,比如 /dev/sda1 表示的是第一块硬盘上的一个分区。详细的信息可以在 Linux kernel 文档 Documentation/devices.txt 文件中找到。

GPT

GPT 的全称是 GUID Partition Table,全局唯一标识分区表,指的是一个实体硬盘的分区表结构布局标准1 GPT 使用 64 bit 逻辑块地址。

MBR

MBR 全称为 Master Boot Record,主引导扇区, DOS type。Sector 0 是被 4 个主分区 primary partition 描述占用的,逻辑分区 (Logical partition) 从序号 5 开始。

如果要查看硬盘的分区情况,可以使用 fdisk

fdisk -l

结果

Disk /dev/loop0: 81.7 MiB, 85692416 bytes, 167368 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop1: 81.7 MiB, 85639168 bytes, 167264 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop2: 81.6 MiB, 85549056 bytes, 167088 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/sda: 223.6 GiB, 240057409536 bytes, 468862128 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x5ad18deb

Device     Boot Start       End   Sectors   Size Id Type
/dev/sda1          63 468862127 468862065 223.6G 83 Linux


Disk /dev/sdb: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x29049925

Device     Boot      Start        End    Sectors   Size Id Type
/dev/sdb1  *            63  629153594  629153532   300G  7 HPFS/NTFS/exFAT
/dev/sdb2        629153656 1953523711 1324370056 631.5G  f W95 Ext'd (LBA)
/dev/sdb5        629153658 1153466999  524313342   250G  7 HPFS/NTFS/exFAT
/dev/sdb6       1153467063 1782588464  629121402   300G  7 HPFS/NTFS/exFAT
/dev/sdb7       1782589440 1798213631   15624192   7.5G 82 Linux swap / Solaris
/dev/sdb8       1798215680 1953523711  155308032  74.1G 83 Linux

Partition 1 does not start on physical sector boundary.
Partition 5 does not start on physical sector boundary.
Partition 6 does not start on physical sector boundary.


Disk /dev/sdc: 119.2 GiB, 128035676160 bytes, 250069680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x326f11b9

Device     Boot     Start       End   Sectors   Size Id Type
/dev/sdc1  *           63 248346992 248346930 118.4G  7 HPFS/NTFS/exFAT
/dev/sdc2       248348672 250066943   1718272   839M 27 Hidden NTFS WinRE

dd

dd 工具是一个专业的测试工具,对测试结果要求不高,可以用来做 IO 读写的简单评估。首先要了解两个特殊设备:

/dev/null 伪设备,回收站。写该文件不会产生 IO
/dev/zero 伪设备,会产生空字符流,对它不会产生 IO

dd 命令使用:

dd if=/dev/zero of=/tmp/test bs=1G count=1 oflag=dsync
  • if 用来设置 dd 命令读取的输入文件名
  • of dd 输出文件名
  • bs 设置 dd 命令读取的块大小
  • count dd 命令读取的块个数
  • oflag=dsync 使用同步 I/O 去除 caching 影响

综上

测试硬盘写速度

sync; dd if=/dev/zero of=tempfile bs=1M count=1024; sync

测试磁盘读速度

dd if=tempfile of=/dev/null bs=1M count=1024

GUI

同样在 Linux 下也可以使用 GUI 图形化的工具来查看,搜索菜单 Disks,然后就能查看当前电脑安装的硬盘了。

查看分区

使用命令 lsblk 查看。

  1. https://en.wikipedia.org/wiki/GUID_Partition_Table 


2018-03-24 linux , hard-drive , ssd

每天学习一个命令:ncdu 磁盘分析工具

最近想把机械硬盘换成 SSD,然后使用 du -h 查看了一下本地硬盘使用,发现用了180多G,想要清理一下废弃的大文件,然后就发现了这个非常好用的磁盘管理工具 ncdu。 Ubuntu 源下有这个软件,可以直接使用命令安装:

sudo apt install ncdu

使用

终端下直接使用 ncdu ,然后工具就会直接扫描当前目录,并且按照文件及文件夹占用大小,从大到小排列,例如:

   22.2 GiB [#####     ] /Documents
   16.2 GiB [###       ] /.local
.  13.7 GiB [###       ] /.cache
   10.9 GiB [##        ] /.m2
   10.8 GiB [##        ] /Dropbox
    9.8 GiB [##        ] /Git
    3.2 GiB [          ] /.IntelliJIdea2016.3
    2.2 GiB [          ] /.pyenv
    1.4 GiB [          ] /.IdeaIC2016.3
    1.3 GiB [          ] /.wiznote

在界面中按下 ? 就会发现很多快捷键

┌───ncdu help─────────────────1:Keys───2:Format───3:About──┐
│                                                          │
│       up, k  Move cursor up                              │
│     down, j  Move cursor down                            │
│ right/enter  Open selected directory                     │
│  left, <, h  Open parent directory                       │
│           n  Sort by name (ascending/descending)         │
│           s  Sort by size (ascending/descending)         │
│           C  Sort by items (ascending/descending)        │
│           d  Delete selected file or directory           │
│           t  Toggle dirs before files when sorting       │
│           g  Show percentage and/or graph                │
│                        -- more --                        │
│                                         Press q to close │
└──────────────────────────────────────────────────────────┘

看到这个快捷键,就可以疯狂的使用d 来删除不再使用的大文件了。

最后开心的按下 q 退出。


2018-03-23 linux , ubuntu , ncdu , disk

使用 clonezilla 备份和恢复

Clonezilla 是一个分区和硬盘镜像和克隆的工具。Clonezilla 能够实现硬盘到硬盘,分区到分区的快速拷贝,在备份文件,克隆系统的应用中有着非常高的性能。使用起来也非常的方便,因此平时都保留着一个 8G U 盘制作的 Clonezilla 可以启动 U 盘。

Clonezilla is a partition and disk imaging/cloning program

下载地址: http://clonezilla.org/downloads.php

之前其实写过一篇克隆系统的文章 这里再系统性的总结一下。

制作 U 盘启动

制作一个 bootable Clonezilla 非常简单,在官网现在 iso 镜像之后,使用镜像写入工具就可以制作可以启动的 Clonezilla。在 Windows 下可以使用 Universal usb installer,或者 unetbootin,Linux 下使用 etcher。几乎都是加载 iso,选择写入设备,写入的过程比较简单,就不展开具体教程了。

备份流程

使用制作好的 U 盘启动,需要调整 PC 启动顺序,然后进入 clonezilla 系统,在 Clonezilla 中可以选择硬盘到硬盘复制,分区到分区复制,还有网络的备份,SSH 的备份,这些不怎么常用就暂时省略,主要使用硬盘到硬盘的备份和分区到分区的备份。

在具体的使用过程中遇到了一系列的问题,比如 Clonezilla 中无法找到新加的磁盘,比如如何将大容量的分区拷贝到小容量的分区中。不过这些问题都一一得到了解决。下面就讲下这些问题的解决方案。

Clonezilla 无法找到新加的磁盘

在电脑上直接插上新的 SSD,有可能默认情况下新的 SSD 没有分区,磁盘上也没有新建的分区表。这个时候 Clonezilla 就无法在分区到分区的拷贝中找到新的磁盘的分区。因此需要使用 Live boot 的 Linux mint U 盘启动,在 U 盘启动的 Linux 中使用 GParted 来针对新的磁盘进行分区。一般情况下直接划分一个系统分区就足够了。

划分分区的时候可能会遇到 MBR(Master Boot Record) 和 GPT(GUID Partition Table) 这样两个分区表的名词,这两个都是硬盘分区表的格式,不过一老一新。

MBR 主引导记录,是传统的分区机制,MBR 支持 32 位或者 64 位系统,但是支持的分区数量有限,并且不支持超过 2T 的硬盘。

GPT 是全局唯一标识分区表,是一个新的分区机制,解决了 MBR 很多缺点。支持大于 2T 的磁盘,fdisk 命令最大只能建立 2T 分区,需要使用 parted 命令来创建大于 2T 的分区。GPT 向后兼容 MBR,必须在支持 UEFI 的硬件上才能使用。

可以使用

sudo parted /dev/sdb print

来查看 sdb 这块硬盘上的分区表。关于 parted 命令更多的介绍,可以参考这篇文章

如果使用 GUI,那么在 U 盘启动的 Linux 中使用 GParted 可以直接对硬盘进行分区,然后应用即可,当新硬盘有分区时,Clonezilla 就能够找到分区并将原先的分区克隆到新的分区中了。

将大容量 HDD 拷贝到小容量的 SSD

Clonezilla 只能够将小的分区复制到大的分区中,因此会面临一个大问题。比如有一块 1T 的机械硬盘,需要将其中的一个 500g 的分区克隆到 250G 的 SSD 中,那么就需要先将 500G 的分区缩小到 250G 以下。查看当前 500G 系统分区实际文件占用大小,实际使用量一定要小于 250G,删除无用文件将实际占用文件缩小到 250G 以下之后,可能需要一个可以启动的 Linux live CD,一般情况下我也会制作一个 Linux Mint 的可启动 U 盘,然后启动该 U 盘,在 Linux Mint 中,使用 GParted 调整需要克隆的分区大小,将分区调整到 250G 以下。搜索关键词 shrink partition。缩小分区操作可能因不同硬盘和文件占用而不同耗时,一般情况下也需要非常长时间的操作。

在缩小分区之后,就可以启动 Clonezilla 然后使用分区到分区的操作,将原先 HDD 上的系统分区拷贝到 SSD 的分区中。拷贝也是一个非常耗时的操作,等待拷贝完成,这样系统就在原来分区和 SSD 上各有一份拷贝了。

由于 Clonezilla 在拷贝时是原样复制,因此可能导致 Linux 分区的 UUID 也一模一样,因此需要根据这篇文章 来修改 Linux 分区的 UUID。

接下来的事情就是修改引导,让电脑启动到 SSD 中的系统。

这里就要推荐一个软件 boot-repair

sudo add-apt-repository ppa:yannubuntu/boot-repair
sudo apt-get update
sudo apt-get install -y boot-repair && boot-repair

需要在 Live boot 的 Linux mint 中启动 boot-repair 来修复确实的引导。然后开机启动新硬盘上的系统就 OK 了。

reference


2018-03-23 clonezilla , tutorial , backup , restore , system , ssd , linux

Trello 类似的工具和应用整理

Trello 是这一年来我发现的为数不多非常好用,并且一直用到现在“好”应用,然而上个礼拜在工作的时候收到一份邮件,是一个内部使用的效率工具,点开一看竟然发现是和 Trello 类似的一个内部规划和管理工具,那个时候就是萌生了写下这样一篇文章的想法。说实话经过一番搜索和调查整理之后发现 Trello 类似的项目真的很多,商业化的,非商业化的,开源的,闭源的,不过追根溯源看板这个概念也并不是 Trello 首创,这个概念本来就来自日本,已经经过多年的实践证明过了的。

KanbanFlow

接触 KanbanFlow 是在《[[软技能]]》这本书中,作者也使用 Trello 和 KanbanFlow 来管理自己的待办,KanbanFlow 优于 Trello 的一点是自带了 Pomodoro 番茄时钟。

Teambition

这是国内团队做的,看官网是主攻企业和大客户,为公司等等提供定制化服务。

我简单的使用了一下 Teambition 的个人版,主要的流程和 Trello 并没有什么大的差异,甚至大体功能都比不上 Trello,比如不能附加图片等等,不过界面很清爽,好的一点是他自带模板功能,Trello 早期让我无法适从的一点就是,进去以后光秃秃,虽然他也有模板,但是对于一个初用者,如果有不同种类的模板给予选择,肯定可以更好的使用起来,虽然熟悉之后可能自己手动根据自己的需求创建相应的项目要来的更加自由,但是初期模板确实给了一个清晰地方向,你可以用来管理 TODO,可以用来指定旅行计划,可以用来管理读书笔记,更加甚至给公司用可以用来管理 OKR,可以用来制定需求池,可以用来管理敏捷开发,用来管理项目进度等等等等。

teambition 模板

Screenshot from 2018-05-19 10-54-15

Screenshot from 2018-05-19 10-56-11

wekan

开源版本的 Trello

如果考虑到隐私问题,可以用来私有托管。并且在他们发布的 1.0 版本 中,增加了 Snap, Docker, VirtualBox, 等等快捷安装的方式。

如果想要在线尝试一下,可以访问这里:https://oasis.sandstorm.io/demo

在安装 Ubuntu Server 18.04 的时候再一次看到 wekan,然后就顺手体验了一下,虽然外观和 Trello 比起来还是有些距离,但是功能上是已经能够满足日常 90% 的需求了。而 Open Source 最棒的就是,如果用着不开心了,自己干。

当然客观上来讲,目前 (2020 年) Trello 在第三方 API 和界面上还是领先与 Wekan 的,但谁能知道 5 年,10 年后呢。

Notion

单独写了一篇文章,开始的时候竟然漏掉了。

其他

下面几个也都大同小异,大家都主打团队协作工具,效率工具,看使用的方式吧,好的工具确实能够提高效率,但却也不能因为好的工具而浪费时间。

  • https://tower.im/
  • https://clickup.com
  • https://airtable.com

2018-03-19 trello , kanban , board , application

VPS 安全设置

以前也写过一篇文章叫做购买 VPS 之后需要做的事情 其中也提到了一些安全设置来确保 VPS 的安全性,但是那篇文章更多的集中于设置和配置。那这篇文章就集中总结归纳一下需要特别注意的安全问题。

保持系统更新

经常检查系统更新,尤其是出现重大安全问题时一定更新到最新的系统,以 Debian/Ubuntu/LinuxMint 为例

apt-get update
apt-get upgrade

SSH 端口和登录

SSH 默认使用 22 端口,我们和 VPS 打交道用的最多的就是这一个端口,修改 /etc/ssh/sshd_configPort 的设置,修改为其他端口,然后使用

ssh -p <the port you set> name@server.ip

来指定端口访问,虽然修改为非默认端口也避免不了被扫描出来,但概率要稍微低一点。

推荐使用公钥、私钥来登录 VPS,在本机 ssh-copy-id name@server.ip 将本地公钥拷贝 到远程 ~/.ssh/authorized_keys 文件中

禁止 root 账户 SSH 登录

限制 root 账户登录 SSH 同理,修改 /etc/ssh/sshd_configPermitRootLogin 值改为 no。注意之前先新建可用账户,然后再禁用 root 登录。

adduser [nickname_you_want]
adduser [nickname_you_want] sudo        # 或者 visudo

禁止密码登录

通过上面的命令生成公私钥之后,可以取消密码登录,编辑 /etc/ssh/sshd_config 然后修改:

PasswordAuthentication no

然后重启 ssh 服务:

sudo /etc/init.d/ssh restart

开启登录失败次数

/etc/ssh/sshd_config 中增加:

MaxAuthTries 6

然后重启 ssh。

禁用 ping

不响应 ping,修改 /proc/sys/net/ipv4/icmp_echo_ignore_all 文件,0 为允许,1 为禁止

# 禁止 ping
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
# 允许 ping
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

限制账号多重登录

编辑 /etc/security/limits.conf 添加配置:

*               hard    maxlogins       2

安装 fail2ban

Fail2ban 是一个能够保护 SSH 等常用端口暴力破解的工具

sudo apt install fail2ban

项目的配置地址在 /etc/fail2ban/ 目录下。

  • fail2ban.conf 文件是 fail2ban 软件配置,包括日志级别,日志位置,PID 等等
  • jail.conf 则是关于功能配置,包括默认禁止登录时间,允许重复登录次数,白名单,邮件等等

其中可以找到一个 jail.conf 的配置文件,该文件可能在升级时被覆盖,所以可以拷贝一份 cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local 来编辑 local 文件,fail2ban 配置文件优先级:

  • /etc/fail2ban/jail.conf
  • /etc/fail2ban/jail.d/*.conf,按字母顺序排列
  • /etc/fail2ban/jail.local
  • /etc/fail2ban/jail.d/*.local,按字母顺序排列

编辑 /etc/fail2ban/jail.local

[DEFAULT]
# "ignoreip" can be an IP address, a CIDR mask or a DNS host. Fail2ban will not
# ban a host which matches an address in this list. Several addresses can be
# defined using space separator.
ignoreip = 127.0.0.1/8 123.45.67.89

# "bantime" is the number of seconds that a host is banned.
bantime  = 31536000            ; 1 year

# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 600
maxretry = 3

更多的配置可以参考这篇文章

fail2ban 的日志可以在 /var/log/fail2ban.log 查看。

如何查看日志

当你发现服务器有异常请求时,如何查看服务器用户登录日志。首先查看当前服务器登录的用户

w

使用该命令可以查看当前连接在线的用户,然后使用

last

来查看过去一段时间的登录用户,包括登录用户名,登录 IP,登录时间,时长等等。如果发现异常等级即使处理。

然后检查 sudo less /var/log/auth.log 文件查看登录日志。

reference


2018-03-18 linux , vps , server , ssh , config , scan

电子书

本站提供服务

最近文章

  • 期权策略:Bull Call Spread Bull Call Spread,可以翻译成牛市看涨价差策略,这是一个期权交易策略。
  • 使用 Quartz 发布 Obsidian 笔记库 自从使用 [[Obsidian]] 以来就一直想要有一个开源版本的 [[Obsidian Publish]] 代替,过去这几年也尝试了不少方案,比如 Jekyll 静态网站生成,比如使用 [[Logseq]] 生成网站, 然后还想过从 Obsidian 同步到 Notion 里面,然后再使用 [[NotionNext]] 来生成网站。
  • 爱沙尼亚电子居民申请记录 在网上逛论坛的时候,偶然看到有人提到了一个爱沙尼亚电子公民的电子居民卡,看起来挺有意思的,之前就看到过 [[帕劳数字居民身份证]],去检索了一下发现帕劳已经涨价到了 248 欧元,爱沙尼亚电子公民感觉上类似,所以就简单的记录一下。
  • DNS 泄漏以及如何防止 什么是 DNS 泄漏
  • 从内地到香港出金最佳的方法 银行汇款