<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>ZFB</title>
    <description>这是我的个人主页</description>
    <link>https://whuzfb.cn/</link>
    <atom:link href="https://whuzfb.cn/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Wed, 01 Feb 2023 01:42:00 +0800</pubDate>
    <lastBuildDate>Wed, 01 Feb 2023 01:42:00 +0800</lastBuildDate>
    <generator>Jekyll v3.9.2</generator>
    
      <item>
        <title>使用ffmpeg对视频和音频文件进行处理</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#0-常用命令说明&quot; id=&quot;markdown-toc-0-常用命令说明&quot;&gt;0. 常用命令说明&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#1-倍速播放&quot; id=&quot;markdown-toc-1-倍速播放&quot;&gt;1. 倍速播放&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#11-视频画面倍速播放&quot; id=&quot;markdown-toc-11-视频画面倍速播放&quot;&gt;1.1 视频画面倍速播放&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#12-音频倍速播放&quot; id=&quot;markdown-toc-12-音频倍速播放&quot;&gt;1.2 音频倍速播放&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#13-视频画面和音频倍速播放&quot; id=&quot;markdown-toc-13-视频画面和音频倍速播放&quot;&gt;1.3 视频画面和音频倍速播放&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-视频片段裁剪&quot; id=&quot;markdown-toc-2-视频片段裁剪&quot;&gt;2. 视频片段裁剪&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#21-获取视频的分辨率&quot; id=&quot;markdown-toc-21-获取视频的分辨率&quot;&gt;2.1 获取视频的分辨率&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#22-截取指定时长的视频片段&quot; id=&quot;markdown-toc-22-截取指定时长的视频片段&quot;&gt;2.2 截取指定时长的视频片段&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#23-裁剪视频画面尺寸&quot; id=&quot;markdown-toc-23-裁剪视频画面尺寸&quot;&gt;2.3 裁剪视频画面尺寸&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-视频导出图片&quot; id=&quot;markdown-toc-3-视频导出图片&quot;&gt;3. 视频导出图片&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-从图片集创建gif文件&quot; id=&quot;markdown-toc-4-从图片集创建gif文件&quot;&gt;4. 从图片集创建GIF文件&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#5-提取视频文件的音频&quot; id=&quot;markdown-toc-5-提取视频文件的音频&quot;&gt;5. 提取视频文件的音频&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#6-把音频和画面合并为新的视频&quot; id=&quot;markdown-toc-6-把音频和画面合并为新的视频&quot;&gt;6. 把音频和画面合并为新的视频&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#7-下载m3u8文件为ts文件&quot; id=&quot;markdown-toc-7-下载m3u8文件为ts文件&quot;&gt;7. 下载m3u8文件为.ts文件&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#8-批量提取视频关键帧&quot; id=&quot;markdown-toc-8-批量提取视频关键帧&quot;&gt;8. 批量提取视频关键帧&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;0-常用命令说明&quot;&gt;0. 常用命令说明&lt;/h2&gt;
&lt;p&gt;ffmpeg是一个命令行工具，所有的操作都是通过命令行来完成的，下面是一些常用的命令说明&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-vcodec codec&lt;/code&gt;：强制使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;codec&lt;/code&gt;编解码方式（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copy&lt;/code&gt;代表不进行重新编码）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-acodec copy&lt;/code&gt;：表示音频不做新的编码，直接把原来的复制过来&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-vcodec copy&lt;/code&gt;：表示视频不做新的编码，直接把原来的复制过来&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-threads 5&lt;/code&gt;：指定&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt;个线程同时转换&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-vn&lt;/code&gt;：取消视频的输出&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-an&lt;/code&gt;：取消音频轨&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-ab 160000&lt;/code&gt;：设置比特率（单位为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bit/s&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-ar 8000&lt;/code&gt;：设置音频采样率（单位为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hz&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-ac 1&lt;/code&gt;：设置声道数，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;就是单声道，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2&lt;/code&gt;就是立体声&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-倍速播放&quot;&gt;1. 倍速播放&lt;/h2&gt;
&lt;h3 id=&quot;11-视频画面倍速播放&quot;&gt;1.1 视频画面倍速播放&lt;/h3&gt;
&lt;p&gt;把输入的视频文件，画面播放速度快放到原来的2倍，保存为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i input.mp4 -filter:v &quot;setpts=0.5*PTS&quot; output.mp4&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;12-音频倍速播放&quot;&gt;1.2 音频倍速播放&lt;/h3&gt;
&lt;p&gt;把输入的视频文件，音频播放速度快放到原来的2倍，保存为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i input.mp4 -filter:a &quot;atempo=2.0&quot; output.mp4&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;13-视频画面和音频倍速播放&quot;&gt;1.3 视频画面和音频倍速播放&lt;/h3&gt;
&lt;p&gt;把输入的视频文件，画面播放速度快放到原来的2倍，音频播放速度快放到原来的2倍，保存为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i input.mp4 -filter_complex &quot;[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]&quot; -map &quot;[v]&quot; -map &quot;[a]&quot; output.mp4&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-视频片段裁剪&quot;&gt;2. 视频片段裁剪&lt;/h2&gt;
&lt;h3 id=&quot;21-获取视频的分辨率&quot;&gt;2.1 获取视频的分辨率&lt;/h3&gt;
&lt;p&gt;方法一：获取视频的分辨率，以默认分隔符分割&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffprobe -v error -show_entries stream=width,height -of csv=p=0 demo.mp4&lt;/code&gt;&lt;br /&gt;
得到输出为： &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1920,1080&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;方法二：获取视频的分辨率，以&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;分隔符分割&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffprobe -v error -show_entries stream=width,height -of csv=p=0:s=x output2.mp4&lt;/code&gt;&lt;br /&gt;
得到输出为： &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1920x1080&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;22-截取指定时长的视频片段&quot;&gt;2.2 截取指定时长的视频片段&lt;/h3&gt;
&lt;p&gt;从视频文件中，截取时间从&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:00&lt;/code&gt;开始到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:11&lt;/code&gt;之间的片段，输出为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -ss 00:00:00 -to 00:00:11 -i input.mp4 -vcodec copy -acodec copy output.mp4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;从视频文件中，截取时间从&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:01:00&lt;/code&gt;开始，时长&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:21&lt;/code&gt;的片段，输出为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -ss 00:01:00 -t 00:00:21 -i input.mp4 -vcodec copy -acodec copy output2.mp4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;从视频文件中，截取时间从&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:00&lt;/code&gt;到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;00:00:11&lt;/code&gt;之间的片段，分辨率为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1920x1080&lt;/code&gt;，输出为新的视频文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -ss 00:00:00 -to 00:00:11 -i input.mp4 -vcodec copy -acodec copy -s 1920,1080 output.mp4&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;23-裁剪视频画面尺寸&quot;&gt;2.3 裁剪视频画面尺寸&lt;/h3&gt;
&lt;p&gt;参数示例：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crop=new_width:new_height:start_x:start_y&lt;/code&gt;&lt;br /&gt;
把原视频画面裁剪成宽高为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;400x200&lt;/code&gt;的新视频，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x&lt;/code&gt;的起始位置是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;（表示从该位置开始，向右&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;400&lt;/code&gt;的像素留下），&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;y&lt;/code&gt;的起始位置是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;（表示从该位置开始，向下&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;200&lt;/code&gt;的像素留下）。也就是说，最后留下的视频画面为原视频画面的一部分（以原视频画面的左上顶点为原点）&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i input.mp4 -vf crop=400:200:0:0 -threads 5 -preset ultrafast -strict -2 output.mp4&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;3-视频导出图片&quot;&gt;3. 视频导出图片&lt;/h2&gt;
&lt;p&gt;从视频文件中，以每秒&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3&lt;/code&gt;帧的速率抽取图片，并更改为指定长、宽，最后按照指定命名格式保存&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i demo.mp4 -r 3 -s 1920x1080 -f image2 ./demo-%03d.jpeg&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;4-从图片集创建gif文件&quot;&gt;4. 从图片集创建GIF文件&lt;/h2&gt;
&lt;p&gt;从图片集创建帧率为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;5&lt;/code&gt;的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GIF&lt;/code&gt;文件&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -f image2 -framerate 5 -i ./demo-%03d.jpeg out.gif&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;5-提取视频文件的音频&quot;&gt;5. 提取视频文件的音频&lt;/h2&gt;
&lt;p&gt;提取视频文件的音频内容保存为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mp3&lt;/code&gt;格式&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -i demo.mp4 -f mp3 -vn -ar 16000 -ac 1 demo.mp3&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;6-把音频和画面合并为新的视频&quot;&gt;6. 把音频和画面合并为新的视频&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -loglevel quiet -i video.m4s -i audio.m4s -c copy -y out.mp4&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;7-下载m3u8文件为ts文件&quot;&gt;7. 下载m3u8文件为.ts文件&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ffmpeg -protocol_whitelist file,http,https,tcp,tls -i https://t.cn/a.m3u8 -c copy my_movie.ts&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;8-批量提取视频关键帧&quot;&gt;8. 批量提取视频关键帧&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;shopt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; nullglob

&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;video_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;out_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;video_path&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# echo ${files[@]}&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# echo ${#files[@]}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;filename &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[@]&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;%.*&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Converting &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;file_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;out_path&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;file_dir&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# 获取视频分辨率（宽，高）&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# 例如： 1920,1080&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# export wh=ffprobe -v error -show_entries stream=width,height -of csv=p=0 &quot;${filename}&quot;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# 视频提取语音，方便识别&lt;/span&gt;
    ffmpeg &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; mp3 &lt;span class=&quot;nt&quot;&gt;-vn&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-ar&lt;/span&gt; 16000 &lt;span class=&quot;nt&quot;&gt;-ac&lt;/span&gt; 1 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;file_dir&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/audio.mp3&quot;&lt;/span&gt;
    &lt;span class=&quot;c&quot;&gt;# 视频关键帧提取，方便导出PPT&lt;/span&gt;
    ffmpeg &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-vf&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'eq(pict_type\,I)'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-vsync&lt;/span&gt; 2 &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; 1920,1080 &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; image2 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;file_dir&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/keyframe-%03d.png&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo &lt;/span&gt;Convert &lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt; successfully!
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 30 Dec 2022 22:59:00 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2022/12/30/ffmpeg-usage/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2022/12/30/ffmpeg-usage/</guid>
        
        <category>Windows</category>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        
        <category>Windows</category>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>修复Adobe Acrobat打开发票字体显示不全的问题</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#0-问题描述&quot; id=&quot;markdown-toc-0-问题描述&quot;&gt;0. 问题描述&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#1-复制系统楷体字体文件&quot; id=&quot;markdown-toc-1-复制系统楷体字体文件&quot;&gt;1. 复制系统楷体字体文件&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-修改字体名称&quot; id=&quot;markdown-toc-2-修改字体名称&quot;&gt;2. 修改字体名称&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-复制字体文件到acrobat字体目录&quot; id=&quot;markdown-toc-3-复制字体文件到acrobat字体目录&quot;&gt;3. 复制字体文件到Acrobat字体目录&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;0-问题描述&quot;&gt;0. 问题描述&lt;/h2&gt;
&lt;p&gt;Acrobat在2021.005.20060以后的新版本有bug，无法读取楷体GB2312字体，导致打开发票时，发票上的部分中文显示为方框或不显示&lt;/p&gt;

&lt;h2 id=&quot;1-复制系统楷体字体文件&quot;&gt;1. 复制系统楷体字体文件&lt;/h2&gt;
&lt;p&gt;文件资源管理器打开&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Windows\Fonts&lt;/code&gt;目录，找到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;楷体 常规&lt;/code&gt;字体文件，即文件&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Windows\Fonts\simkai.ttf&lt;/code&gt;，复制到其他目录，这样不会影响系统正常使用&lt;/p&gt;

&lt;h2 id=&quot;2-修改字体名称&quot;&gt;2. 修改字体名称&lt;/h2&gt;
&lt;p&gt;使用字体编辑工具FontCreator打开&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;simkai.ttf&lt;/code&gt;字体文件，选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Font-Properties&lt;/code&gt;打开属性修改，将&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Family Name&lt;/code&gt;修改为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KaiTi_GB2312&lt;/code&gt;，选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;File – Export Font – Export – Export Desktop Font&lt;/code&gt;导出字体，可以命名为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;simkai-new.otf&lt;/code&gt;，等待几分钟完成&lt;/p&gt;

&lt;h2 id=&quot;3-复制字体文件到acrobat字体目录&quot;&gt;3. 复制字体文件到Acrobat字体目录&lt;/h2&gt;
&lt;p&gt;将修改后的字体文件&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;simkai-new.otf&lt;/code&gt;复制到&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Program Files\Adobe\Acrobat DC\Resource\Font&lt;/code&gt;目录，重启Acrobat即可&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Dec 2022 20:03:15 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2022/12/28/adobe-acrobat-cn-char/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2022/12/28/adobe-acrobat-cn-char/</guid>
        
        <category>Windows</category>
        
        
        <category>Windows</category>
        
      </item>
    
      <item>
        <title>使用Python代码在Windows资源管理器中定位文件</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-安装pywin32&quot; id=&quot;markdown-toc-1-安装pywin32&quot;&gt;1. 安装pywin32&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-脚本文件内容&quot; id=&quot;markdown-toc-2-脚本文件内容&quot;&gt;2. 脚本文件内容&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-安装pywin32&quot;&gt;1. 安装pywin32&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;pywin32
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2-脚本文件内容&quot;&gt;2. 脚本文件内容&lt;/h2&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 'zfb'
# time: 2021-01-06 13:33
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pathlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;win32com.shell.shell&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shell&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;launch_file_explorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_with_abs_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;'''
    每次弹出文件资源管理器，只能打开一个文件夹，然后（定位）选择一个文件（夹）
    '''&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_with_abs_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 对于Linux系统来说
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;#    如果使用Unity/Gnome桌面，可以使用命令
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;#        nautilus ~/Documents/foo.txt
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;#    对于其他桌面系统，可参考 xdg-open 命令
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# 严格按照此格式，不能自己加空格
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'explorer.exe /e,/select,&quot;{}&quot;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;launch_files_explorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;'''
    每次弹出文件资源管理器，只能打开一个文件夹，可以选择多个文件（夹）
    '''&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;folder_pidl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHILCreateFromPath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;desktop&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHGetDesktopFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shell_folder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;desktop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BindToObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folder_pidl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IID_IShellFolder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name_to_item_mapping&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;desktop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetDisplayNameOf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shell_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;to_show&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_to_item_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;目录{}下找不到文件{}&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;to_show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_to_item_mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SHOpenFolderAndSelectItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;folder_pidl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to_show&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;abspath&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;D:/github/zfb132.github.com/&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;index.html&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;README.md&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;robots.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;launch_file_explorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;launch_files_explorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 27 Dec 2022 21:51:00 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2022/12/27/reveal-in-explorer/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2022/12/27/reveal-in-explorer/</guid>
        
        <category>Python</category>
        
        <category>Windows</category>
        
        
        <category>Python</category>
        
        <category>Windows</category>
        
      </item>
    
      <item>
        <title>使用git diff查看不同文件或者不同commit之间的区别</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-查看不同文件的区别&quot; id=&quot;markdown-toc-1-查看不同文件的区别&quot;&gt;1. 查看不同文件的区别&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-查看不同commit之间的修改&quot; id=&quot;markdown-toc-2-查看不同commit之间的修改&quot;&gt;2. 查看不同commit之间的修改&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-把diff的转换为html保存&quot; id=&quot;markdown-toc-3-把diff的转换为html保存&quot;&gt;3. 把diff的转换为html保存&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-ansi2htmlsh文件内容&quot; id=&quot;markdown-toc-4-ansi2htmlsh文件内容&quot;&gt;4. ansi2html.sh文件内容&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-查看不同文件的区别&quot;&gt;1. 查看不同文件的区别&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a.txt&lt;/code&gt;和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b.txt&lt;/code&gt;不在版本控制系统中：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git diff &lt;span class=&quot;nt&quot;&gt;--color-words&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-index&lt;/span&gt; a.txt b.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;2-查看不同commit之间的修改&quot;&gt;2. 查看不同commit之间的修改&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git diff &lt;span class=&quot;nt&quot;&gt;--color-words&lt;/span&gt; HEAD~4 HEAD~3
git diff &lt;span class=&quot;nt&quot;&gt;--color-words&lt;/span&gt; ac238c26 5d449a61
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;3-把diff的转换为html保存&quot;&gt;3. 把diff的转换为html保存&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 首先安装ansi2html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# https://github.com/pixelb/scripts/blob/master/scripts/ansi2html.sh&lt;/span&gt;
wget &lt;span class=&quot;s2&quot;&gt;&quot;http://www.pixelbeat.org/scripts/ansi2html.sh&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; ansi2html.sh
&lt;span class=&quot;nb&quot;&gt;chmod&lt;/span&gt; +x ansi2html.sh
git diff &lt;span class=&quot;nt&quot;&gt;--color-words&lt;/span&gt; HEAD~4 HEAD~3 | ansi2html.sh &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; docs/diff.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后可以用浏览器打开&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docs/diff.html&lt;/code&gt;查看，打印成pdf文件也可以&lt;/p&gt;

&lt;h2 id=&quot;4-ansi2htmlsh文件内容&quot;&gt;4. ansi2html.sh文件内容&lt;/h2&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Convert ANSI (terminal) colours and attributes to HTML&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Licence: LGPLv2&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Author:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    http://www.pixelbeat.org/docs/terminal_colours/&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Examples:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    ls -l --color=always | ansi2html.sh &amp;gt; ls.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    git show --color | ansi2html.sh &amp;gt; last_change.html&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    Generally one can use the `script` util to capture full terminal output.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Changes:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    V0.1, 24 Apr 2008, Initial release&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    V0.2, 01 Jan 2009, Phil Harnish &amp;lt;philharnish@gmail.com&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Support `git diff --color` output by&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         matching ANSI codes that specify only&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         bold or background colour.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                       P@draigBrady.com&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Support `ls --color` output by stripping&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         redundant leading 0s from ANSI codes.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Support `grep --color=always` by stripping&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         unhandled ANSI codes (specifically ^[[K).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    V0.3, 20 Mar 2009, http://eexpress.blog.ubuntu.org.cn/&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Remove cat -v usage which mangled non ascii input.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Cleanup regular expressions used.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Support other attributes like reverse, ...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                       P@draigBrady.com&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Correctly nest &amp;lt;span&amp;gt; tags (even across lines).&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Add a command line option to use a dark background.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Strip more terminal control codes.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    V0.4, 17 Sep 2009, P@draigBrady.com&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Handle codes with combined attributes and color.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Handle isolated &amp;lt;bold&amp;gt; attributes with css.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#                         Strip more terminal control codes.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#    V0.26, 16 Nov 2019&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#      http://github.com/pixelb/scripts/commits/master/scripts/ansi2html.sh&lt;/span&gt;

gawk &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--version&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'0.26\n'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;usage&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s\n'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'This utility converts ANSI codes in data passed to stdin
It has 4 optional parameters:
--bg=dark --palette=linux|solarized|tango|xterm --css-only|--body-only
E.g.: ls -l --color=always | ansi2html.sh --bg=dark &amp;gt; ls.html'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--help&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;usage
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;processArg&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--bg=dark&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;dark_bg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;yes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--css-only&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;css_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;yes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--body-only&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;body_only&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;yes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--palette=solarized&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
       &lt;span class=&quot;c&quot;&gt;# See http://ethanschoonover.com/solarized&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;073642&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;D30102&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;859900&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;B58900&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;268BD2&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;D33682&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;2AA198&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;EEE8D5&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;002B36&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CB4B16&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;586E75&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;657B83&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;P12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;839496&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;6C71C4&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P14&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;93A1A1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FDF6E3&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--palette=solarized-xterm&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
       &lt;span class=&quot;c&quot;&gt;# Above mapped onto the xterm 256 color palette&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;262626&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AF0000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5F8700&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AF8700&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0087FF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AF005F&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00AFAF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;E4E4E4&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;1C1C1C&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;D75F00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;585858&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;626262&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;P12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;808080&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5F5FAF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P14&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;8A8A8A&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FFFFD7&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--palette=tango&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
       &lt;span class=&quot;c&quot;&gt;# Gnome default&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;000000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CC0000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4E9A06&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;C4A000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;3465A4&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;75507B&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;06989A&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;D3D7CF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;555753&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;EF2929&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;8AE234&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FCE94F&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;P12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;729FCF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AD7FA8&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P14&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;34E2E2&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;EEEEEC&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--palette=xterm&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
       &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;P0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;000000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CD0000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00CD00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CDCD00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0000EE&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;CD00CD&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00CDCD&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;E5E5E5&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;7F7F7F&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FF0000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00FF00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FFFF00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;P12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5C5CFF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FF00FF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P14&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00FFFF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FFFFFF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;c&quot;&gt;# linux console&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;000000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AA0000&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00AA00&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AA5500&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0000AA&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AA00AA&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;00AAAA&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;AAAAAA&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
       &lt;span class=&quot;nv&quot;&gt;P8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;555555&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;nv&quot;&gt;P9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FF5555&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;55FF55&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P11&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FFFF55&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;P12&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5555FF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P13&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FF55FF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P14&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;55FFFF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;P15&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;FFFFFF&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--palette=linux&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

processArg &lt;span class=&quot;c&quot;&gt;#defaults&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;var &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$@&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;processArg &lt;span class=&quot;nv&quot;&gt;$var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$css_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; usage

&lt;span class=&quot;c&quot;&gt;# Mac OSX's GNU sed is installed as gsed&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# use e.g. homebrew 'gnu-sed' to get it&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  if &lt;/span&gt;gsed &lt;span class=&quot;nt&quot;&gt;--version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;alias sed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;gsed
  &lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Error, can't find an acceptable GNU sed.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
  &lt;span class=&quot;k&quot;&gt;fi
fi&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$css_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s'&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta http-equiv=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Content-Type&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; content=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text/html; charset=utf-8&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&amp;gt;
&amp;lt;style type=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text/css&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;
pre { white-space: pre-wrap; }
&quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.ef0,.f0 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb0,.b0 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef1,.f1 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb1,.b1 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef2,.f2 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb2,.b2 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef3,.f3 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P3&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb3,.b3 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P3&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef4,.f4 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P4&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb4,.b4 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P4&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef5,.f5 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P5&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb5,.b5 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P5&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef6,.f6 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P6&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb6,.b6 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P6&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef7,.f7 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P7&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; } .eb7,.b7 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P7&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.ef8, .f0 &amp;gt; .bold,.bold &amp;gt; .f0 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P8&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef9, .f1 &amp;gt; .bold,.bold &amp;gt; .f1 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P9&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef10,.f2 &amp;gt; .bold,.bold &amp;gt; .f2 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P10&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef11,.f3 &amp;gt; .bold,.bold &amp;gt; .f3 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P11&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef12,.f4 &amp;gt; .bold,.bold &amp;gt; .f4 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P12&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef13,.f5 &amp;gt; .bold,.bold &amp;gt; .f5 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P13&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef14,.f6 &amp;gt; .bold,.bold &amp;gt; .f6 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P14&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.ef15,.f7 &amp;gt; .bold,.bold &amp;gt; .f7 { color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P15&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; font-weight: normal; }
.eb8  { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P8&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb9  { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P9&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb10 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P10&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb11 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P11&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb12 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P12&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb13 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P13&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb14 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P14&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
.eb15 { background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P15&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; }
&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The default xterm 256 colour palette&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;red &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0 1 2 3 4 5 &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  for &lt;/span&gt;green &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0 1 2 3 4 5 &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
    for &lt;/span&gt;blue &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0 1 2 3 4 5 &lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$red&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$green&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$blue&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$red&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$red&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$green&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$green&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;nv&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$blue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;40&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$blue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.ef%d { color: #%2.2x%2.2x%2.2x; } &quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$g&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.eb%d { background-color: #%2.2x%2.2x%2.2x; }&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$r&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$g&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$b&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;done
  done
done
for &lt;/span&gt;gray &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;seq &lt;/span&gt;0 23&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$gray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;232&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$gray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;))&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.ef%d { color: #%2.2x%2.2x%2.2x; } &quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;.eb%d { background-color: #%2.2x%2.2x%2.2x; }&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$c&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$l&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'
.f9 { color: '&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dark_bg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P7&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' }
.b9 { background-color: #'&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dark_bg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$P15&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'; }
.f9 &amp;gt; .bold,.bold &amp;gt; .f9, body.f9 &amp;gt; pre &amp;gt; .bold {
  /* Bold is heavy black on white, or bright white
     depending on the default background */
  color: '&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dark_bg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P15&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;#&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'
  font-weight: '&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dark_bg&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'normal;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'bold;'&lt;/span&gt;&lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'
}
.reverse {
  /* CSS does not support swapping fg and bg colours unfortunately,
     so just hardcode something that will look OK on all backgrounds. */
  '&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P0&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;; background-color: #&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$P7&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&quot;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'
}
.underline { text-decoration: underline; }
.line-through { text-decoration: line-through; }
.blink { text-decoration: blink; }
/* Avoid pixels between adjacent span elements.
   Note this only works for lines less than 80 chars
   where we close span elements on the same line.
span { display: inline-block; }
*/
'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$css_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s\n'&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'To use the css generated from --css-only, do: '&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;'&amp;lt;head&amp;gt;&amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;style.css&quot;&amp;gt;&amp;lt;/head&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$css_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body class=&quot;f9 b9&quot;&amp;gt;
&amp;lt;pre&amp;gt;
'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'%s\n'&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Be sure to use &amp;lt;body class=&quot;f9 b9&quot;&amp;gt; and &amp;lt;pre&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2

&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'\x1b\['&lt;/span&gt;        &lt;span class=&quot;c&quot;&gt;#shortcut to match escape codes&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Handle various xterm control sequences.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# See /usr/share/doc/xterm-*/ctlseqs.txt&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;
# escape ampersand and quote
s#&amp;amp;#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;amp;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;amp;#g; s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;amp;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;quot;#g;
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b[^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b]*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\\#&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#g  # strip anything between &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\e&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; and ST
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b][0-9]*;[^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\a&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;]*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\a&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;##g # strip any OSC (xterm title etc.)
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\$&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;## # strip trailing &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
# strip other non SGR escape sequences
s#[&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;07]##g
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b[]&amp;gt;=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\]&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9;]*##g
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1bP+.&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;##g
# Mark cursor positioning codes &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Jr;c;
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;G#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;J;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,2&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;H#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;J&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;#g
# Mark clear as &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Cn where n=1 is screen and n=0 is to end-of-line
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;H#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;C1;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;K#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;C0;#g
# Mark Cursor move columns as &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Mn where n is +ve for right, -ve for left
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;C#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;M1;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;C#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;M&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;D#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;M-&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;P#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;X&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9;?]*[^0-9;?m]##g
&quot;&lt;/span&gt; |

&lt;span class=&quot;c&quot;&gt;# Normalize the input before transformation&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;
# escape HTML (ampersand and quote done above)
s#&amp;gt;#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;amp;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;gt;#g; s#&amp;lt;#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;amp;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;lt;#g;
# handle truecolor
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;38;2;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
&amp;lt;span style=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;color:rgb(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\,\2\,\3\)\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;48;2;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
&amp;lt;span style=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;background-color:rgb(&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\,\2\,\3\)\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
# normalize SGR codes a little
# split 256 colors out and mark so that they're not
# recognised by the following 'split combined' line
:e
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9;]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[34]8;5;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;¬&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g; t e
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[34]8;5;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;¬&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g;
:c
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9;]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g; t c   # split combined
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#g                                 #strip leading 0
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1m&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(\(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[4579]m&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1m#g                   #bold last (with clr)
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0m#g                                          #add leading 0 to norm
# undo any 256 color marking
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;¬&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[34]8;5;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g;
# map 16 color codes to color + bold
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1m#g;
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1m#g;
# change 'reset' code to &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;R
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0m#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;R;#g
&quot;&lt;/span&gt; |

&lt;span class=&quot;c&quot;&gt;# Convert SGR sequences to HTML&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;
# common combinations to minimise html (optional)
:f
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3[0-7]m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g; t f
:b
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4[0-7]m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#g; t b
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\2\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-7]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;bold&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;underline&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;5m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;blink&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;7m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;reverse&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;9m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;line-through&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;38;5;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ef&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;48;5;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9]&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1,3&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\}\)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;m#&amp;lt;span class=&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;eb&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\1\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;gt;#g
s#&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0-9;]*m##g # strip unhandled codes
&quot;&lt;/span&gt; |

&lt;span class=&quot;c&quot;&gt;# Convert alternative character set and handle cursor movement codes&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Note we convert here, as if we do at start we have to worry about avoiding&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# conversion of SGR codes etc., whereas doing here we only have to&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# avoid conversions of stuff between &amp;amp;...; or &amp;lt;...&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Note we could use sed to do this based around:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   sed 'y/abcdefghijklmnopqrstuvwxyz{}`~/▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·/'&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# However that would be very awkward as we need to only conv some input.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# The basic scheme that we do in the awk script below is:&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  1. enable transliterate once &quot;T1; is seen&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  2. disable once &quot;T0; is seen (may be on diff line)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  3. never transliterate between &amp;amp;; or &amp;lt;&amp;gt; chars&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  4. track x,y movements and active display mode at each position&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#  5. buffer line/screen and dump when required&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;
# change 'smacs' and 'rmacs' to &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T1 and &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T0 to simplify matching.
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b(0#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T1;#g;
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0E#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T1;#g;
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1b(B#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T0;#g
s#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;0F#&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;T0;#g
&quot;&lt;/span&gt; |
&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
gawk &lt;span class=&quot;s1&quot;&gt;'
function dump_line(l,del,c,blanks,ret) {
  for(c=1;c&amp;lt;maxX;c++) {
    if ((c SUBSEP l) in attr || alength(cur)) {
      ret = ret blanks fixas(cur,attr[c,l])
      if(del) delete attr[c,l]
      blanks=&quot;&quot;
    }
    if ((c SUBSEP l) in dump) {
      ret=ret blanks dump[c,l]
      if(del) delete dump[c,l]
      blanks=&quot;&quot;
    } else blanks=blanks &quot; &quot;
  }
  if(alength(cur)) ret=ret blanks
  return ret
}
function dump_screen(l,ret) {
  for(l=1;l&amp;lt;=maxY;l++)
    ret=ret dump_line(l,0) &quot;\n&quot;
  return ret fixas(cur, &quot;&quot;)
}
function atos(a,i,ret) {
  for(i=1;i&amp;lt;=alength(a);i++) if(i in a) ret=ret a[i]
  return ret
}
function alength(a, i, k) {
    k = 0
    for(i in a) k++
    return k
}
function fixas(a,s,spc,i,attr,rm,ret) {
  spc=alength(a)
  l=split(s,attr,&quot;&amp;gt;&quot;)
  for(i=1;i&amp;lt;=spc;i++) {
    rm=rm?rm:(a[i]!=attr[i]&quot;&amp;gt;&quot;)
    if(rm) {
      ret=ret &quot;&amp;lt;/span&amp;gt;&quot;
      delete a[i];
    }
  }
  for(i=1;i&amp;lt;l;i++) {
    attr[i]=attr[i]&quot;&amp;gt;&quot;
    if(a[i]!=attr[i]) {
      a[i]=attr[i]
      ret = ret attr[i]
    }
  }
  return ret
}
function encode(string,start,end,i,ret,pos,sc,buf) {
   if(!end) end=length(string);
   if(!start) start=1;
   state=3
   for(i=1;i&amp;lt;=length(string);i++) {
     c=substr(string,i,1)
     if(state==2) {
       sc=sc c
       if(c==&quot;;&quot;) {
          c=sc
          state=last_mode
       } else continue
     } else {
       if(c==&quot;\r&quot;) { x=1; continue }
       if(c==&quot;&amp;lt;&quot;) {
         # Change attributes - store current active
         # attributes in span array
         split(substr(string,i),cord,&quot;&amp;gt;&quot;);
         i+=length(cord[1])
         span[++spc]=cord[1] &quot;&amp;gt;&quot;
         continue
       }
       else if(c==&quot;&amp;amp;&quot;) {
         # All goes to single position till we see a semicolon
         sc=c
         state=2
         continue
       }
       else if(c==&quot;\b&quot;) {
          # backspace move insertion point back 1
          if(spc) attr[x,y]=atos(span)
          x=x&amp;gt;1?x-1:1
          continue
       }
       else if(c==&quot;\&quot;&quot;) {
          split(substr(string,i+2),cord,&quot;;&quot;)
          cc=substr(string,i+1,1);
          if(cc==&quot;T&quot;) {
              # Transliterate on/off
              if(cord[1]==1&amp;amp;&amp;amp;state==3) last_mode=state=4
              if(cord[1]==0&amp;amp;&amp;amp;state==4) last_mode=state=3
          }
          else if(cc==&quot;C&quot;) {
              # Clear
              if(cord[1]+0) {
                # Screen - if Recording dump screen
                if(dumpStatus==dsActive) ret=ret dump_screen()
                dumpStatus=dsActive
                delete dump
                delete attr
                x=y=1
              } else {
                # To end of line
                for(pos=x;pos&amp;lt;maxX;pos++) {
                  dump[pos,y]=&quot; &quot;
                  if (!spc) delete attr[pos,y]
                  else attr[pos,y]=atos(span)
                }
              }
          }
          else if(cc==&quot;J&quot;) {
              # Jump to x,y
              i+=length(cord[2])+1
              # If line is higher - dump previous screen
              if(dumpStatus==dsActive&amp;amp;&amp;amp;cord[1]&amp;lt;y) {
                ret=ret dump_screen();
                dumpStatus=dsNew;
              }
              x=cord[2]
              if(length(cord[1]) &amp;amp;&amp;amp; y!=cord[1]){
                y=cord[1]
                if(y&amp;gt;maxY) maxY=y
                # Change y - start recording
                dumpStatus=dumpStatus?dumpStatus:dsReset
              }
          }
          else if(cc==&quot;M&quot;) {
              # Move left/right on current line
              x+=cord[1]
          }
          else if(cc==&quot;X&quot;) {
              # delete on right
              for(pos=x;pos&amp;lt;=maxX;pos++) {
                nx=pos+cord[1]
                if(nx&amp;lt;maxX) {
                  if((nx SUBSEP y) in attr) attr[pos,y] = attr[nx,y]
                  else delete attr[pos,y]
                  if((nx SUBSEP y) in dump) dump[pos,y] = dump[nx,y]
                  else delete dump[pos,y]
                } else if(spc) {
                  attr[pos,y]=atos(span)
                  dump[pos,y]=&quot; &quot;
                }
              }
          }
          else if(cc==&quot;R&quot;) {
              # Reset attributes
              while(spc) delete span[spc--]
          }
          i+=length(cord[1])+2
          continue
       }
       else if(state==4&amp;amp;&amp;amp;i&amp;gt;=start&amp;amp;&amp;amp;i&amp;lt;=end&amp;amp;&amp;amp;c in Trans) c=Trans[c]
     }
     if(dumpStatus==dsReset) {
       delete dump
       delete attr
       ret=ret&quot;\n&quot;
       dumpStatus=dsActive
     }
     if(dumpStatus==dsNew) {
       # After moving/clearing we are now ready to write
       # somthing to the screen so start recording now
       ret=ret&quot;\n&quot;
       dumpStatus=dsActive
     }
     if(dumpStatus==dsActive||dumpStatus==dsOff) {
       dump[x,y] = c
       if(!spc) delete attr[x,y]
       else attr[x,y] = atos(span)
       if(++x&amp;gt;maxX) maxX=x;
     }
    }
    # End of line if dumping increment y and set x back to first col
    x=1
    if(!dumpStatus) return ret dump_line(y,1);
    else if(++y&amp;gt;maxY) maxY=y;
    return ret
}
BEGIN{
  OFS=FS
  # dump screen status
  dsOff=0    # Not dumping screen contents just write output direct
  dsNew=1    # Just after move/clear waiting for activity to start recording
  dsReset=2  # Screen cleared build new empty buffer and record
  dsActive=3 # Currently recording
  F=&quot;abcdefghijklmnopqrstuvwxyz{}`~&quot;
  T=&quot;▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·&quot;
  maxX=80
  delete cur;
  x=y=1
  for(i=1;i&amp;lt;=length(F);i++)Trans[substr(F,i,1)]=substr(T,i,1);
}
{ $0=encode($0) }
1
END {
  if(dumpStatus) {
    print dump_screen();
  }
}'&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$body_only&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/pre&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;\n'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 27 Dec 2022 20:20:52 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2022/12/27/git-diff/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2022/12/27/git-diff/</guid>
        
        <category>Git</category>
        
        <category>Windows</category>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        
        <category>Git</category>
        
        <category>Windows</category>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>SRT字幕文件转文本文件</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-获取字幕文件&quot; id=&quot;markdown-toc-1-获取字幕文件&quot;&gt;1. 获取字幕文件&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-python脚本&quot; id=&quot;markdown-toc-2-python脚本&quot;&gt;2. python脚本&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-获取字幕文件&quot;&gt;1. 获取字幕文件&lt;/h2&gt;
&lt;p&gt;一般来说，很多视频网站都会提供视频的字幕文件。有的可以直接下载，有的需要先下载视频，然后再使用字幕软件提取字幕文件。还有一些可以在Chrome浏览器中安装字幕插件，然后在视频播放页面中直接下载字幕文件。总而言之，需要先获取到字幕文件，然后才能进行下一步操作。&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SRT&lt;/code&gt;格式的字幕文件是最常见的，其格式如下所示：&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-txt&quot; data-lang=&quot;txt&quot;&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;1
00:00:00,000 --&amp;gt; 00:00:02,000
Life is short

2
00:00:02,205 --&amp;gt; 00:00:04,000
You need Python
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;可以看到，字幕文件由多个字幕组成，每个字幕由两行组成，第一行是字幕的序号，第二行是字幕的时间轴，第三行是字幕的内容。字幕之间用空行分隔。所以，只需要先删除所有空行，然后对&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;line_num%3==0&lt;/code&gt;的行进行处理，即可得到字幕的内容&lt;/p&gt;

&lt;h2 id=&quot;2-python脚本&quot;&gt;2. python脚本&lt;/h2&gt;
&lt;p&gt;文件内容如下：&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 'zfb'
# time: 2019-10-26 17:17
&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;glob&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 输出文件的头部信息，可以为空
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;header&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;zfb 2019-10-26 17:17&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 段落开始符号
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin_para_symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;  &quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 拼接句子的符号
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split_line_symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;，&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 拼接字幕文件的符号
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split_file_symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\n\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_toc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 去除所有空行
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;strip_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strip_lines&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_srt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 去除所有空行
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;strip_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lines&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 根据文件格式，字幕文字所在行是3的倍数，从起始位置，到结束位置，间隔为3
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;text_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strip_lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 按照逗号拼接全文
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;split_line_symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text_lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 按文件名排序
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;glob&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*.srt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srt_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toc_lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txt_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srt_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toc_lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;begin_para_symbol&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_srt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srt_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;split_file_symbol&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;txt_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;w&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'SRT字幕文件转TXT文件'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;formatter_class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RawDescriptionHelpFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;epilog&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;'''&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;用法示例：
    python srt2txt.py ./srt/ ./content.txt -t ./toc.txt
    python srt2txt.py ./srt/ ./content.txt
    python srt2txt.py
'''&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 可选参数
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;-s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;--srt_dir&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./srt/&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;*.srt字幕文件所在目录，默认为当前目录下的srt文件夹&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;-o&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;--output_name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./content.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;输出文件名，默认为content.txt&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;-t&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;--toc&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;./toc.txt&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;目录文件名，默认为toc.txt, 如果没有，会根据字幕文件名生成&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 字幕文件所在目录
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;srt_file_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srt_dir&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 目录文件，如果没有，会根据字幕文件名生成
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;toc_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toc&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 输出文件
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;txt_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_name&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;srt_file_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toc_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 读取目录文件
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;toc_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_toc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toc_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 根据srt文件名，生成目录文件
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;toc_lines&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;toc_lines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;txt_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Tue, 27 Dec 2022 19:35:11 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2022/12/27/convert-srt-to-txt/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2022/12/27/convert-srt-to-txt/</guid>
        
        <category>Python</category>
        
        <category>Linux</category>
        
        <category>Ubuntu</category>
        
        <category>Windows</category>
        
        
        <category>Python</category>
        
        <category>Linux</category>
        
        <category>Ubuntu</category>
        
        <category>Windows</category>
        
      </item>
    
      <item>
        <title>在ubuntu系统安装配置heatererp软件</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-下载软件包并安装依赖&quot; id=&quot;markdown-toc-1-下载软件包并安装依赖&quot;&gt;1. 下载软件包并安装依赖&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-配置heatererp&quot; id=&quot;markdown-toc-2-配置heatererp&quot;&gt;2. 配置heatererp&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-创建文件夹保存运算结果&quot; id=&quot;markdown-toc-3-创建文件夹保存运算结果&quot;&gt;3. 创建文件夹保存运算结果&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-运行测试&quot; id=&quot;markdown-toc-4-运行测试&quot;&gt;4. 运行测试&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#5-注意&quot; id=&quot;markdown-toc-5-注意&quot;&gt;5. 注意&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-下载软件包并安装依赖&quot;&gt;1. 下载软件包并安装依赖&lt;/h2&gt;
&lt;p&gt;安装需要依赖的软件，使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nec2c&lt;/code&gt;虽然运行慢，但是配置简单&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt-get install zip nec2c octave&lt;/code&gt;&lt;br /&gt;
本项目代码仓库网址： &lt;a href=&quot;https://gitlab.com/andrewsenior/heatererp&quot; title=&quot;&amp;quot;)  
项目介绍网址： [https://www.eiscat.uit.no/DataBases/heating_logs/htr-log-index-2015.html](https://www.eiscat.uit.no/DataBases/heating_logs/htr-log-index-2015.html &amp;quot;&quot;&gt;https://gitlab.com/andrewsenior/heatererp&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;2-配置heatererp&quot;&gt;2. 配置heatererp&lt;/h2&gt;
&lt;p&gt;启动heatererp，步骤如下：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd ~/heatererp-master/bin&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chmod +x ./erpmodel.sh&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./erpmodel.sh&lt;/code&gt;&lt;br /&gt;
然后会提示设置各种路径，可以随便弄，然后再修改&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.config/heatererp/conf.m&lt;/code&gt;文件中的路径&lt;br /&gt;
设置完以后保证&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conf.m&lt;/code&gt;的内容如下，注意&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model_engine&lt;/code&gt;设置为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nec2c&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-matlab highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;% Configuration script for Heater ERP model&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/home/zfb/heatererp-master/models'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nec2_bin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/the/real/path/to/nec2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;nec2c_bin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'nec2c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;model_engine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'nec2c'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;log_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/home/zfb/heatererp/logs'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;results_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/home/zfb/heatererp/results'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plots_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'/home/zfb/heatererp/plots'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;3-创建文件夹保存运算结果&quot;&gt;3. 创建文件夹保存运算结果&lt;/h2&gt;
&lt;p&gt;创建的文件夹要与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conf.m&lt;/code&gt;文件中设置的相对应&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd ~ &amp;amp;&amp;amp; mkdir heatererp &amp;amp;&amp;amp; cd heatererp&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mkdir logs plots results&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;4-运行测试&quot;&gt;4. 运行测试&lt;/h2&gt;
&lt;p&gt;放置log文件，执行sh脚本运行模型&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cp ~/heatererp-master/testing/1970-01-01_tx.log ~/heatererp/logs/&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd ~/heatererp-master/bin &amp;amp;&amp;amp; ./erpmodel.sh&lt;/code&gt;&lt;br /&gt;
在打开的octave软件的提示符里面输入以下内容即可计算&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;erpmodel('01-Jan-1970 00:00:00');erpmodel('01-Jan-1970 01:28:00');&lt;/code&gt;
等待运行结束，在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/zfb/heatererp/&lt;/code&gt;对应文件夹寻找结果&lt;/p&gt;
&lt;h2 id=&quot;5-注意&quot;&gt;5. 注意&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;在Ubuntu 18.04系统测试通过（Ubuntu 20.04好像不太行）&lt;/li&gt;
  &lt;li&gt;如果系统有GUI，还会同时显示图片&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.log&lt;/code&gt;文件的第一行是实验开始时间，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;erpmodel()&lt;/code&gt;的参数可以是那个时刻及以后的时刻&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 27 Feb 2021 15:37:56 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2021/02/27/ubuntu_config_heatererp/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2021/02/27/ubuntu_config_heatererp/</guid>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>在linux系统监控某个程序的执行情况并通知用户</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#介绍&quot; id=&quot;markdown-toc-介绍&quot;&gt;介绍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#代码&quot; id=&quot;markdown-toc-代码&quot;&gt;代码&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#运行监控代码文件&quot; id=&quot;markdown-toc-运行监控代码文件&quot;&gt;运行监控代码文件&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;介绍&quot;&gt;介绍&lt;/h2&gt;
&lt;p&gt;如果有一个下载任务需要执行（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;python3 download.py&lt;/code&gt;），该任务会下载许多文件，一般将其放在后台执行。但是又需要知道它是否在某个时刻退出，可能是因为：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;任务执行完毕，正常结束运行&lt;/li&gt;
  &lt;li&gt;任务异常退出，可能由于下载的网站爬虫策略限制，也可能是其他原因&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;无论由于哪个原因，一旦程序停止，都需要立刻用户，所以编写以下代码来实现该功能&lt;/p&gt;
&lt;h2 id=&quot;代码&quot;&gt;代码&lt;/h2&gt;
&lt;p&gt;使用python语言编写监控程序&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;detect.py&lt;/code&gt;文件：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;如果需要使用腾讯云发送短信通知，则安装库&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;qcloudsms_py&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;如果需要使用twilio发送短信通知，则安装库&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;twilio&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;文件内容如下：&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 'zfb'
# time: 19-06-29 09:52
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;socket&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;logging.handlers&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RotatingFileHandler&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qcloudsms_py&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SmsSingleSender&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;qcloudsms_py.httpclient&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTTPError&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;LOG_FORMAT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%(asctime)s [%(funcName)s: %(filename)s,%(lineno)d] - %(levelname)s : %(message)s&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DATE_FORMAT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;%m/%d/%Y %H:%M:%S&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;LOG_PATH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;./log/&quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# 初始化日志文件配置
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 创建日志文件夹
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LOG_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mkdir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LOG_PATH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;myapp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;myapp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setLevel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DEBUG&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 切割日志文件
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RotatingFileHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LOG_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxBytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backupCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Formatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;LOG_FORMAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATE_FORMAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;myapp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myapp&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'detect.log'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'detect'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# ------------  使用腾讯云发送短信通知用户  -----------
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;APP_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1412345678&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;APP_KEY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;3998d59614123456789b72dd5961405c&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;TEMPLATE_ID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;101234&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SMS_SIGN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;签名A&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------  使用腾讯云发送短信通知用户  -----------
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------  使用twilio发送短信  ------------------
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SMS_SID&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'ACb770c5f63aac91c44d97891234567890'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SMS_TOKEN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'42b1294966799e965883181234567890'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SMS_FROM_NUMBER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'+12512123456'&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------  使用twilio发送短信  ------------------
&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------  使用邮箱发信  ------------------------
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EMAIL_FROM&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'example@qq.com'&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;EMAIL_PWD&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'123demo'&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ------------  使用邮箱发信  ------------------------
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sendSMS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;app_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;APP_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;APP_KEY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template_id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TEMPLATE_ID&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sms_sign&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SMS_SIGN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ssender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SmsSingleSender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;app_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ssender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;send_with_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sms_sign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HTTPError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dumps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 使用twilio的使用账户发送短信
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;send_sms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;twilio.rest&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Client&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 账户信息： twilio.com/console
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;account_sid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMS_SID&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;auth_token&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMS_TOKEN&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;from_phone_num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMS_FROM_NUMBER&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;account_sid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;auth_token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;messages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_phone_num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 使用139邮箱的短信通知功能
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;send_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;smtplib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMTPException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMTP_SSL&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.mime.text&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEText&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;email.header&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 发件人
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMAIL_FROM&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;EMAIL_PWD&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 三个参数：第一个为文本内容，第二个为plain设置文本格式，第三个为utf-8设置编码
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MIMEText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;plain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'utf-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'From'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'utf-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'To'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'utf-8'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Subject&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Header&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# 使用非本地服务器，需要建立ssl连接
&lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;smtpObj&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMTP_SSL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;smtp.exmail.qq.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;465&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;smtpObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pwd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;smtpObj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sendmail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;as_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;邮件发送成功&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SMTPException&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Error：无法发送邮件.Case:%s&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 检测下载进程是否正在运行
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isRunning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;popen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'ps -ef | grep {}'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;search_param&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# print(line)
&lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/bin/sh&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;grep&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Terminated&quot;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# print(length)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# 获取系统用户名和ip
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInfomation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 创建socket访问DNS来获取本机的IP，如果是NAT的话，则是局域网IP
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;local_ip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AF_INET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;socket&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SOCK_DGRAM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'1.1.1.1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;local_ip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getsockname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# 访问www.ip.cn网站获取公网IP
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;net_ip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;127.0.0.1&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;net_ip&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'https://api.ipify.org'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;local_ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;net_ip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isRunning&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;download.py&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;flag_file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/home/ubuntu/flag&quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# now = datetime.datetime.now().strftime(&quot;%Y-%m-%d %H:%M:%S&quot;)
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;program is running&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;program stopped, nobody fixed it.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getInfomation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;您的主机{}，公网IP地址为{}，局域网IP为{}，下载进程已中断&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;13612345678&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sendSMS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'spy'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;send_sms&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;send_email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;user@qq.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;spy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flag_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;w+&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;nb&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Please delete me after restarting the download program.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;program stopped&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&quot;运行监控代码文件&quot;&gt;运行监控代码文件&lt;/h2&gt;
&lt;p&gt;在终端输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;crontab -e&lt;/code&gt;打开定时管理任务，然后在文件中最后添加一行，内容如下：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*/30 * * * * python3 /home/ubuntu/detect.py&lt;/code&gt;&lt;br /&gt;
此代码表示每隔30min运行一次&lt;br /&gt;
&lt;strong&gt;注意&lt;/strong&gt;：每次重新启动下载进程之后，务必删除&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flag&lt;/code&gt;文件（为了防止因为没有及时重启下载进程而浪费短信资源，在主目录&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~&lt;/code&gt;下输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rm flag&lt;/code&gt;即可删除此文件）&lt;/p&gt;
</description>
        <pubDate>Thu, 11 Feb 2021 13:30:21 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2021/02/11/linux_monitor_program/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2021/02/11/linux_monitor_program/</guid>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Python</category>
        
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Python</category>
        
      </item>
    
      <item>
        <title>在linux系统使用expect命令自动填充ssh或scp等命令的密码</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#expect命令使用范例&quot; id=&quot;markdown-toc-expect命令使用范例&quot;&gt;expect命令使用范例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;expect命令使用范例&quot;&gt;expect命令使用范例&lt;/h2&gt;
&lt;p&gt;shell脚本文件的名称为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;download.sh&lt;/code&gt;，内容如下：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 任何一句命令执行出错，都会终止该脚本&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-e&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 设置为调试模式，在执行过程中会同时输出各变量的值&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# set -x&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 连接scp&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#######################&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# expect {&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   -re &quot;.*es.*o.*&quot; {&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#     exp_send &quot;yes\r&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#     exp_continue&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   }&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   -re &quot;.*sword.*&quot; {&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#     exp_send &quot;mypwd12345\r&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   }&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# }&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 把远程机器上的文件下载到本地机器&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 参数1: 远程机器上的文件（或文件夹）的绝对路径&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 参数2: 存放位置，即本地机器上的文件夹&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 当scp下载大文件时，需要耗费更多时间，设置timeout&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;function &lt;/span&gt;scp_download&lt;span class=&quot;o&quot;&gt;(){&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$# &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 2 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;need_ssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0
&lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;need_ssh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$3&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zfb
&lt;span class=&quot;nv&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;192.168.1.56&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;passwd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;1234567890pwd&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$3&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-eq&lt;/span&gt; 1 &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ssh登录远程机器，为目标文件添加读写执行权限&lt;/span&gt;
/usr/bin/expect&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    spawn ssh &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    expect {
        -timeout -1
        &quot;*yes/no&quot; {
            send &quot;yes&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;;exp_continue
        }
        &quot;*password:&quot; {
            send &quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$passwd&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
            # zfb@my-Server:~$
            expect &quot;~.*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
            send &quot;sudo chmod 777 &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
            expect &quot;*assword:&quot;
            send &quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$passwd&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
            expect &quot;~.*&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$&quot;&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
            send &quot;exit&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
            expect eof
        }
    }
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 使用scp自动下载文件&lt;/span&gt;
/usr/bin/expect&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    set timeout 600
    spawn scp -r &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$host&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$dst&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    expect {
        &quot;*yes/no&quot; {
            send &quot;yes&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;;exp_continue
        }
        &quot;*password:&quot; {
            send &quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$passwd&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;&quot;
            expect eof
        }
    }
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;EOF
&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# 脚本运行参数&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 参数1: 远程机器的文件（夹）绝对路径， 例如 /media/data/test/a.txt&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 参数2：保存位置，即本地路径&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 若本地不存在，则创建目录&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; does not exist, ready to mkdir &quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;mkdir successfully!&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi
&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;/opendata
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; does not exist, ready to mkdir &quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;mkdir successfully!&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;scp_download &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;/test.txt &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
scp_download &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;/test/testaa.py &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;mv&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;/testaa.py &lt;span class=&quot;nv&quot;&gt;$2&lt;/span&gt;/testbb.py
scp_download &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;/test/opendata/testcc.txt &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# testdd.txt在远程机器上，无读取权限，需要ssh进行chmod添加权限&lt;/span&gt;
scp_download &lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;/test/opendata/testdd.txt &lt;span class=&quot;nv&quot;&gt;$data&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;使用方法示例：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;./download.sh /media/data/test ./&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 16 Jan 2021 14:13:22 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2021/01/16/linux_expect/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2021/01/16/linux_expect/</guid>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
      </item>
    
      <item>
        <title>在Ubuntu系统以及WSL 2安装使用Docker</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-docker介绍&quot; id=&quot;markdown-toc-1-docker介绍&quot;&gt;1. Docker介绍&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-安装使用wsl-2的docker&quot; id=&quot;markdown-toc-2-安装使用wsl-2的docker&quot;&gt;2. 安装使用WSL 2的Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-配置docker&quot; id=&quot;markdown-toc-3-配置docker&quot;&gt;3. 配置Docker&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-docker常用命令&quot; id=&quot;markdown-toc-4-docker常用命令&quot;&gt;4. docker常用命令&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#41-exec&quot; id=&quot;markdown-toc-41-exec&quot;&gt;4.1 exec&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#42-run&quot; id=&quot;markdown-toc-42-run&quot;&gt;4.2 run&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#5-dockerfile&quot; id=&quot;markdown-toc-5-dockerfile&quot;&gt;5. Dockerfile&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#6-docker-compose&quot; id=&quot;markdown-toc-6-docker-compose&quot;&gt;6. docker-compose&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#7-ubuntu不是wsl安装使用docker&quot; id=&quot;markdown-toc-7-ubuntu不是wsl安装使用docker&quot;&gt;7. Ubuntu（不是WSL）安装使用Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-docker介绍&quot;&gt;1. Docker介绍&lt;/h2&gt;
&lt;p&gt;Docker 使用 Google 公司推出的 Go 语言 进行开发实现，基于 Linux 内核的 cgroup，namespace，以及 OverlayFS 类的 Union FS 等技术，对进程进行封装隔离，属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程，因此也称其为容器。&lt;br /&gt;
Docker包含三个概念：镜像（Image）、容器（Container）、仓库（Repository）&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;镜像是只读的，镜像中包含有需要运行的文件（运行时所需的程序、库、资源、配置等文件；运行时准备的一些配置参数如匿名卷、环境变量、用户等）。镜像用来创建容器container，一个镜像可以运行多个container；镜像可以通过Dockerfile创建，也可以从Docker hub/registry上下载&lt;/li&gt;
  &lt;li&gt;容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。容器的实质是进程，但与直接在宿主执行的进程不同，容器进程可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间，甚至自己的用户 ID 空间；每一个容器运行时，是以镜像为基础层，在其上创建一个当前容器的存储层，我们可以称这个为容器运行时读写而准备的存储层为&lt;strong&gt;容器存储层&lt;/strong&gt;；容器存储层的生存周期和容器一样，容器消亡时，容器存储层也随之消亡。因此，任何保存于容器存储层的信息都会随容器删除而丢失；容器不应该向其存储层内写入任何数据，&lt;strong&gt;容器存储层要保持无状态化&lt;/strong&gt;。所有的文件写入操作，都应该使用&lt;strong&gt;数据卷&lt;/strong&gt;（Volume）、或者&lt;strong&gt;绑定宿主目录&lt;/strong&gt;，在这些位置的读写会跳过容器存储层，直接对宿主（或网络存储）发生读写，其性能和稳定性更高&lt;/li&gt;
  &lt;li&gt;镜像构建完成后，可以很容易的在当前宿主机上运行，但是，如果需要在其它服务器上使用这个镜像，就需要一个集中的存储、分发镜像的服务，Docker Registry（注册服务器）就是这样的服务；一个 Docker Registry 中可以包含多个仓库（Repository）；每个仓库可以包含多个标签（Tag）；每个标签对应一个镜像。一个仓库会包含同一个软件不同版本的镜像，而标签就常用于对应该软件的各个版本。我们可以通过&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;仓库名&amp;gt;:&amp;lt;标签&amp;gt;&lt;/code&gt;的格式来指定具体是这个软件哪个版本的镜像（仓库名经常以两段式路径形式出现，比如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jwilder/nginx-proxy&lt;/code&gt;，前者往往意味着 Docker Registry 多用户环境下的用户名，后者则往往是对应的软件名）。如果不给出标签，将以&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latest&lt;/code&gt;作为默认标签，例如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubuntu:16.04&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubuntu&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ubuntu:latest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker三个命令：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;docker-compose&lt;/strong&gt;：Docker镜像在创建之后，往往需要自己手动&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pull&lt;/code&gt;来获取镜像，然后执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;run&lt;/code&gt;命令来运行。当服务需要用到多种容器，容器之间又产生了各种依赖和连接的时候，部署一个服务的手动操作是令人感到十分厌烦的。&lt;strong&gt;dcoker-compose&lt;/strong&gt;技术，就是通过一个&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.yml&lt;/code&gt;配置文件，将所有的容器的部署方法、文件映射、容器连接等等一系列的配置写在一个配置文件里，最后只需要执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose up&lt;/code&gt;命令就会像执行脚本一样的去一个个安装容器并自动部署他们，极大的便利了复杂服务的部署&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;docker-machine&lt;/strong&gt;：Docker公司官方提出的，用于在各种平台上快速创建具有 docker 服务的虚拟机的技术，甚至可以通过指定 driver 来定制虚拟机的实现原理（一般是 virtualbox）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;docker-swarm&lt;/strong&gt;：swarm 是基于 docker 平台实现的集群技术，他可以通过几条简单的指令快速的创建一个 docker 集群，接着在集群的共享网络上部署应用，最终实现分布式的服务&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2-安装使用wsl-2的docker&quot;&gt;2. 安装使用WSL 2的Docker&lt;/h2&gt;
&lt;p&gt;在WSL使用Docker的官网安装&lt;a href=&quot;https://docs.docker.com/docker-for-windows/wsl/&quot;&gt;教程&lt;/a&gt;，需要自己安装&lt;a href=&quot;https://hub.docker.com/editions/community/docker-ce-desktop-windows/&quot;&gt;Windows版Docker&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;3-配置docker&quot;&gt;3. 配置Docker&lt;/h2&gt;
&lt;p&gt;打开Docker软件，修改设置：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Resources–&amp;gt;WSL Integration，启用自己安装的子系统&lt;/li&gt;
  &lt;li&gt;Docker Engine修改镜像配置为
    &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;registry-mirrors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://hub-mirror.c.163.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
   &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://mirror.baidubce.com&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;insecure-registries&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;debug&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;experimental&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;上述配置文件的路径在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Users\zfb\.docker\daemon.json&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;保存配置并重启Docker，则Windows的Powershell和WSL均可正常使用docker&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;4-docker常用命令&quot;&gt;4. docker常用命令&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;所有命令中，容器id与容器名字可以混用&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker info&lt;/code&gt;：查看当前系统Docker信息&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker version&lt;/code&gt;：查看当前Docker的版本&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker inspect c4b66ffc84d3&lt;/code&gt;：输出容器的详细信息&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker cp tomcat:/webapps/js/text.js /home/admin&lt;/code&gt;：将容器中的文件复制到宿主机&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker run hello-world&lt;/code&gt;：运行最简单的一个docker命令，测试是否安装成功&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker pull angelkitty/nginx_web:v1&lt;/code&gt;：下载镜像，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{registry}/{namespace or project}/{image}:{tag}&lt;/code&gt;，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;registry&lt;/code&gt;不填的情况下默认为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker.io&lt;/code&gt;（可通过修改配置文件改为其他），&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;namespace or project&lt;/code&gt;不填的情况下默认为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;library&lt;/code&gt;，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tag&lt;/code&gt;不填的情况下默认为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latest&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker commit c4b66ffc84d3 zfb/testimage:2.0&lt;/code&gt;：可以保留对镜像的修改，在原有镜像的基础上，再叠加上容器的存储层，并构成新的镜像，将其保存下来形成镜像。以后运行这个新镜像的时候，就会拥有原有容器最后的文件变化，但是不利于分发部署，因为其他人不知道生成此镜像的步骤&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker images&lt;/code&gt;：查看宿主机上的镜像，镜像保存在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/docker&lt;/code&gt;目录下&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker rmi c4b66ffc84d3&lt;/code&gt;：删除id为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c4b66ffc84d3&lt;/code&gt;的本地镜像，也可以是镜像的名字&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker rmi -f $(docker images -q)&lt;/code&gt;：强制删除所有镜像&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker image prune -f -a&lt;/code&gt;：强制删除所有不使用的镜像&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker ps -a -q&lt;/code&gt;：显示所有（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-a&lt;/code&gt;）容器（运行中和已退出）的详细信息，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-q&lt;/code&gt;表示只显示容器的id信息&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker top c4b66ffc84d3&lt;/code&gt;：查看容器内的进程&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker stop $(docker ps -aq)&lt;/code&gt;：停止所有的容器&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker stop 8d0eb8b4180b&lt;/code&gt;：停止id为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8d0eb8b4180b&lt;/code&gt;的容器，也可以是容器的名字，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webserver&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker start Name或者ID&lt;/code&gt;：启动id为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID&lt;/code&gt;的容器，也可以是容器的名字，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Name&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker kill Name或者ID&lt;/code&gt;：强制杀死id为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID&lt;/code&gt;的容器，也可以是容器的名字，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Name&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker restart name或者ID&lt;/code&gt;：重启id为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID&lt;/code&gt;的容器，也可以是容器的名字，如&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Name&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker rm $(docker ps -a -q)&lt;/code&gt;：删除所有容器&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker container prune&lt;/code&gt;：删除所有已停止的容器&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;41-exec&quot;&gt;4.1 exec&lt;/h3&gt;
&lt;p&gt;使用此命令可以进入正在运行（或已经创建）的容器，例如：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker exec -it webserver bash&lt;/code&gt;&lt;br /&gt;
此命令表示进入名称为webserver的容器里面（也可以通过id进入），并且执行bash命令；此时我们会看到回显：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt; ~ &amp;gt; docker exec -it webserver bash
root@79b527eb60ee:/#
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-i&lt;/code&gt;表示即使没有附加也保持标准输入打开，以交互模式运行容器，通常与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt;同时使用&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt;表示为容器重新分配一个伪输入终端，通常与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-i&lt;/code&gt;同时使用&lt;br /&gt;
在bash修改配置、退出容器时候：如果要正常退出不关闭容器，需要按&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+P+Q&lt;/code&gt;进行退出容器，如果要回到运行中的容器则&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker attach c4b66ffc84d3&lt;/code&gt;；如果使用exit退出，那么在退出之后会关闭容器，可以使用下面的流程恢复&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker restart &amp;amp;&amp;amp; docker attach&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;42-run&quot;&gt;4.2 run&lt;/h3&gt;
&lt;p&gt;run命令会去首先在本地寻找镜像，如果不存在则从网络下载&lt;br /&gt;
使用镜像nginx:latest以交互模式启动（创建）一个容器，在容器内执行/bin/bash命令&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker run --name webserver -d -p 4000:80 -it nginx:latest /bin/bash&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--name&lt;/code&gt;：为容器指定名称&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--cpuset=&quot;0-2&quot; or --cpuset=&quot;0,1,2&quot;&lt;/code&gt;：绑定容器到指定CPU运行&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--link mypostgres_merry:db&lt;/code&gt;：将此容器与名称为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mypostgres_merry&lt;/code&gt;的容器连接，并为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mypostgres_merry&lt;/code&gt;容器设置别名为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;db&lt;/code&gt;&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-d&lt;/code&gt;：表示后台运行容器，并返回容器ID&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-e username=&quot;ritchie&quot;&lt;/code&gt;：为容器设置环境变量&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-m&lt;/code&gt;：设置容器使用内存最大值&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-P&lt;/code&gt;：随机端口映射，容器内部端口随机映射到主机的端口&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-p 4000:80&lt;/code&gt;：指定端口映射，将容器的80端口映射为宿主机的4000端口&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-v /home/zfb/myimage:/data&lt;/code&gt;：将主机上的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/zfb/myimage&lt;/code&gt;目录中的内容关联到容器的文件系统&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data&lt;/code&gt;下&lt;/p&gt;

&lt;h2 id=&quot;5-dockerfile&quot;&gt;5. Dockerfile&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;是一个用来构建镜像的文本文件（定制镜像），文本内容包含了一条条构建镜像所需的指令（每一条指令的内容，就是描述该层应当如何构建）和说明，每添加一层，镜像就会变大一些，所以尽可能把同类操作合并为一个指令&lt;br /&gt;
忽略大小写，但是建议使用大写，使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;#&lt;/code&gt;作为注释，每一行只支持一条指令，每条指令可以携带多个参数&lt;br /&gt;
指令的换行方式与shell环境一致（用转义符&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\&lt;/code&gt;表示换行），如下所示：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get update &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        build-essential &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        cmake &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;此指令与&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;apt-get update &amp;amp;&amp;amp; apt-get install -y build-essential cmake git&lt;/code&gt;效果完全一致&lt;br /&gt;
一般来说&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;的内容分为四个部分：&lt;strong&gt;基础镜像信息&lt;/strong&gt;、&lt;strong&gt;维护者信息&lt;/strong&gt;、&lt;strong&gt;镜像操作指令&lt;/strong&gt;和&lt;strong&gt;容器启动时执行指令&lt;/strong&gt;；支持的指令为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FROM&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MAINTAINER&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RUN&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EXPOSE&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENV&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARG&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ADD&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;COPY&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENTRYPOINT&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;VOLUME&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;USER&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WORKDIR&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ONBUILD&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-dockerfile highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 第一条指令必须为 FROM 指令，表示下面修改基于的镜像&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# FROM ubuntu:20.04&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;FROM&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; nginx:1.11&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 指定维护者信息&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;MAINTAINER&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; zfb and example@gmail.com&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 指定RUN命令更新镜像，RUN command，command为shell支持的所有命令&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 尽量把它们写为一条（用&amp;amp;&amp;amp;连接），多条的话会打包多层&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 每一个 RUN 都是启动一个容器、执行命令、然后提交存储层文件变更&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 因此cd命令与其他命令&amp;amp;&amp;amp;连起来放到同一个RUN，否则不会成功&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# RUN命令的另一种写法（exec格式，一定要使用双引号&quot;），CMD命令也支持此写法&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# RUN [&quot;/bin/bash&quot;, &quot;-c&quot;, &quot;echo hello&quot;]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 对于国内使用，先更换源；有的是cn，有的不是&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 然后更新apt、安装需要的软件包、删除缓存文件使镜像更小&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# RUN echo &quot;deb http://archive.ubuntu.com/ubuntu/ raring main universe&quot; &amp;gt;&amp;gt; /etc/apt/sources.list&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/cn.archive.ubuntu.com/mirrors.ustc.edu.cn/g'&lt;/span&gt; /etc/apt/sources.list &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sed&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'s/archive.ubuntu.com/mirrors.ustc.edu.cn/g'&lt;/span&gt; /etc/apt/sources.list &lt;span class=&quot;se&quot;&gt;\
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get update &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 指定容器对外暴露的端口号为3000-4000和5008&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 讨论以下几种情况&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   1. 既没有在Dockerfile里Expose，也没有run -p&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   2. 只在Dockerfile里Expose了这个端口&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   3. 同时在Dockerfile里Expose，又run -p&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   4. 只有run -p&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 针对情况1&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   启动在这个容器里的服务既不能被host主机和外网访问&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   也不能被链接的容器访问，只能在此容器内部使用&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 针对情况2&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   启动在这个容器里的服务不能被docker外部世界（宿主机和其他主机）访问&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   但是可以通过容器链接，被其他链接的容器访问到&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 针对情况3&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   启动的这个容器既可以被docker外部世界访问，也可以被链接的容器访问&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 针对情况4&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   等价于情况3&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;EXPOSE&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; 80 443 3000-4000 5008&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 在镜像构建过程中设置环境变量，可以被后面的所有指令使用，会永久的保存到该镜像创建的任何容器中&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 例如：ADD、COPY、ENV、EXPOSE、FROM、LABEL、USER、WORKDIR、VOLUME、STOPSIGNAL、ONBUILD、RUN&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 但不能被CMD指令使用&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; MYDIR /mydir&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; VERSION=1.0 DEBUG=&quot;on&quot; NAME=zfb&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ARG设置的构建环境的环境变量（参数名称和默认值），在将来容器运行时不会存在（但是docker history可以看到）&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 构建命令 docker build 中用 --build-arg MYDEBUG=off 来覆盖&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ARG&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; MYDEBUG=on&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 改变环境状态并影响以后的层，RUN、CMD、ENTRYPOINT这类命令的身份&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 这个用户必须是事先建立好的&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;RUN &lt;/span&gt;groupadd &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; gp_redis &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; useradd &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt; redis gp_redis
&lt;span class=&quot;k&quot;&gt;USER&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; redis:gp_redis&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 指定工作目录，相当于cd&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 该语句以后各层的当前目录就被改为指定的目录，如该目录不存在，WORKDIR 会自动建立目录&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;WORKDIR&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; /home/$NAME/test&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 从构建上下文目录中&amp;lt;源路径&amp;gt;的文件/目录复制到新的一层的镜像内的&amp;lt;目标路径&amp;gt;位置&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 构建上下文：docker build -t testx .    其中.表示当前目录，则上下文为当前宿主机的目录&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &amp;lt;源路径&amp;gt;   可以是多个，甚至可以是通配符&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# &amp;lt;目标路径&amp;gt; 可以是容器内的绝对路径，也可以是相对于工作目录的路径（若不存在自动创建缺失目录）&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;COPY&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; check?.log ./&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 格式和 COPY 命令相同，可以完成 COPY 命令的所有功能，还具有其他功能&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 自动解压压缩文件并把它们添加到镜像中；从 url 拷贝文件到镜像中&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; myname.tar.gz ./&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 在镜像中创建挂载点，这样只要通过该镜像创建的容器都有了挂载点&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 通过 VOLUME 指令创建的挂载点，无法指定宿主机上对应的目录，是自动生成的&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# docker run -v可以指定&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 指定两个挂载点 /data1 和 /data2&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;VOLUME&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;/data1&quot;, &quot;/data2&quot;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ENTRYPOINT指定容器启动程序及参数，格式和RUN格式一样，exec格式和shell格式&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 只有最新的一行ENTRYPOINT生效，前面会被覆盖&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 当指定ENTRYPOINT后，CMD指令的含义改变了&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 不再是直接运行命令，而是将CMD（或者docker run时的命令）的内容作为参数传给ENTRYPOINT指令&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 例如，CMD命令指定ENTRYPOINT命令的参数，&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ENTRYPOINT [&quot;docker-entrypoint.sh&quot;]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# CMD [ &quot;redis-server&quot; ]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 如上设置会在容器创建后自动运行shell命令  ./docker-entrypoint.sh &quot;redis-server&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 再例如：docker run mytest curl -s http://ip.cn -i（mytest的Dockerfile未设置ENTRYPOINT）&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 等价于：docker run newtest -i（newtest的Dockerfile设置ENTRYPOINT如下）&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ENTRYPOINT&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;curl&quot;, &quot;-s&quot;, &quot;http://ip.cn&quot;]&lt;/span&gt;


&lt;span class=&quot;c&quot;&gt;# CMD 指令的格式和 RUN 相似，表示容器创建后自动执行的命令，只有最新的一行CMD生效，前面会被覆盖&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 但是需要明白前台、后台的概念，区分容器和虚拟机的差异&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 对于容器而言，其启动程序就是容器应用进程，容器就是为了主进程而存在的，主进程退出，容器就退出&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 例如指令 CMD service nginx start 会被理解为 CMD [ &quot;sh&quot;, &quot;-c&quot;, &quot;service nginx start&quot;]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 主进程实际上是sh，当service nginx start命令结束后，sh也就结束了，就会令容器退出&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 解决方法： 直接执行nginx可执行文件，并且要求以前台形式运行，如下所示&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;CMD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; [&quot;nginx&quot;, &quot;-g&quot;, &quot;daemon off;&quot;]&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# 当所创建的镜像作为其它新创建镜像的基础镜像时，所执行的操作指令&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 也就是本镜像被from时，自动立即执行的指令&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ONBUILD&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;ADD&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; . /app/src&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;ONBUILD RUN &lt;/span&gt;/usr/local/bin/python-build &lt;span class=&quot;nt&quot;&gt;--dir&lt;/span&gt; /app/src
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;最不容易发生变化的操作放在较低的镜像层中，这样在重新 build 镜像时就会使用前面 build 产生的缓存&lt;br /&gt;
编写完成&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;之后，可以通过&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker build&lt;/code&gt;命令来创建镜像，该命令将读取指定路径下（包括子目录）的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;文件，并将该路径下所有内容发送给&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Docker&lt;/code&gt;服务端，由服务端来创建镜像。因此一般建议放置&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;的目录为空目录。也可以通过&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.dockerignore&lt;/code&gt;文件（每一行添加一条匹配模式）来让&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Docker&lt;/code&gt;忽略路径下的目录和文件；要指定镜像的标签信息，可以通过&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t&lt;/code&gt;选项，例如：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo docker build -t myrepo/myapp:2.0 /tmp/test1/&lt;/code&gt;&lt;br /&gt;
&lt;strong&gt;注意&lt;/strong&gt;：对于使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;创建的镜像构建的容器来说，直接启动就会执行&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMD&lt;/code&gt;命令（或&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENTRYPOINT&lt;/code&gt;命令），所以如果是别人制作的镜像，例如&lt;a href=&quot;https://hub.docker.com/r/opendronemap/odm/dockerfile&quot;&gt;opendronemap/odm/dockerfile&lt;/a&gt;，我们很可能就无法进入容器内的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/bin/bash&lt;/code&gt;来执行其他操作。这时，使用如下命令启动容器就可以覆盖&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dockerfile&lt;/code&gt;的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ENTRYPOINT&lt;/code&gt;命令，来执行自己需要的命令：&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker run -it --entrypoint /bin/bash opendronemap/odm&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;6-docker-compose&quot;&gt;6. docker-compose&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/docker/compose&quot;&gt;docker-compose&lt;/a&gt;是定义和运行多个Docker容器的应用，它允许用户通过一个单独的&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt;模板文件来定义一组相关联的应用容器为一个项目。两个重要的概念：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;服务 (service)：一个应用的容器，实际上可以包括若干运行相同镜像的容器实例&lt;/li&gt;
  &lt;li&gt;项目 (project)：由一组关联的应用容器组成的一个完整业务单元，在&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker-compose.yml&lt;/code&gt;文件中定义&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;7-ubuntu不是wsl安装使用docker&quot;&gt;7. Ubuntu（不是WSL）安装使用Docker&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;卸载旧版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo apt-get remove docker docker-engine docker.io&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;添加apt源并安装：
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 添加使用 HTTPS 传输的软件包以及 CA 证书&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;apt-transport-https ca-certificates curl software-properties-common
&lt;span class=&quot;c&quot;&gt;# 由于国内网络问题，使用国内源；官方地址为 https://download.docker.com/linux/ubuntu/gpg&lt;/span&gt;
curl &lt;span class=&quot;nt&quot;&gt;-fsSL&lt;/span&gt; https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | &lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-key add -
&lt;span class=&quot;c&quot;&gt;# 向 source.list 中添加 Docker 软件源；官方地址为 https://download.docker.com/linux/ubuntu&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;add-apt-repository &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
 &lt;span class=&quot;s2&quot;&gt;&quot;deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;lsb_release &lt;span class=&quot;nt&quot;&gt;-cs&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;
 stable&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 更新 apt 软件包缓存&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update
&lt;span class=&quot;c&quot;&gt;# 安装 docker-ce&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;docker-ce
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;配置文件路径&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/docker/daemon.json&lt;/code&gt;，如果不存在则自己创建，添加以下内容：
    &lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;registry-mirrors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://hub-mirror.c.163.com&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
 &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://mirror.baidubce.com&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;然后重新启动服务：&lt;/p&gt;
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl restart docker
&lt;span class=&quot;c&quot;&gt;# 测试docker是否正确安装&lt;/span&gt;
docker run hello-world
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;建立 docker 用户组（可选）：默认情况下&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;命令会使用 Unix socket 与 Docker 引擎通讯。而只有&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;root&lt;/code&gt;用户和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;组的用户才可以访问 Docker 引擎的 Unix socket。因此，更好地做法是将需要使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;的用户加入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker&lt;/code&gt;用户组
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 建立 docker 组&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;groupadd docker
&lt;span class=&quot;c&quot;&gt;# 将当前用户加入 docker 组&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;usermod &lt;span class=&quot;nt&quot;&gt;-aG&lt;/span&gt; docker &lt;span class=&quot;nv&quot;&gt;$USER&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# 更新用户组&lt;/span&gt;
newgrp docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;p&gt;如果还是出现报错，那么登出再登入该用户。还是不可以的话，就重启机器再次尝试&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;设置开机自启以及手动启动Docker
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 设置Docker开机自启&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl &lt;span class=&quot;nb&quot;&gt;enable &lt;/span&gt;docker
&lt;span class=&quot;c&quot;&gt;# 启动Docker&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;systemctl start docker
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Wed, 16 Dec 2020 11:20:55 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2020/12/16/ubuntu_and_wsl2_config_docker/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2020/12/16/ubuntu_and_wsl2_config_docker/</guid>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Windows</category>
        
        <category>Python</category>
        
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Windows</category>
        
        <category>Python</category>
        
      </item>
    
      <item>
        <title>ubuntu系统配置基于CUDA 11.0的最新深度学习环境</title>
        <description>&lt;h2 class=&quot;no_toc&quot; id=&quot;目录&quot;&gt;目录&lt;/h2&gt;

&lt;ul id=&quot;markdown-toc&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#1-深度学习硬件环境参数&quot; id=&quot;markdown-toc-1-深度学习硬件环境参数&quot;&gt;1. 深度学习硬件环境参数&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#2-深度学习系统环境配置&quot; id=&quot;markdown-toc-2-深度学习系统环境配置&quot;&gt;2. 深度学习系统环境配置&lt;/a&gt;    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#21-安装nvidia驱动&quot; id=&quot;markdown-toc-21-安装nvidia驱动&quot;&gt;2.1 安装nvidia驱动&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#22-安装cuda&quot; id=&quot;markdown-toc-22-安装cuda&quot;&gt;2.2 安装CUDA&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#23-安装cudnn&quot; id=&quot;markdown-toc-23-安装cudnn&quot;&gt;2.3 安装cuDNN&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#3-python3软件环境配置&quot; id=&quot;markdown-toc-3-python3软件环境配置&quot;&gt;3. python3软件环境配置&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#4-ubuntu-2004系统注意事项&quot; id=&quot;markdown-toc-4-ubuntu-2004系统注意事项&quot;&gt;4. Ubuntu 20.04系统注意事项&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;1-深度学习硬件环境参数&quot;&gt;1. 深度学习硬件环境参数&lt;/h2&gt;
&lt;p&gt;服务器的硬件配置如下：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;CPU型号：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2 * (Intel Xeon Gold 5218 @ 2.3GHz * 32)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;内存大小：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;12 * (32GB 2663MHz)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;GPU型号：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8 * (GeForce GTX 2080 Ti)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;硬盘：
    &lt;ul&gt;
      &lt;li&gt;系统（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RAID 1&lt;/code&gt;）：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;2 * (960GB SSD) = 960GB&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;数据（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RAID 6&lt;/code&gt;）：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;6 * (10T HDD 7200rpm) = 40TB&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;系统和各基础软件的版本都在下表中列出：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;操作系统版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ubuntu 18.04-amd64&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;英伟达显卡驱动：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-driver-450&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;CUDA版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;11.0.3&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;cuDNN版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8.0.4&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Python版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3.6.9&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;tensorflow版本：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf-nightly-2.5.0.dev20201209&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;2-深度学习系统环境配置&quot;&gt;2. 深度学习系统环境配置&lt;/h2&gt;
&lt;h3 id=&quot;21-安装nvidia驱动&quot;&gt;2.1 安装nvidia驱动&lt;/h3&gt;
&lt;p&gt;目前我使用过的方法有三种，按照便捷程度依次降低的顺序来介绍&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;推荐方法（在图形窗口操作）：
    &lt;ul&gt;
      &lt;li&gt;打开软件&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Software &amp;amp; Updates&lt;/code&gt;（系统和更新）&lt;/li&gt;
      &lt;li&gt;点击选项&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Additional drivers&lt;/code&gt;（附加驱动）&lt;/li&gt;
      &lt;li&gt;选定&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia driver meta nvidia-450&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;点击按钮&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Apply changes&lt;/code&gt;（应用更改）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;备用方法：
    &lt;ul&gt;
      &lt;li&gt;打开终端，依次输入以下命令：
        &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;add-apt-repository ppa:graphics-drivers/ppa
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;nvidia-driver-450
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;        &lt;/div&gt;
      &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;最后的方法：访问nvidia官网下载&lt;a href=&quot;https://www.nvidia.com/Download/driverResults.aspx/164073/en-us&quot;&gt;适用于ubuntu的驱动包&lt;/a&gt;，一般为&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.run&lt;/code&gt;格式。然后在终端运行，根据提示操作即可&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不管哪种方法，都需要重启电脑。然后，在终端输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nvidia-smi&lt;/code&gt;命令得到如下示例输出则表明安装成功&lt;/p&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Thu Dec 10 15:42:47 2020       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.80.02    Driver Version: 450.80.02    CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce RTX 208...  Off  | 00000000:3D:00.0 Off |                  N/A |
| 28%   30C    P8     9W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   1  GeForce RTX 208...  Off  | 00000000:3E:00.0 Off |                  N/A |
| 27%   29C    P8     5W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   2  GeForce RTX 208...  Off  | 00000000:40:00.0 Off |                  N/A |
| 27%   29C    P8    17W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   3  GeForce RTX 208...  Off  | 00000000:41:00.0 Off |                  N/A |
| 27%   28C    P8    22W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   4  GeForce RTX 208...  Off  | 00000000:B1:00.0 Off |                  N/A |
| 27%   29C    P8     3W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   5  GeForce RTX 208...  Off  | 00000000:B2:00.0 Off |                  N/A |
| 27%   29C    P8    14W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   6  GeForce RTX 208...  Off  | 00000000:B4:00.0 Off |                  N/A |
| 29%   31C    P8    20W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
|   7  GeForce RTX 208...  Off  | 00000000:B5:00.0 Off |                  N/A |
| 27%   29C    P8     7W / 250W |      6MiB / 11019MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    1   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    2   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    3   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    4   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    5   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    6   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
|    7   N/A  N/A     16810      G   /usr/lib/xorg/Xorg                  4MiB |
+-----------------------------------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&quot;22-安装cuda&quot;&gt;2.2 安装CUDA&lt;/h3&gt;
&lt;p&gt;访问&lt;a href=&quot;https://developer.nvidia.com/cuda-11.0-update1-download-archive?target_os=Linux&amp;amp;target_arch=x86_64&amp;amp;target_distro=Ubuntu&amp;amp;target_version=1804&amp;amp;target_type=deblocal&quot; title=&quot;CUDA 11.0 Update 1的下载网址&quot;&gt;CUDA 11.0 Update 1的下载网址&lt;/a&gt;，选择适合自己操作系统版本的文件下载，然后打开终端依次输入以下命令：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin
&lt;span class=&quot;nb&quot;&gt;sudo mv &lt;/span&gt;cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600
wget https://developer.download.nvidia.com/compute/cuda/11.0.3/local_installers/cuda-repo-ubuntu1804-11-0-local_11.0.3-450.51.06-1_amd64.deb
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; cuda-repo-ubuntu1804-11-0-local_11.0.3-450.51.06-1_amd64.deb
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-key add /var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;cuda
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;此时CUDA以及安装完毕，在终端输入&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cd /usr/local/cuda-11.0/bin &amp;amp;&amp;amp; ./nvcc -V&lt;/code&gt;命令得到如下示例输出则表明安装成功&lt;/p&gt;
&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Wed_Jul_22_19:09:09_PDT_2020
Cuda compilation tools, release 11.0, V11.0.221
Build cuda_11.0_bu.TC445_37.28845127_0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;但是，为了方便下面深度学习软件的使用，还要把相关路径加入PATH。打开文件&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;~/.profile&lt;/code&gt;（若不存在则新建） ，在文档末尾添加以下内容：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# set PATH for cuda 11.0 installation&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/usr/local/cuda-11.0/bin/&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/cuda-11.0/bin&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;:+:&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PATH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}}&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/cuda-11.0/lib64&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LD_LIBRARY_PATH&lt;/span&gt;:+:&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;LD_LIBRARY_PATH&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;重启计算机即可使环境变量生效&lt;/p&gt;
&lt;h3 id=&quot;23-安装cudnn&quot;&gt;2.3 安装cuDNN&lt;/h3&gt;
&lt;p&gt;打开&lt;a href=&quot;https://developer.nvidia.com/rdp/cudnn-archive&quot; title=&quot;cuDNN的下载网址&quot;&gt;cuDNN的下载网址&lt;/a&gt;，然后点击&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuDNN v8.0.4 (September 28th, 2020), for CUDA 11.0&lt;/code&gt;并根据自己的操作系统选择合适的版本。其中，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuDNN Runtime Library&lt;/code&gt;和&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuDNN Developer Library&lt;/code&gt;是必须要下载的，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cuDNN Code Samples and User Guide&lt;/code&gt;为可选项目。然后依次安装前面下载的3个文件：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; libcudnn8_8.0.4.30-1+cuda11.0_amd64.deb
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; libcudnn8-dev_8.0.4.30-1+cuda11.0_amd64.deb
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dpkg &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; libcudnn8-samples_8.0.4.30-1+cuda11.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;此时，显卡已经配置完成&lt;/p&gt;
&lt;h2 id=&quot;3-python3软件环境配置&quot;&gt;3. python3软件环境配置&lt;/h2&gt;
&lt;p&gt;创建基于python3的虚拟环境，然后安装深度学习需要用到的库：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# 安装python3开发库&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt-get &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;python3-pip python3-venv
&lt;span class=&quot;c&quot;&gt;# 创建名称为myvenv的虚拟环境&lt;/span&gt;
python3 &lt;span class=&quot;nt&quot;&gt;-m&lt;/span&gt; venv myvenv
&lt;span class=&quot;c&quot;&gt;# 激活myvenv虚拟环境&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;source &lt;/span&gt;myvenv/bin/activate
&lt;span class=&quot;c&quot;&gt;# pip安装深度学习相关第三方库&lt;/span&gt;
pip3 &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;tf-nightly &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; https://pypi.python.org/simple
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;确保下载的是&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tf-nightly-2.5.0.dev20201209&lt;/code&gt;（目前的最新版）&lt;/li&gt;
  &lt;li&gt;使用&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pypi&lt;/code&gt;的镜像源可能导致版本不是最新的&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tensorflow&lt;/code&gt;包目前还不支持&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CUDA 11.0&lt;/code&gt;，它最高支持&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CUDA 10.1&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;如果安装&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tensorflow&lt;/code&gt;遇到报错&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;launchpadlib 1.10.6 requires testresources, which is not installed&lt;/code&gt;，执行以下代码：
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# sudo apt install python3-widgetsnbextension&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;python3-testresources
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
    &lt;h2 id=&quot;4-ubuntu-2004系统注意事项&quot;&gt;4. Ubuntu 20.04系统注意事项&lt;/h2&gt;
  &lt;/li&gt;
  &lt;li&gt;不同之处：CUDA版本号不变，但选择用于&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ubuntu 20.04&lt;/code&gt;系统&lt;/li&gt;
  &lt;li&gt;不同之处：cuDNN版本选择&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;8.0.5&lt;/code&gt;且用于&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ubuntu 20.04&lt;/code&gt;系统&lt;/li&gt;
  &lt;li&gt;其他步骤同Ubuntu 18.04&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 13 Dec 2020 17:24:01 +0800</pubDate>
        <link>https://whuzfb.cn/blog/2020/12/13/ubuntu_config_deep_learning_new/</link>
        <guid isPermaLink="true">https://whuzfb.cn/blog/2020/12/13/ubuntu_config_deep_learning_new/</guid>
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Python</category>
        
        
        <category>Ubuntu</category>
        
        <category>Linux</category>
        
        <category>Python</category>
        
      </item>
    
  </channel>
</rss>