在Linux下通过Docker运行Code Composer Studio

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-ccstudio说明" id="markdown-toc-1-ccstudio说明">1. CCStudio说明</a> <ul> <li><a href="#11-软件配置情况" id="markdown-toc-11-软件配置情况">1.1 软件配置情况</a></li> </ul> </li> <li><a href="#2-构建镜像" id="markdown-toc-2-构建镜像">2. 构建镜像</a> <ul> <li><a href="#21-自动" id="markdown-toc-21-自动">2.1 自动</a></li> <li><a href="#22-手动" id="markdown-toc-22-手动">2.2 手动</a></li> </ul> </li> <li><a href="#3-运行容器" id="markdown-toc-3-运行容器">3. 运行容器</a></li> <li><a href="#4-ccstudio组件" id="markdown-toc-4-ccstudio组件">4. CCStudio组件</a></li> <li><a href="#5-其他参考" id="markdown-toc-5-其他参考">5. 其他参考</a></li> </ul> <h2 id="1-ccstudio说明">1. CCStudio说明</h2> <p>Docker镜像可在以下位置获取:</p> <ul> <li><a href="https://hub.docker.com/r/whuzfb/ccstudio">Dockerhub: whuzfb/ccstudio</a></li> <li><a href="https://github.com/zfb132/ccstudio/pkgs/container/ccstudio">GHCR: zfb132/ccstudio</a></li> </ul> <h3 id="11-软件配置情况">1.1 软件配置情况</h3> <ol> <li>目前理论上支持的<a href="https://www.ti.com/tool/CCSTUDIO">CCStudio</a>版本: <ul> <li>10.x(已测试版本<code class="language-plaintext highlighter-rouge">10.0.0.00010</code>、<code class="language-plaintext highlighter-rouge">10.4.0.00006</code>)</li> <li>11.x(已测试版本<code class="language-plaintext highlighter-rouge">11.0.0.00012</code>、<code class="language-plaintext highlighter-rouge">11.2.0.00007</code>)</li> <li>12.x(已测试版本<code class="language-plaintext highlighter-rouge">12.0.0.00009</code>、<code class="language-plaintext highlighter-rouge">12.8.1.00005</code>)</li> <li>20.x(已测试版本<code class="language-plaintext highlighter-rouge">20.2.0.00012</code>)</li> </ul> </li> <li>支持的Ubuntu版本: ubuntu 20.04及以上版本(已测试版本<code class="language-plaintext highlighter-rouge">20.04</code>、<code class="language-plaintext highlighter-rouge">22.04</code>、<code class="language-plaintext highlighter-rouge">24.04</code>)</li> <li>支持安装指定版本的<a href="https://www.ti.com/tool/MMWAVE-SDK">mmWave SDK</a>,已测试版本<code class="language-plaintext highlighter-rouge">03.06.02.00-LTS</code></li> <li>支持安装指定版本的<a href="https://software-dl.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/bios/sysbios/">SYS/BIOS</a>,已测试版本<code class="language-plaintext highlighter-rouge">6.73.01.01</code></li> </ol> <p><a href="https://github.com/zfb132/ccstudio">zfb132/ccstudio</a>目的是提供一个在Linux系统上安装<a href="https://www.ti.com/tool/CCSTUDIO">Code Composer Studio</a>的Docker镜像,方便在Linux系统(无桌面环境)上使用CCStudio进行TI芯片的开发,尤其是适用于CI/CD场景。用户也可以参考仓库的<a href="https://github.com/zfb132/ccstudio/blob/main/configure.sh">configure.sh</a>脚本在自己的Linux系统上安装CCStudio</p> <p>容器内部最重要的三个目录:</p> <ul> <li><code class="language-plaintext highlighter-rouge">/ccs_projects</code>:CCStudio项目目录(运行容器必须挂载本地目录到此目录,因为entrypoint.sh脚本会在此目录下查找项目文件)</li> <li><code class="language-plaintext highlighter-rouge">/workspaces</code>:CCStudio工作空间目录(容器内部CCS的工作空间目录为/workspaces,编译结果也存放在此目录下)</li> <li><code class="language-plaintext highlighter-rouge">/opt/ti</code>:TI系列产品的安装目录(容器内部CCStudio、mmwave SDK、SYS/BIOS的安装目录)</li> </ul> <p>不同版本的CCStudio在Linux系统的安装说明:</p> <ul> <li><a href="https://software-dl.ti.com/ccs/esd/documents/ccs_linux_host_support.html">CCS Linux Host Support</a></li> <li><a href="https://software-dl.ti.com/ccs/esd/documents/ccsv12_linux_host_support.html">CCS Linux Host Support v12</a></li> <li><a href="https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_installation.html">CCS Installation Guide v20</a></li> </ul> <p>不同版本的CCStudio命令行程序的使用说明:</p> <ul> <li><a href="https://software-dl.ti.com/ccs/esd/documents/ccs_projects-command-line.html">CCS Command Line Interface (v12 and below)</a></li> <li><a href="https://software-dl.ti.com/ccs/esd/documents/users_guide/ccs_project-command-line.html">CCS Command Line Interface (v20 and above)</a></li> </ul> <h2 id="2-构建镜像">2. 构建镜像</h2> <h3 id="21-自动">2.1 自动</h3> <p>使用<code class="language-plaintext highlighter-rouge">make</code>命令自动构建镜像</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 查看可用的目标</span> make list <span class="c"># 构建指定的镜像</span> make ubuntu24.04-20.2.0.00012-mmw <span class="c"># 逐个构建镜像</span> make all <span class="c"># 并行构建镜像(但是输出日志会混在一起)</span> make <span class="nt">-j</span> <span class="si">$(</span><span class="nb">nproc</span><span class="si">)</span> all <span class="c"># 生成docker-compose.yaml文件用于并行构建镜像</span> make gen_compose <span class="c"># 使用docker-compose构建镜像</span> docker compose <span class="nt">-f</span> docker-compose.yaml <span class="nt">--parallel</span> 2 build </code></pre></div></div> <h3 id="22-手动">2.2 手动</h3> <p>构建镜像的脚本如下:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># --network host</span> <span class="c"># --build-arg "HTTP_PROXY=http://127.0.0.1:9900/" \</span> <span class="c"># --build-arg "HTTPS_PROXY=http://127.0.0.1:9900/" \</span> <span class="c"># --progress=plain --no-cache</span> <span class="c"># MMWSDK_COMPONENTS或BIOS_VERSION参数若为空,表示不安装对应组件</span> <span class="nb">export </span><span class="nv">UBUNTU_VERSION</span><span class="o">=</span>24.04 <span class="nb">export </span><span class="nv">CCSTUDIO_VERSION</span><span class="o">=</span>20.2.0.00012 <span class="nb">export </span><span class="nv">CCS_COMPONENTS</span><span class="o">=</span><span class="s2">"PF_MMWAVE,PF_C6000SC,PF_TM4C"</span> <span class="nb">export </span><span class="nv">MMWSDK_VERSION</span><span class="o">=</span><span class="s2">"03.06.02.00-LTS"</span> <span class="nb">export </span><span class="nv">MMWSDK_COMPONENTS</span><span class="o">=</span><span class="s2">"ALL"</span> <span class="nb">export </span><span class="nv">BIOS_VERSION</span><span class="o">=</span><span class="s2">"6.73.01.01"</span> <span class="c"># 使用major.minor版本号作为ccstudio版本标识</span> <span class="nb">export </span><span class="nv">CCS_VERSION_SHORT</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="k">${</span><span class="nv">CCSTUDIO_VERSION</span><span class="k">}</span> | <span class="nb">cut</span> <span class="nt">-d</span> <span class="s1">'.'</span> <span class="nt">-f</span> 1-2<span class="si">)</span> <span class="nb">export </span><span class="nv">tag</span><span class="o">=</span><span class="s2">"whuzfb/ccstudio:</span><span class="k">${</span><span class="nv">CCS_VERSION_SHORT</span><span class="k">}</span><span class="s2">-ubuntu</span><span class="k">${</span><span class="nv">UBUNTU_VERSION</span><span class="k">}</span><span class="s2">"</span> docker build <span class="nt">-t</span> <span class="k">${</span><span class="nv">tag</span><span class="k">}</span> <span class="nb">.</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"OS_VERSION=</span><span class="k">${</span><span class="nv">UBUNTU_VERSION</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"CCS_VERSION=</span><span class="k">${</span><span class="nv">CCSTUDIO_VERSION</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"CCS_COMPONENTS=</span><span class="k">${</span><span class="nv">CCS_COMPONENTS</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"MMWSDK_VERSION=</span><span class="k">${</span><span class="nv">MMWSDK_VERSION</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"MMWSDK_COMPONENTS=</span><span class="k">${</span><span class="nv">MMWSDK_COMPONENTS</span><span class="k">}</span><span class="s2">"</span> <span class="se">\</span> <span class="nt">--build-arg</span> <span class="s2">"BIOS_VERSION=</span><span class="k">${</span><span class="nv">BIOS_VERSION</span><span class="k">}</span><span class="s2">"</span> </code></pre></div></div> <h2 id="3-运行容器">3. 运行容器</h2> <p>从Docker Hub拉取镜像<a href="https://hub.docker.com/r/whuzfb/ccstudio">whuzfb/ccstudio</a>:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 拉取最新版本的ccstudio镜像(20.2-ubuntu24.04-mmw)</span> docker pull whuzfb/ccstudio:latest </code></pre></div></div> <p>或者使用本地构建的镜像</p> <p>挂载本地的ccs项目目录到容器内的<code class="language-plaintext highlighter-rouge">/ccs_projects</code>目录下并启动构建:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 假设本地项目目录为 ./mmw_oob</span> git clone <span class="nt">--recursive</span> https://github.com/zfb132/mmw_oob.git ./mmw_oob <span class="c"># 该目录下包含out_of_box_6843_isk_mss.projectspec文件,且包含Debug编译配置</span> <span class="c"># 运行以下命令可以在容器内编译该项目</span> <span class="c"># 如果需要保存结果,那么使用 -v ./results:/workspaces (容器内部CCS的工作目录为/workspaces)</span> <span class="c"># 默认时区为UTC,可以通过设置 -e TZ=... 来更改时区(例如 -e TZ=Asia/Shanghai)</span> <span class="nb">mkdir</span> ./results docker run <span class="se">\</span> <span class="nt">-e</span> <span class="nv">TZ</span><span class="o">=</span>Asia/Shanghai <span class="se">\</span> <span class="nt">-v</span> ./mmw_oob:/ccs_projects <span class="se">\</span> <span class="nt">-v</span> ./results:/workspaces <span class="se">\</span> <span class="nt">-it</span> <span class="nt">--rm</span> <span class="nt">--name</span> ccstudio whuzfb/ccstudio:latest <span class="se">\</span> <span class="s2">"out_of_box_6843_isk_mss.projectspec"</span> <span class="s2">"Debug"</span> </code></pre></div></div> <h2 id="4-ccstudio组件">4. CCStudio组件</h2> <p><a href="https://software-dl.ti.com/ccs/esd/documents/ccs_installer-cli.html">可安装的产品系列</a>列表:</p> <table> <thead> <tr> <th style="text-align: center">Product family</th> <th style="text-align: center">Description</th> <th style="text-align: center">OS</th> </tr> </thead> <tbody> <tr> <td style="text-align: center">PF_MSP430</td> <td style="text-align: center">MSP430 ultra-low power MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_MSP432</td> <td style="text-align: center">SimpleLink™ MSP432™ low power + performance MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_CC2X</td> <td style="text-align: center">SimpleLink™ CC13xx and CC26xx Wireless MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_CC3X</td> <td style="text-align: center">SimpleLink™ Wi-Fi® CC32xx Wireless MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_CC2538</td> <td style="text-align: center">CC2538 IEEE 802.15.4 Wireless MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_C28</td> <td style="text-align: center">C2000 real-time MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_TM4C</td> <td style="text-align: center">TM4C12x ARM® Cortex®-M4F core-based MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_PGA</td> <td style="text-align: center">PGA Sensor Signal Conditioners</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_HERCULES</td> <td style="text-align: center">Hercules™ Safety MCUs</td> <td style="text-align: center">windows-x64, linux-x64, osx</td> </tr> <tr> <td style="text-align: center">PF_SITARA</td> <td style="text-align: center">Sitara™ AM3x, AM4x, AM5x and AM6x MPUs (will also include AM2x for CCS 10.x)</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_SITARA_MCU</td> <td style="text-align: center">Sitara™ AM2x MCUs (only supported in CCS 11.x and greater)</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_OMAPL</td> <td style="text-align: center">OMAP-L1x DSP + ARM9® Processor</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_DAVINCI</td> <td style="text-align: center">DaVinci (DM) Video Processors</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_OMAP</td> <td style="text-align: center">OMAP Processors</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_TDA_DRA</td> <td style="text-align: center">TDAx Driver Assistance SoCs &amp; Jacinto DRAx Infotainment SoCs</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_C55</td> <td style="text-align: center">C55x ultra-low-power DSP</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_C6000SC</td> <td style="text-align: center">C6000 Power-Optimized DSP</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_C66AK_KEYSTONE</td> <td style="text-align: center">66AK2x multicore DSP + ARM® Processors &amp; C66x KeyStone™ multicore DSP</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_MMWAVE</td> <td style="text-align: center">mmWave Sensors</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_C64MC</td> <td style="text-align: center">C64x multicore DSP</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> <tr> <td style="text-align: center">PF_DIGITAL_POWER</td> <td style="text-align: center">UCD Digital Power Controllers</td> <td style="text-align: center">windows-x64, linux-x64</td> </tr> </tbody> </table> <h2 id="5-其他参考">5. 其他参考</h2> <ul> <li><a href="https://github.com/zfb132/ccstudio">zfb132/ccstudio</a></li> <li><a href="https://github.com/zfb132/mmw_oob">zfb132/mmw_oob</a></li> <li><a href="https://github.com/uoohyo/docker-ccstudio-ide">uoohyo/ccstudio-ide</a></li> <li><a href="https://github.com/uoohyo/action-ccstudio-ide">uoohyo/action-ccstudio-ide</a></li> <li><a href="https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1412767/ccstudio-code-composer-studio-12-8-and-uniflash-8-7-on-ubuntu-24-04">ccstudio code composer studio 12.8 and uniflash 8.7 on ubuntu 24.04</a></li> <li><a href="https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1532443/codecomposer-installing-ccs-20-2-0-into-a-docker-container">codecomposer installing ccs 20.2.0 into a docker container</a></li> </ul>

2025/7/21
阅读更多

Windows电脑配置以太网口访问雷达

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-总体说明" id="markdown-toc-1-总体说明">1. 总体说明</a></li> <li><a href="#2-windows电脑配置以太网口" id="markdown-toc-2-windows电脑配置以太网口">2. windows电脑配置以太网口</a></li> <li><a href="#3-雷达配置ip和网关和路由" id="markdown-toc-3-雷达配置ip和网关和路由">3. 雷达配置ip和网关和路由</a></li> <li><a href="#4-windows开启路由转发功能" id="markdown-toc-4-windows开启路由转发功能">4. windows开启路由转发功能</a></li> <li><a href="#5-windows配置以太网共享无线网络" id="markdown-toc-5-windows配置以太网共享无线网络">5. windows配置以太网共享无线网络</a></li> </ul> <h2 id="1-总体说明">1. 总体说明</h2> <p>适用情况: 目的只是调试雷达,且当前没有配置好的交换机或路由器<br /> 主要功能: 把雷达的以太网口<code class="language-plaintext highlighter-rouge">eth1</code>连接到windows电脑的以太网口(此时两者即可互相ping通,可以ssh),还可以通过windows电脑的无线网络让雷达连接到互联网</p> <p>其中雷达的<code class="language-plaintext highlighter-rouge">eth1</code>口配置如下</p> <ul> <li>IP地址示例: <code class="language-plaintext highlighter-rouge">192.168.19.241</code></li> <li>子网掩码示例: <code class="language-plaintext highlighter-rouge">255.255.255.0</code></li> <li>网关示例: <code class="language-plaintext highlighter-rouge">192.168.19.244</code>(可以自行修改为其他ip,只要与windows电脑的以太网口IP地址一致即可,例如<code class="language-plaintext highlighter-rouge">192.168.19.254</code>)</li> </ul> <p>windows电脑的以太网口配置如下</p> <ul> <li>IP地址示例: <code class="language-plaintext highlighter-rouge">192.168.19.244</code>(只要与雷达网关一致即可,例如<code class="language-plaintext highlighter-rouge">192.168.19.254</code>)</li> <li>子网掩码示例: <code class="language-plaintext highlighter-rouge">255.255.255.0</code></li> <li>网关: 留空</li> </ul> <p>windows电脑可以替换为其他Linux电脑,配置方法类似</p> <h2 id="2-windows电脑配置以太网口">2. windows电脑配置以太网口</h2> <ol> <li>打开<code class="language-plaintext highlighter-rouge">控制面板</code> -&gt; <code class="language-plaintext highlighter-rouge">网络和Internet</code> -&gt; <code class="language-plaintext highlighter-rouge">网络和共享中心</code> -&gt; <code class="language-plaintext highlighter-rouge">更改适配器设置</code></li> <li>然后再手动修改windows的以太网适配器的IP地址是<code class="language-plaintext highlighter-rouge">192.168.19.244</code>(也可以是<code class="language-plaintext highlighter-rouge">192.168.19.254</code>),子网掩码是<code class="language-plaintext highlighter-rouge">255.255.255.0</code>,保存即可(该适配器可能会显示为<code class="language-plaintext highlighter-rouge">未识别的网络</code>,属性信息里面IPv4和IPv6可能会提示无法获取Internet访问权限,这是正常的)</li> </ol> <h2 id="3-雷达配置ip和网关和路由">3. 雷达配置ip和网关和路由</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 查看当前网络信息(发现eth1的ip地址是192.168.19.241)</span> ip a <span class="c"># 1: 1o:&lt;L0OPBACK,UP,LOWER UP&gt; mtu 16436 qdisc noqueue state UNKNOWN</span> <span class="c"># link/loopback 00:00:00:00:00:00 brd60:00:00:00:00:00</span> <span class="c"># inet 127.0.0.1/8 scope host lo</span> <span class="c"># inet6 ::1/128 scope host</span> <span class="c"># valid lft forever preferred lft forever</span> <span class="c"># 2: eth0: &lt;NO-CARRIER,BROADCAST,MULTICAST,UP&gt; mtu 1500 qdisc pfifo fast state DOWN qlen 1000</span> <span class="c"># link/ether 00:0a:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff</span> <span class="c"># inet 192.168.1.0/24 brd 192.168.1.255 scope global eth0</span> <span class="c"># 3: eth1: &lt;BROADCAST,MULTICAST,UP,LOWER UP&gt; mtu 1500 qdisc pfifo fast state UNKNOWN qlen 1000</span> <span class="c"># link/ether 08:1f:ff:ff:ff:ff brd ff:ff:ff:ff:ff:ff</span> <span class="c"># inet 192.168.19.241/24 brd 192.168.19.255 scope global eth1</span> <span class="c"># inet6 fe80::alf:7lff:fe03:bbc/64 scope link</span> <span class="c"># valid lft forever preferred lft forever</span> <span class="c"># 4: eth2: &lt;BROADCAST,MULTICAST,UP,LOWER UP&gt; mtu 1500 qdisc pfifo fast state UP qlen 1000</span> <span class="c"># link/ether 00:0b:bb:bb:bb:bb brd ff:ff:ff:ff:ff:ff</span> <span class="c"># inet 172.16.1.0/16 brd 172.16.255.255 scope global eth2</span> <span class="c"># inet6 fe80::20b:abff:fed3:2b52/64 scope link</span> <span class="c"># valid lft forever preferred lft forever</span> <span class="c"># 查看默认网关(发现eth1的网关是192.168.19.254)</span> route <span class="nt">-n</span> <span class="c"># Kernel Ip routing table</span> <span class="c"># Destination Gateway Genmask Flags Metric Ref User Iface</span> <span class="c"># 192.168.19.0 0.0.0.0 255.255.255.0 U 0 0 0 eth1</span> <span class="c"># 192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0</span> <span class="c"># 172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth2</span> <span class="c"># 127.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 lo</span> <span class="c"># 0.0.0.0 192.168.19.254 0.0.0.0 UG 0 0 0 eth1</span> </code></pre></div></div> <p>如果不想对雷达进行任何修改,则直接把windows电脑的以太网口IP地址修改为<code class="language-plaintext highlighter-rouge">192.168.19.254</code>,子网掩码是<code class="language-plaintext highlighter-rouge">255.255.255.0</code>,保存即可。雷达会通过<code class="language-plaintext highlighter-rouge">eth1</code>口(ip地址是<code class="language-plaintext highlighter-rouge">192.168.19.241</code>)经由windows电脑的以太网口(ip地址是<code class="language-plaintext highlighter-rouge">192.168.19.254</code>)互相访问。</p> <p>如果希望自定义雷达的IP和网关,则可以在雷达上执行以下命令:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 切换到root用户(192.168.19.241是自己设置的eth1口IP地址,只要与windows电脑的以太网口IP地址在同一网段即可)</span> ifconfig eth1 192.168.19.241 netmask 255.255.255.0 up <span class="c"># 删除默认网关</span> route del default <span class="c"># 添加新的默认网关(这里的网关是windows电脑的以太网口IP地址)</span> route add default gw 192.168.19.244 eth1 </code></pre></div></div> <p>此时在windows电脑上可以通过ssh连接到雷达:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ssh username@192.168.19.241 </code></pre></div></div> <p>但是如果想让雷达访问互联网,则需要在windows电脑上开启网络转发功能,并配置以太网共享无线网络。</p> <h2 id="4-windows开启路由转发功能">4. windows开启路由转发功能</h2> <ol> <li>修改注册表:以管理员身份打开cmd,输入以下命令 <pre><code class="language-regedit"> reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v IPEnableRouter /D 1 /f </code></pre> </li> <li>启动<code class="language-plaintext highlighter-rouge">Routing and Remote Access</code>服务:以管理员身份打开cmd,输入以下命令 <pre><code class="language-pwsh"> # 如果报错,就手动去服务中启动 sc config RemoteAccess start=auto sc start RemoteAccess sc query RemoteAccess </code></pre> </li> </ol> <h2 id="5-windows配置以太网共享无线网络">5. windows配置以太网共享无线网络</h2> <ol> <li>配置共享地址段(防止在共享WLAN给ethernet时,弹出对话框提示以太网的ip地址只能是<code class="language-plaintext highlighter-rouge">192.168.137.1</code>) 以管理员身份打开cmd,输入以下命令 <pre><code class="language-reg"> reg add "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters" -v ScopeAddress -d 192.168.19.142 -f reg add "HKLM\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters" -v ScopeAddressBackup -d 192.168.19.142 -f </code></pre> <p>此处只要<code class="language-plaintext highlighter-rouge">ScopeAddress</code>和<code class="language-plaintext highlighter-rouge">ScopeAddressBackup</code>的网段是<code class="language-plaintext highlighter-rouge">192.168.19.x</code>即可</p> </li> <li>打开<code class="language-plaintext highlighter-rouge">控制面板</code> -&gt; <code class="language-plaintext highlighter-rouge">网络和Internet</code> -&gt; <code class="language-plaintext highlighter-rouge">网络和共享中心</code> -&gt; <code class="language-plaintext highlighter-rouge">更改适配器设置</code></li> <li>右键点击<code class="language-plaintext highlighter-rouge">无线网络连接</code> -&gt; <code class="language-plaintext highlighter-rouge">属性</code> -&gt; <code class="language-plaintext highlighter-rouge">共享</code>选项卡</li> <li>勾选<code class="language-plaintext highlighter-rouge">允许其他网络用户通过此计算机的Internet连接来连接</code>,在下拉框中选择<code class="language-plaintext highlighter-rouge">以太网</code>(即windows与雷达连接网线后出现的网络适配器),点击<code class="language-plaintext highlighter-rouge">确定</code></li> </ol> <p>此时雷达就可以通过windows电脑的无线网络访问互联网了,直接在雷达上执行以下命令测试:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ping baidu.com </code></pre></div></div> <p>关于如何使用frp配置远程访问,参考<a href="https://blog.whuzfb.cn/blog/2020/07/05/remote_access_lan_gui/">远程访问安装xfce4的内网服务器</a></p>

2025/5/26
阅读更多

使用ffmpeg对视频和音频文件进行处理

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#0-常用命令说明" id="markdown-toc-0-常用命令说明">0. 常用命令说明</a></li> <li><a href="#1-倍速播放" id="markdown-toc-1-倍速播放">1. 倍速播放</a> <ul> <li><a href="#11-视频画面倍速播放" id="markdown-toc-11-视频画面倍速播放">1.1 视频画面倍速播放</a></li> <li><a href="#12-音频倍速播放" id="markdown-toc-12-音频倍速播放">1.2 音频倍速播放</a></li> <li><a href="#13-视频画面和音频倍速播放" id="markdown-toc-13-视频画面和音频倍速播放">1.3 视频画面和音频倍速播放</a></li> </ul> </li> <li><a href="#2-视频片段裁剪" id="markdown-toc-2-视频片段裁剪">2. 视频片段裁剪</a> <ul> <li><a href="#21-获取视频的分辨率" id="markdown-toc-21-获取视频的分辨率">2.1 获取视频的分辨率</a></li> <li><a href="#22-截取指定时长的视频片段" id="markdown-toc-22-截取指定时长的视频片段">2.2 截取指定时长的视频片段</a></li> <li><a href="#23-裁剪视频画面尺寸" id="markdown-toc-23-裁剪视频画面尺寸">2.3 裁剪视频画面尺寸</a></li> </ul> </li> <li><a href="#3-视频导出图片" id="markdown-toc-3-视频导出图片">3. 视频导出图片</a></li> <li><a href="#4-从图片集创建gif文件" id="markdown-toc-4-从图片集创建gif文件">4. 从图片集创建GIF文件</a></li> <li><a href="#5-提取视频文件的音频" id="markdown-toc-5-提取视频文件的音频">5. 提取视频文件的音频</a></li> <li><a href="#6-把音频和画面合并为新的视频" id="markdown-toc-6-把音频和画面合并为新的视频">6. 把音频和画面合并为新的视频</a></li> <li><a href="#7-下载m3u8文件为ts文件" id="markdown-toc-7-下载m3u8文件为ts文件">7. 下载m3u8文件为.ts文件</a></li> <li><a href="#8-批量提取视频关键帧" id="markdown-toc-8-批量提取视频关键帧">8. 批量提取视频关键帧</a></li> </ul> <h2 id="0-常用命令说明">0. 常用命令说明</h2> <p>ffmpeg是一个命令行工具,所有的操作都是通过命令行来完成的,下面是一些常用的命令说明</p> <ul> <li><code class="language-plaintext highlighter-rouge">-vcodec codec</code>:强制使用<code class="language-plaintext highlighter-rouge">codec</code>编解码方式(<code class="language-plaintext highlighter-rouge">copy</code>代表不进行重新编码)</li> <li><code class="language-plaintext highlighter-rouge">-acodec copy</code>:表示音频不做新的编码,直接把原来的复制过来</li> <li><code class="language-plaintext highlighter-rouge">-vcodec copy</code>:表示视频不做新的编码,直接把原来的复制过来</li> <li><code class="language-plaintext highlighter-rouge">-threads 5</code>:指定<code class="language-plaintext highlighter-rouge">5</code>个线程同时转换</li> <li><code class="language-plaintext highlighter-rouge">-vn</code>:取消视频的输出</li> <li><code class="language-plaintext highlighter-rouge">-an</code>:取消音频轨</li> <li><code class="language-plaintext highlighter-rouge">-ab 160000</code>:设置比特率(单位为<code class="language-plaintext highlighter-rouge">bit/s</code>)</li> <li><code class="language-plaintext highlighter-rouge">-ar 8000</code>:设置音频采样率(单位为<code class="language-plaintext highlighter-rouge">Hz</code>)</li> <li><code class="language-plaintext highlighter-rouge">-ac 1</code>:设置声道数,<code class="language-plaintext highlighter-rouge">1</code>就是单声道,<code class="language-plaintext highlighter-rouge">2</code>就是立体声</li> </ul> <h2 id="1-倍速播放">1. 倍速播放</h2> <h3 id="11-视频画面倍速播放">1.1 视频画面倍速播放</h3> <p>把输入的视频文件,画面播放速度快放到原来的2倍,保存为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i input.mp4 -filter:v "setpts=0.5*PTS" output.mp4</code></p> <h3 id="12-音频倍速播放">1.2 音频倍速播放</h3> <p>把输入的视频文件,音频播放速度快放到原来的2倍,保存为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i input.mp4 -filter:a "atempo=2.0" output.mp4</code></p> <h3 id="13-视频画面和音频倍速播放">1.3 视频画面和音频倍速播放</h3> <p>把输入的视频文件,画面播放速度快放到原来的2倍,音频播放速度快放到原来的2倍,保存为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i input.mp4 -filter_complex "[0:v]setpts=0.5*PTS[v];[0:a]atempo=2.0[a]" -map "[v]" -map "[a]" output.mp4</code></p> <h2 id="2-视频片段裁剪">2. 视频片段裁剪</h2> <h3 id="21-获取视频的分辨率">2.1 获取视频的分辨率</h3> <p>方法一:获取视频的分辨率,以默认分隔符分割<br /> <code class="language-plaintext highlighter-rouge">ffprobe -v error -show_entries stream=width,height -of csv=p=0 demo.mp4</code><br /> 得到输出为: <code class="language-plaintext highlighter-rouge">1920,1080</code></p> <p>方法二:获取视频的分辨率,以<code class="language-plaintext highlighter-rouge">x</code>分隔符分割<br /> <code class="language-plaintext highlighter-rouge">ffprobe -v error -show_entries stream=width,height -of csv=p=0:s=x output2.mp4</code><br /> 得到输出为: <code class="language-plaintext highlighter-rouge">1920x1080</code></p> <h3 id="22-截取指定时长的视频片段">2.2 截取指定时长的视频片段</h3> <p>从视频文件中,截取时间从<code class="language-plaintext highlighter-rouge">00:00:00</code>开始到<code class="language-plaintext highlighter-rouge">00:00:11</code>之间的片段,输出为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -ss 00:00:00 -to 00:00:11 -i input.mp4 -vcodec copy -acodec copy output.mp4</code></p> <p>从视频文件中,截取时间从<code class="language-plaintext highlighter-rouge">00:01:00</code>开始,时长<code class="language-plaintext highlighter-rouge">00:00:21</code>的片段,输出为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -ss 00:01:00 -t 00:00:21 -i input.mp4 -vcodec copy -acodec copy output2.mp4</code></p> <p>从视频文件中,截取时间从<code class="language-plaintext highlighter-rouge">00:00:00</code>到<code class="language-plaintext highlighter-rouge">00:00:11</code>之间的片段,分辨率为<code class="language-plaintext highlighter-rouge">1920x1080</code>,输出为新的视频文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -ss 00:00:00 -to 00:00:11 -i input.mp4 -vcodec copy -acodec copy -s 1920,1080 output.mp4</code></p> <h3 id="23-裁剪视频画面尺寸">2.3 裁剪视频画面尺寸</h3> <p>参数示例:<code class="language-plaintext highlighter-rouge">crop=new_width:new_height:start_x:start_y</code><br /> 把原视频画面裁剪成宽高为<code class="language-plaintext highlighter-rouge">400x200</code>的新视频,<code class="language-plaintext highlighter-rouge">x</code>的起始位置是<code class="language-plaintext highlighter-rouge">0</code>(表示从该位置开始,向右<code class="language-plaintext highlighter-rouge">400</code>的像素留下),<code class="language-plaintext highlighter-rouge">y</code>的起始位置是<code class="language-plaintext highlighter-rouge">0</code>(表示从该位置开始,向下<code class="language-plaintext highlighter-rouge">200</code>的像素留下)。也就是说,最后留下的视频画面为原视频画面的一部分(以原视频画面的左上顶点为原点)<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i input.mp4 -vf crop=400:200:0:0 -threads 5 -preset ultrafast -strict -2 output.mp4</code></p> <h2 id="3-视频导出图片">3. 视频导出图片</h2> <p>从视频文件中,以每秒<code class="language-plaintext highlighter-rouge">3</code>帧的速率抽取图片,并更改为指定长、宽,最后按照指定命名格式保存<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i demo.mp4 -r 3 -s 1920x1080 -f image2 ./demo-%03d.jpeg</code></p> <h2 id="4-从图片集创建gif文件">4. 从图片集创建GIF文件</h2> <p>从图片集创建帧率为<code class="language-plaintext highlighter-rouge">5</code>的<code class="language-plaintext highlighter-rouge">GIF</code>文件<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -f image2 -framerate 5 -i ./demo-%03d.jpeg out.gif</code></p> <h2 id="5-提取视频文件的音频">5. 提取视频文件的音频</h2> <p>提取视频文件的音频内容保存为<code class="language-plaintext highlighter-rouge">mp3</code>格式<br /> <code class="language-plaintext highlighter-rouge">ffmpeg -i demo.mp4 -f mp3 -vn -ar 16000 -ac 1 demo.mp3</code></p> <h2 id="6-把音频和画面合并为新的视频">6. 把音频和画面合并为新的视频</h2> <p><code class="language-plaintext highlighter-rouge">ffmpeg -loglevel quiet -i video.m4s -i audio.m4s -c copy -y out.mp4</code></p> <h2 id="7-下载m3u8文件为ts文件">7. 下载m3u8文件为.ts文件</h2> <p><code class="language-plaintext highlighter-rouge">ffmpeg -protocol_whitelist file,http,https,tcp,tls -i https://t.cn/a.m3u8 -c copy my_movie.ts</code></p> <h2 id="8-批量提取视频关键帧">8. 批量提取视频关键帧</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/bash</span> <span class="nb">shopt</span> <span class="nt">-s</span> nullglob <span class="nb">export </span><span class="nv">video_path</span><span class="o">=</span><span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="nb">export </span><span class="nv">out_path</span><span class="o">=</span><span class="s2">"</span><span class="nv">$2</span><span class="s2">"</span> <span class="nb">export </span><span class="nv">files</span><span class="o">=(</span><span class="k">${</span><span class="nv">video_path</span><span class="k">}</span>/<span class="k">*</span><span class="o">)</span> <span class="c"># echo ${files[@]}</span> <span class="c"># echo ${#files[@]}</span> <span class="k">for </span>filename <span class="k">in</span> <span class="s2">"</span><span class="k">${</span><span class="nv">files</span><span class="p">[@]</span><span class="k">}</span><span class="s2">"</span> <span class="k">do </span><span class="nv">filename</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">filename</span><span class="k">}</span><span class="s2">"</span> <span class="nb">export </span><span class="nv">name</span><span class="o">=</span><span class="si">$(</span><span class="nb">basename</span> <span class="s2">"</span><span class="k">${</span><span class="nv">filename</span><span class="k">}</span><span class="s2">"</span><span class="si">)</span> <span class="nv">name</span><span class="o">=</span><span class="k">${</span><span class="nv">name</span><span class="p">%.*</span><span class="k">}</span> <span class="nb">echo </span>Converting <span class="k">${</span><span class="nv">filename</span><span class="k">}</span> <span class="nb">export </span><span class="nv">file_dir</span><span class="o">=</span><span class="s2">"</span><span class="k">${</span><span class="nv">out_path</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">name</span><span class="k">}</span><span class="s2">"</span> <span class="nb">mkdir</span> <span class="s2">"</span><span class="k">${</span><span class="nv">file_dir</span><span class="k">}</span><span class="s2">"</span> <span class="c"># 获取视频分辨率(宽,高)</span> <span class="c"># 例如: 1920,1080</span> <span class="c"># export wh=ffprobe -v error -show_entries stream=width,height -of csv=p=0 "${filename}"</span> <span class="c"># 视频提取语音,方便识别</span> ffmpeg <span class="nt">-y</span> <span class="nt">-i</span> <span class="s2">"</span><span class="k">${</span><span class="nv">filename</span><span class="k">}</span><span class="s2">"</span> <span class="nt">-f</span> mp3 <span class="nt">-vn</span> <span class="nt">-ar</span> 16000 <span class="nt">-ac</span> 1 <span class="s2">"</span><span class="k">${</span><span class="nv">file_dir</span><span class="k">}</span><span class="s2">/audio.mp3"</span> <span class="c"># 视频关键帧提取,方便导出PPT</span> ffmpeg <span class="nt">-y</span> <span class="nt">-i</span> <span class="s2">"</span><span class="k">${</span><span class="nv">filename</span><span class="k">}</span><span class="s2">"</span> <span class="nt">-vf</span> <span class="k">select</span><span class="o">=</span><span class="s1">'eq(pict_type\,I)'</span> <span class="nt">-vsync</span> 2 <span class="nt">-s</span> 1920,1080 <span class="nt">-f</span> image2 <span class="s2">"</span><span class="k">${</span><span class="nv">file_dir</span><span class="k">}</span><span class="s2">/keyframe-%03d.png"</span> <span class="nb">echo </span>Convert <span class="k">${</span><span class="nv">filename</span><span class="k">}</span> successfully! <span class="k">done</span> </code></pre></div></div>

2022/12/30
阅读更多

修复Adobe Acrobat打开发票字体显示不全的问题

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#0-问题描述" id="markdown-toc-0-问题描述">0. 问题描述</a></li> <li><a href="#1-复制系统楷体字体文件" id="markdown-toc-1-复制系统楷体字体文件">1. 复制系统楷体字体文件</a></li> <li><a href="#2-修改字体名称" id="markdown-toc-2-修改字体名称">2. 修改字体名称</a></li> <li><a href="#3-复制字体文件到acrobat字体目录" id="markdown-toc-3-复制字体文件到acrobat字体目录">3. 复制字体文件到Acrobat字体目录</a></li> </ul> <h2 id="0-问题描述">0. 问题描述</h2> <p>Acrobat在2021.005.20060以后的新版本有bug,无法读取楷体GB2312字体,导致打开发票时,发票上的部分中文显示为方框或不显示</p> <h2 id="1-复制系统楷体字体文件">1. 复制系统楷体字体文件</h2> <p>文件资源管理器打开<code class="language-plaintext highlighter-rouge">C:\Windows\Fonts</code>目录,找到<code class="language-plaintext highlighter-rouge">楷体 常规</code>字体文件,即文件<code class="language-plaintext highlighter-rouge">C:\Windows\Fonts\simkai.ttf</code>,复制到其他目录,这样不会影响系统正常使用</p> <h2 id="2-修改字体名称">2. 修改字体名称</h2> <p>使用字体编辑工具FontCreator打开<code class="language-plaintext highlighter-rouge">simkai.ttf</code>字体文件,选择<code class="language-plaintext highlighter-rouge">Font-Properties</code>打开属性修改,将<code class="language-plaintext highlighter-rouge">Family Name</code>修改为<code class="language-plaintext highlighter-rouge">KaiTi_GB2312</code>,选择<code class="language-plaintext highlighter-rouge">File – Export Font – Export – Export Desktop Font</code>导出字体,可以命名为<code class="language-plaintext highlighter-rouge">simkai-new.otf</code>,等待几分钟完成</p> <h2 id="3-复制字体文件到acrobat字体目录">3. 复制字体文件到Acrobat字体目录</h2> <p>将修改后的字体文件<code class="language-plaintext highlighter-rouge">simkai-new.otf</code>复制到<code class="language-plaintext highlighter-rouge">C:\Program Files\Adobe\Acrobat DC\Resource\Font</code>目录,重启Acrobat即可</p>

2022/12/28
阅读更多

使用Python代码在Windows资源管理器中定位文件

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-安装pywin32" id="markdown-toc-1-安装pywin32">1. 安装pywin32</a></li> <li><a href="#2-脚本文件内容" id="markdown-toc-2-脚本文件内容">2. 脚本文件内容</a></li> </ul> <h2 id="1-安装pywin32">1. 安装pywin32</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip <span class="nb">install </span>pywin32 </code></pre></div></div> <h2 id="2-脚本文件内容">2. 脚本文件内容</h2> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python # -*- coding: utf-8 -*- # author: 'zfb' # time: 2021-01-06 13:33 </span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span> <span class="kn">import</span> <span class="nn">win32com.shell.shell</span> <span class="k">as</span> <span class="n">shell</span> <span class="k">def</span> <span class="nf">launch_file_explorer</span><span class="p">(</span><span class="n">file_with_abs_path</span><span class="p">):</span> <span class="s">''' 每次弹出文件资源管理器,只能打开一个文件夹,然后(定位)选择一个文件(夹) '''</span> <span class="nb">file</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">file_with_abs_path</span><span class="p">)</span> <span class="c1"># 对于Linux系统来说 </span> <span class="c1"># 如果使用Unity/Gnome桌面,可以使用命令 </span> <span class="c1"># nautilus ~/Documents/foo.txt </span> <span class="c1"># 对于其他桌面系统,可参考 xdg-open 命令 </span> <span class="c1"># 严格按照此格式,不能自己加空格 </span> <span class="n">os</span><span class="p">.</span><span class="n">system</span><span class="p">(</span><span class="s">'explorer.exe /e,/select,"{}"'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="nb">file</span><span class="p">))</span> <span class="k">def</span> <span class="nf">launch_files_explorer</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">files</span><span class="p">):</span> <span class="s">''' 每次弹出文件资源管理器,只能打开一个文件夹,可以选择多个文件(夹) '''</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">files</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> <span class="k">return</span> <span class="n">path</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">Path</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> <span class="n">folder_pidl</span> <span class="o">=</span> <span class="n">shell</span><span class="p">.</span><span class="n">SHILCreateFromPath</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="mi">0</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span> <span class="n">desktop</span> <span class="o">=</span> <span class="n">shell</span><span class="p">.</span><span class="n">SHGetDesktopFolder</span><span class="p">()</span> <span class="n">shell_folder</span> <span class="o">=</span> <span class="n">desktop</span><span class="p">.</span><span class="n">BindToObject</span><span class="p">(</span><span class="n">folder_pidl</span><span class="p">,</span> <span class="bp">None</span><span class="p">,</span> <span class="n">shell</span><span class="p">.</span><span class="n">IID_IShellFolder</span><span class="p">)</span> <span class="n">name_to_item_mapping</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">([(</span><span class="n">desktop</span><span class="p">.</span><span class="n">GetDisplayNameOf</span><span class="p">(</span><span class="n">item</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span> <span class="n">item</span><span class="p">)</span> <span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="n">shell_folder</span><span class="p">])</span> <span class="n">to_show</span> <span class="o">=</span> <span class="p">[]</span> <span class="k">for</span> <span class="nb">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">:</span> <span class="k">if</span> <span class="ow">not</span> <span class="nb">file</span> <span class="ow">in</span> <span class="n">name_to_item_mapping</span><span class="p">:</span> <span class="k">raise</span> <span class="nb">Exception</span><span class="p">(</span><span class="s">"目录{}下找不到文件{}"</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="nb">file</span><span class="p">))</span> <span class="n">to_show</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">name_to_item_mapping</span><span class="p">[</span><span class="nb">file</span><span class="p">])</span> <span class="n">shell</span><span class="p">.</span><span class="n">SHOpenFolderAndSelectItems</span><span class="p">(</span><span class="n">folder_pidl</span><span class="p">,</span> <span class="n">to_show</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">name</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">__file__</span><span class="p">)</span> <span class="n">path</span> <span class="o">=</span> <span class="s">"D:/github/zfb132.github.com/"</span> <span class="n">names</span> <span class="o">=</span> <span class="p">[</span><span class="s">"index.html"</span><span class="p">,</span> <span class="s">"README.md"</span><span class="p">,</span> <span class="s">"robots.txt"</span><span class="p">]</span> <span class="n">launch_file_explorer</span><span class="p">(</span><span class="n">name</span><span class="p">)</span> <span class="n">launch_files_explorer</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">names</span><span class="p">)</span> </code></pre></div></div>

2022/12/27
阅读更多

使用git diff查看不同文件或者不同commit之间的区别

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-查看不同文件的区别" id="markdown-toc-1-查看不同文件的区别">1. 查看不同文件的区别</a></li> <li><a href="#2-查看不同commit之间的修改" id="markdown-toc-2-查看不同commit之间的修改">2. 查看不同commit之间的修改</a></li> <li><a href="#3-把diff的转换为html保存" id="markdown-toc-3-把diff的转换为html保存">3. 把diff的转换为html保存</a></li> <li><a href="#4-ansi2htmlsh文件内容" id="markdown-toc-4-ansi2htmlsh文件内容">4. ansi2html.sh文件内容</a></li> </ul> <h2 id="1-查看不同文件的区别">1. 查看不同文件的区别</h2> <p><code class="language-plaintext highlighter-rouge">a.txt</code>和<code class="language-plaintext highlighter-rouge">b.txt</code>不在版本控制系统中:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git diff <span class="nt">--color-words</span> <span class="nt">--no-index</span> a.txt b.txt </code></pre></div></div> <h2 id="2-查看不同commit之间的修改">2. 查看不同commit之间的修改</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git diff <span class="nt">--color-words</span> HEAD~4 HEAD~3 git diff <span class="nt">--color-words</span> ac238c26 5d449a61 </code></pre></div></div> <h2 id="3-把diff的转换为html保存">3. 把diff的转换为html保存</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># 首先安装ansi2html</span> <span class="c"># https://github.com/pixelb/scripts/blob/master/scripts/ansi2html.sh</span> wget <span class="s2">"http://www.pixelbeat.org/scripts/ansi2html.sh"</span> <span class="nt">-O</span> ansi2html.sh <span class="nb">chmod</span> +x ansi2html.sh git diff <span class="nt">--color-words</span> HEAD~4 HEAD~3 | ansi2html.sh <span class="o">&gt;</span> docs/diff.html </code></pre></div></div> <p>然后可以用浏览器打开<code class="language-plaintext highlighter-rouge">docs/diff.html</code>查看,打印成pdf文件也可以</p> <h2 id="4-ansi2htmlsh文件内容">4. ansi2html.sh文件内容</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/bin/sh</span> <span class="c"># Convert ANSI (terminal) colours and attributes to HTML</span> <span class="c"># Licence: LGPLv2</span> <span class="c"># Author:</span> <span class="c"># http://www.pixelbeat.org/docs/terminal_colours/</span> <span class="c"># Examples:</span> <span class="c"># ls -l --color=always | ansi2html.sh &gt; ls.html</span> <span class="c"># git show --color | ansi2html.sh &gt; last_change.html</span> <span class="c"># Generally one can use the `script` util to capture full terminal output.</span> <span class="c"># Changes:</span> <span class="c"># V0.1, 24 Apr 2008, Initial release</span> <span class="c"># V0.2, 01 Jan 2009, Phil Harnish &lt;philharnish@gmail.com&gt;</span> <span class="c"># Support `git diff --color` output by</span> <span class="c"># matching ANSI codes that specify only</span> <span class="c"># bold or background colour.</span> <span class="c"># P@draigBrady.com</span> <span class="c"># Support `ls --color` output by stripping</span> <span class="c"># redundant leading 0s from ANSI codes.</span> <span class="c"># Support `grep --color=always` by stripping</span> <span class="c"># unhandled ANSI codes (specifically ^[[K).</span> <span class="c"># V0.3, 20 Mar 2009, http://eexpress.blog.ubuntu.org.cn/</span> <span class="c"># Remove cat -v usage which mangled non ascii input.</span> <span class="c"># Cleanup regular expressions used.</span> <span class="c"># Support other attributes like reverse, ...</span> <span class="c"># P@draigBrady.com</span> <span class="c"># Correctly nest &lt;span&gt; tags (even across lines).</span> <span class="c"># Add a command line option to use a dark background.</span> <span class="c"># Strip more terminal control codes.</span> <span class="c"># V0.4, 17 Sep 2009, P@draigBrady.com</span> <span class="c"># Handle codes with combined attributes and color.</span> <span class="c"># Handle isolated &lt;bold&gt; attributes with css.</span> <span class="c"># Strip more terminal control codes.</span> <span class="c"># V0.26, 16 Nov 2019</span> <span class="c"># http://github.com/pixelb/scripts/commits/master/scripts/ansi2html.sh</span> gawk <span class="nt">--version</span> <span class="o">&gt;</span>/dev/null <span class="o">||</span> <span class="nb">exit </span>1 <span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--version"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then </span><span class="nb">printf</span> <span class="s1">'0.26\n'</span> <span class="o">&amp;&amp;</span> <span class="nb">exit </span><span class="k">fi </span>usage<span class="o">()</span> <span class="o">{</span> <span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="se">\</span> <span class="s1">'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 &gt; ls.html'</span> <span class="o">&gt;</span>&amp;2 <span class="nb">exit</span> <span class="o">}</span> <span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--help"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then </span>usage <span class="k">fi </span>processArg<span class="o">()</span> <span class="o">{</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--bg=dark"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">{</span> <span class="nv">dark_bg</span><span class="o">=</span><span class="nb">yes</span><span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="o">}</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--css-only"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">{</span> <span class="nv">css_only</span><span class="o">=</span><span class="nb">yes</span><span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="o">}</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--body-only"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">{</span> <span class="nv">body_only</span><span class="o">=</span><span class="nb">yes</span><span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="o">}</span> <span class="k">if</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--palette=solarized"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="c"># See http://ethanschoonover.com/solarized</span> <span class="nv">P0</span><span class="o">=</span>073642<span class="p">;</span> <span class="nv">P1</span><span class="o">=</span>D30102<span class="p">;</span> <span class="nv">P2</span><span class="o">=</span>859900<span class="p">;</span> <span class="nv">P3</span><span class="o">=</span>B58900<span class="p">;</span> <span class="nv">P4</span><span class="o">=</span>268BD2<span class="p">;</span> <span class="nv">P5</span><span class="o">=</span>D33682<span class="p">;</span> <span class="nv">P6</span><span class="o">=</span>2AA198<span class="p">;</span> <span class="nv">P7</span><span class="o">=</span>EEE8D5<span class="p">;</span> <span class="nv">P8</span><span class="o">=</span>002B36<span class="p">;</span> <span class="nv">P9</span><span class="o">=</span>CB4B16<span class="p">;</span> <span class="nv">P10</span><span class="o">=</span>586E75<span class="p">;</span> <span class="nv">P11</span><span class="o">=</span>657B83<span class="p">;</span> <span class="nv">P12</span><span class="o">=</span>839496<span class="p">;</span> <span class="nv">P13</span><span class="o">=</span>6C71C4<span class="p">;</span> <span class="nv">P14</span><span class="o">=</span>93A1A1<span class="p">;</span> <span class="nv">P15</span><span class="o">=</span>FDF6E3<span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="k">elif</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--palette=solarized-xterm"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="c"># Above mapped onto the xterm 256 color palette</span> <span class="nv">P0</span><span class="o">=</span>262626<span class="p">;</span> <span class="nv">P1</span><span class="o">=</span>AF0000<span class="p">;</span> <span class="nv">P2</span><span class="o">=</span>5F8700<span class="p">;</span> <span class="nv">P3</span><span class="o">=</span>AF8700<span class="p">;</span> <span class="nv">P4</span><span class="o">=</span>0087FF<span class="p">;</span> <span class="nv">P5</span><span class="o">=</span>AF005F<span class="p">;</span> <span class="nv">P6</span><span class="o">=</span>00AFAF<span class="p">;</span> <span class="nv">P7</span><span class="o">=</span>E4E4E4<span class="p">;</span> <span class="nv">P8</span><span class="o">=</span>1C1C1C<span class="p">;</span> <span class="nv">P9</span><span class="o">=</span>D75F00<span class="p">;</span> <span class="nv">P10</span><span class="o">=</span>585858<span class="p">;</span> <span class="nv">P11</span><span class="o">=</span>626262<span class="p">;</span> <span class="nv">P12</span><span class="o">=</span>808080<span class="p">;</span> <span class="nv">P13</span><span class="o">=</span>5F5FAF<span class="p">;</span> <span class="nv">P14</span><span class="o">=</span>8A8A8A<span class="p">;</span> <span class="nv">P15</span><span class="o">=</span>FFFFD7<span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="k">elif</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--palette=tango"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> <span class="c"># Gnome default</span> <span class="nv">P0</span><span class="o">=</span>000000<span class="p">;</span> <span class="nv">P1</span><span class="o">=</span>CC0000<span class="p">;</span> <span class="nv">P2</span><span class="o">=</span>4E9A06<span class="p">;</span> <span class="nv">P3</span><span class="o">=</span>C4A000<span class="p">;</span> <span class="nv">P4</span><span class="o">=</span>3465A4<span class="p">;</span> <span class="nv">P5</span><span class="o">=</span>75507B<span class="p">;</span> <span class="nv">P6</span><span class="o">=</span>06989A<span class="p">;</span> <span class="nv">P7</span><span class="o">=</span>D3D7CF<span class="p">;</span> <span class="nv">P8</span><span class="o">=</span>555753<span class="p">;</span> <span class="nv">P9</span><span class="o">=</span>EF2929<span class="p">;</span> <span class="nv">P10</span><span class="o">=</span>8AE234<span class="p">;</span> <span class="nv">P11</span><span class="o">=</span>FCE94F<span class="p">;</span> <span class="nv">P12</span><span class="o">=</span>729FCF<span class="p">;</span> <span class="nv">P13</span><span class="o">=</span>AD7FA8<span class="p">;</span> <span class="nv">P14</span><span class="o">=</span>34E2E2<span class="p">;</span> <span class="nv">P15</span><span class="o">=</span>EEEEEC<span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="k">elif</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--palette=xterm"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then </span><span class="nv">P0</span><span class="o">=</span>000000<span class="p">;</span> <span class="nv">P1</span><span class="o">=</span>CD0000<span class="p">;</span> <span class="nv">P2</span><span class="o">=</span>00CD00<span class="p">;</span> <span class="nv">P3</span><span class="o">=</span>CDCD00<span class="p">;</span> <span class="nv">P4</span><span class="o">=</span>0000EE<span class="p">;</span> <span class="nv">P5</span><span class="o">=</span>CD00CD<span class="p">;</span> <span class="nv">P6</span><span class="o">=</span>00CDCD<span class="p">;</span> <span class="nv">P7</span><span class="o">=</span>E5E5E5<span class="p">;</span> <span class="nv">P8</span><span class="o">=</span>7F7F7F<span class="p">;</span> <span class="nv">P9</span><span class="o">=</span>FF0000<span class="p">;</span> <span class="nv">P10</span><span class="o">=</span>00FF00<span class="p">;</span> <span class="nv">P11</span><span class="o">=</span>FFFF00<span class="p">;</span> <span class="nv">P12</span><span class="o">=</span>5C5CFF<span class="p">;</span> <span class="nv">P13</span><span class="o">=</span>FF00FF<span class="p">;</span> <span class="nv">P14</span><span class="o">=</span>00FFFF<span class="p">;</span> <span class="nv">P15</span><span class="o">=</span>FFFFFF<span class="p">;</span> <span class="k">return</span><span class="p">;</span> <span class="k">else</span> <span class="c"># linux console</span> <span class="nv">P0</span><span class="o">=</span>000000<span class="p">;</span> <span class="nv">P1</span><span class="o">=</span>AA0000<span class="p">;</span> <span class="nv">P2</span><span class="o">=</span>00AA00<span class="p">;</span> <span class="nv">P3</span><span class="o">=</span>AA5500<span class="p">;</span> <span class="nv">P4</span><span class="o">=</span>0000AA<span class="p">;</span> <span class="nv">P5</span><span class="o">=</span>AA00AA<span class="p">;</span> <span class="nv">P6</span><span class="o">=</span>00AAAA<span class="p">;</span> <span class="nv">P7</span><span class="o">=</span>AAAAAA<span class="p">;</span> <span class="nv">P8</span><span class="o">=</span>555555<span class="p">;</span> <span class="nv">P9</span><span class="o">=</span>FF5555<span class="p">;</span> <span class="nv">P10</span><span class="o">=</span>55FF55<span class="p">;</span> <span class="nv">P11</span><span class="o">=</span>FFFF55<span class="p">;</span> <span class="nv">P12</span><span class="o">=</span>5555FF<span class="p">;</span> <span class="nv">P13</span><span class="o">=</span>FF55FF<span class="p">;</span> <span class="nv">P14</span><span class="o">=</span>55FFFF<span class="p">;</span> <span class="nv">P15</span><span class="o">=</span>FFFFFF<span class="p">;</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$1</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"--palette=linux"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="k">return</span><span class="p">;</span> <span class="k">fi</span> <span class="o">}</span> processArg <span class="c">#defaults</span> <span class="k">for </span>var <span class="k">in</span> <span class="s2">"</span><span class="nv">$@</span><span class="s2">"</span><span class="p">;</span> <span class="k">do </span>processArg <span class="nv">$var</span><span class="p">;</span> <span class="k">done</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$css_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> usage <span class="c"># Mac OSX's GNU sed is installed as gsed</span> <span class="c"># use e.g. homebrew 'gnu-sed' to get it</span> <span class="k">if</span> <span class="o">!</span> <span class="nb">sed</span> <span class="nt">--version</span> <span class="o">&gt;</span>/dev/null 2&gt;&amp;1<span class="p">;</span> <span class="k">then if </span>gsed <span class="nt">--version</span> <span class="o">&gt;</span>/dev/null 2&gt;&amp;1<span class="p">;</span> <span class="k">then </span><span class="nb">alias sed</span><span class="o">=</span>gsed <span class="k">else </span><span class="nb">echo</span> <span class="s2">"Error, can't find an acceptable GNU sed."</span> <span class="o">&gt;</span>&amp;2 <span class="nb">exit </span>1 <span class="k">fi fi</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$css_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s1">'%s'</span> <span class="s2">"&lt;html&gt; &lt;head&gt; &lt;meta http-equiv=</span><span class="se">\"</span><span class="s2">Content-Type</span><span class="se">\"</span><span class="s2"> content=</span><span class="se">\"</span><span class="s2">text/html; charset=utf-8</span><span class="se">\"</span><span class="s2">/&gt; &lt;style type=</span><span class="se">\"</span><span class="s2">text/css</span><span class="se">\"</span><span class="s2">&gt; pre { white-space: pre-wrap; } "</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">".ef0,.f0 { color: #</span><span class="nv">$P0</span><span class="s2">; } .eb0,.b0 { background-color: #</span><span class="nv">$P0</span><span class="s2">; } .ef1,.f1 { color: #</span><span class="nv">$P1</span><span class="s2">; } .eb1,.b1 { background-color: #</span><span class="nv">$P1</span><span class="s2">; } .ef2,.f2 { color: #</span><span class="nv">$P2</span><span class="s2">; } .eb2,.b2 { background-color: #</span><span class="nv">$P2</span><span class="s2">; } .ef3,.f3 { color: #</span><span class="nv">$P3</span><span class="s2">; } .eb3,.b3 { background-color: #</span><span class="nv">$P3</span><span class="s2">; } .ef4,.f4 { color: #</span><span class="nv">$P4</span><span class="s2">; } .eb4,.b4 { background-color: #</span><span class="nv">$P4</span><span class="s2">; } .ef5,.f5 { color: #</span><span class="nv">$P5</span><span class="s2">; } .eb5,.b5 { background-color: #</span><span class="nv">$P5</span><span class="s2">; } .ef6,.f6 { color: #</span><span class="nv">$P6</span><span class="s2">; } .eb6,.b6 { background-color: #</span><span class="nv">$P6</span><span class="s2">; } .ef7,.f7 { color: #</span><span class="nv">$P7</span><span class="s2">; } .eb7,.b7 { background-color: #</span><span class="nv">$P7</span><span class="s2">; } .ef8, .f0 &gt; .bold,.bold &gt; .f0 { color: #</span><span class="nv">$P8</span><span class="s2">; font-weight: normal; } .ef9, .f1 &gt; .bold,.bold &gt; .f1 { color: #</span><span class="nv">$P9</span><span class="s2">; font-weight: normal; } .ef10,.f2 &gt; .bold,.bold &gt; .f2 { color: #</span><span class="nv">$P10</span><span class="s2">; font-weight: normal; } .ef11,.f3 &gt; .bold,.bold &gt; .f3 { color: #</span><span class="nv">$P11</span><span class="s2">; font-weight: normal; } .ef12,.f4 &gt; .bold,.bold &gt; .f4 { color: #</span><span class="nv">$P12</span><span class="s2">; font-weight: normal; } .ef13,.f5 &gt; .bold,.bold &gt; .f5 { color: #</span><span class="nv">$P13</span><span class="s2">; font-weight: normal; } .ef14,.f6 &gt; .bold,.bold &gt; .f6 { color: #</span><span class="nv">$P14</span><span class="s2">; font-weight: normal; } .ef15,.f7 &gt; .bold,.bold &gt; .f7 { color: #</span><span class="nv">$P15</span><span class="s2">; font-weight: normal; } .eb8 { background-color: #</span><span class="nv">$P8</span><span class="s2">; } .eb9 { background-color: #</span><span class="nv">$P9</span><span class="s2">; } .eb10 { background-color: #</span><span class="nv">$P10</span><span class="s2">; } .eb11 { background-color: #</span><span class="nv">$P11</span><span class="s2">; } .eb12 { background-color: #</span><span class="nv">$P12</span><span class="s2">; } .eb13 { background-color: #</span><span class="nv">$P13</span><span class="s2">; } .eb14 { background-color: #</span><span class="nv">$P14</span><span class="s2">; } .eb15 { background-color: #</span><span class="nv">$P15</span><span class="s2">; } "</span> <span class="c"># The default xterm 256 colour palette</span> <span class="k">for </span>red <span class="k">in </span>0 1 2 3 4 5 <span class="p">;</span> <span class="k">do for </span>green <span class="k">in </span>0 1 2 3 4 5 <span class="p">;</span> <span class="k">do for </span>blue <span class="k">in </span>0 1 2 3 4 5 <span class="p">;</span> <span class="k">do </span><span class="nv">c</span><span class="o">=</span><span class="k">$((</span><span class="m">16</span> <span class="o">+</span> <span class="o">(</span><span class="nv">$red</span> <span class="o">*</span> <span class="m">36</span><span class="o">)</span> <span class="o">+</span> <span class="o">(</span><span class="nv">$green</span> <span class="o">*</span> <span class="m">6</span><span class="o">)</span> <span class="o">+</span> <span class="nv">$blue</span><span class="k">))</span> <span class="nv">r</span><span class="o">=</span><span class="k">$((</span><span class="o">(</span><span class="nv">$red</span> <span class="o">*</span> <span class="m">40</span> <span class="o">+</span> <span class="m">55</span><span class="o">)</span> <span class="o">*</span> <span class="o">(</span><span class="nv">$red</span> <span class="o">&gt;</span> <span class="m">0</span><span class="k">))</span><span class="o">)</span> <span class="nv">g</span><span class="o">=</span><span class="k">$((</span><span class="o">(</span><span class="nv">$green</span> <span class="o">*</span> <span class="m">40</span> <span class="o">+</span> <span class="m">55</span><span class="o">)</span> <span class="o">*</span> <span class="o">(</span><span class="nv">$green</span> <span class="o">&gt;</span> <span class="m">0</span><span class="k">))</span><span class="o">)</span> <span class="nv">b</span><span class="o">=</span><span class="k">$((</span><span class="o">(</span><span class="nv">$blue</span> <span class="o">*</span> <span class="m">40</span> <span class="o">+</span> <span class="m">55</span><span class="o">)</span> <span class="o">*</span> <span class="o">(</span><span class="nv">$blue</span> <span class="o">&gt;</span> <span class="m">0</span><span class="k">))</span><span class="o">)</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">".ef%d { color: #%2.2x%2.2x%2.2x; } "</span> <span class="nv">$c</span> <span class="nv">$r</span> <span class="nv">$g</span> <span class="nv">$b</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">".eb%d { background-color: #%2.2x%2.2x%2.2x; }</span><span class="se">\n</span><span class="s2">"</span> <span class="nv">$c</span> <span class="nv">$r</span> <span class="nv">$g</span> <span class="nv">$b</span> <span class="k">done done done for </span>gray <span class="k">in</span> <span class="si">$(</span><span class="nb">seq </span>0 23<span class="si">)</span><span class="p">;</span> <span class="k">do </span><span class="nv">c</span><span class="o">=</span><span class="k">$((</span><span class="nv">$gray</span><span class="o">+</span><span class="m">232</span><span class="k">))</span> <span class="nv">l</span><span class="o">=</span><span class="k">$((</span><span class="nv">$gray</span><span class="o">*</span><span class="m">10</span> <span class="o">+</span> <span class="m">8</span><span class="k">))</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">".ef%d { color: #%2.2x%2.2x%2.2x; } "</span> <span class="nv">$c</span> <span class="nv">$l</span> <span class="nv">$l</span> <span class="nv">$l</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">".eb%d { background-color: #%2.2x%2.2x%2.2x; }</span><span class="se">\n</span><span class="s2">"</span> <span class="nv">$c</span> <span class="nv">$l</span> <span class="nv">$l</span> <span class="nv">$l</span> <span class="k">done</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s1">'%s'</span> <span class="s1">' .f9 { color: '</span><span class="sb">`</span><span class="o">[</span> <span class="s2">"</span><span class="nv">$dark_bg</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="s2">"#</span><span class="nv">$P7</span><span class="s2">;"</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">"#</span><span class="nv">$P0</span><span class="s2">;"</span><span class="sb">`</span><span class="s1">' } .b9 { background-color: #'</span><span class="sb">`</span><span class="o">[</span> <span class="s2">"</span><span class="nv">$dark_bg</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="nv">$P0</span> <span class="o">||</span> <span class="nb">printf</span> <span class="nv">$P15</span><span class="sb">`</span><span class="s1">'; } .f9 &gt; .bold,.bold &gt; .f9, body.f9 &gt; pre &gt; .bold { /* Bold is heavy black on white, or bright white depending on the default background */ color: '</span><span class="sb">`</span><span class="o">[</span> <span class="s2">"</span><span class="nv">$dark_bg</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="s2">"#</span><span class="nv">$P15</span><span class="s2">;"</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s2">"#</span><span class="nv">$P0</span><span class="s2">;"</span><span class="sb">`</span><span class="s1">' font-weight: '</span><span class="sb">`</span><span class="o">[</span> <span class="s2">"</span><span class="nv">$dark_bg</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="s1">'normal;'</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s1">'bold;'</span><span class="sb">`</span><span class="s1">' } .reverse { /* CSS does not support swapping fg and bg colours unfortunately, so just hardcode something that will look OK on all backgrounds. */ '</span><span class="s2">"color: #</span><span class="nv">$P0</span><span class="s2">; background-color: #</span><span class="nv">$P7</span><span class="s2">;"</span><span class="s1">' } .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; } */ '</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$css_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="se">\</span> <span class="s1">'To use the css generated from --css-only, do: '</span><span class="se">\</span> <span class="s1">'&lt;head&gt;&lt;link rel="stylesheet" type="text/css" href="style.css"&gt;&lt;/head&gt;'</span> <span class="o">&gt;</span>&amp;2 <span class="o">[</span> <span class="s2">"</span><span class="nv">$css_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">exit</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s1">'%s'</span> <span class="s1">'&lt;/style&gt; &lt;/head&gt; &lt;body class="f9 b9"&gt; &lt;pre&gt; '</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">&amp;&amp;</span> <span class="nb">printf</span> <span class="s1">'%s\n'</span> <span class="s1">'Be sure to use &lt;body class="f9 b9"&gt; and &lt;pre&gt;'</span> <span class="o">&gt;</span>&amp;2 <span class="nv">p</span><span class="o">=</span><span class="s1">'\x1b\['</span> <span class="c">#shortcut to match escape codes</span> <span class="c"># Handle various xterm control sequences.</span> <span class="c"># See /usr/share/doc/xterm-*/ctlseqs.txt</span> <span class="nb">sed</span> <span class="s2">" # escape ampersand and quote s#&amp;#</span><span class="se">\&amp;</span><span class="s2">amp;#g; s#</span><span class="se">\"</span><span class="s2">#</span><span class="se">\&amp;</span><span class="s2">quot;#g; s#</span><span class="se">\x</span><span class="s2">1b[^</span><span class="se">\x</span><span class="s2">1b]*</span><span class="se">\x</span><span class="s2">1b</span><span class="se">\\\#</span><span class="s2">#g # strip anything between </span><span class="se">\e</span><span class="s2"> and ST s#</span><span class="se">\x</span><span class="s2">1b][0-9]*;[^</span><span class="se">\a</span><span class="s2">]*</span><span class="se">\a</span><span class="s2">##g # strip any OSC (xterm title etc.) s#</span><span class="se">\r\$</span><span class="s2">## # strip trailing </span><span class="se">\r</span><span class="s2"> # strip other non SGR escape sequences s#[</span><span class="se">\x</span><span class="s2">07]##g s#</span><span class="se">\x</span><span class="s2">1b[]&gt;=</span><span class="se">\]</span><span class="s2">[0-9;]*##g s#</span><span class="se">\x</span><span class="s2">1bP+.</span><span class="se">\{</span><span class="s2">5</span><span class="se">\}</span><span class="s2">##g # Mark cursor positioning codes </span><span class="se">\"</span><span class="s2">Jr;c; s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,2</span><span class="se">\}\)</span><span class="s2">G#</span><span class="se">\"</span><span class="s2">J;</span><span class="se">\1</span><span class="s2">;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,2</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,2</span><span class="se">\}\)</span><span class="s2">H#</span><span class="se">\"</span><span class="s2">J</span><span class="se">\1</span><span class="s2">;</span><span class="se">\2</span><span class="s2">;#g # Mark clear as </span><span class="se">\"</span><span class="s2">Cn where n=1 is screen and n=0 is to end-of-line s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">H#</span><span class="se">\"</span><span class="s2">C1;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">K#</span><span class="se">\"</span><span class="s2">C0;#g # Mark Cursor move columns as </span><span class="se">\"</span><span class="s2">Mn where n is +ve for right, -ve for left s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">C#</span><span class="se">\"</span><span class="s2">M1;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">C#</span><span class="se">\"</span><span class="s2">M</span><span class="se">\1</span><span class="s2">;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">D#</span><span class="se">\"</span><span class="s2">M-</span><span class="se">\1</span><span class="s2">;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">P#</span><span class="se">\"</span><span class="s2">X</span><span class="se">\1</span><span class="s2">;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">[0-9;?]*[^0-9;?m]##g "</span> | <span class="c"># Normalize the input before transformation</span> <span class="nb">sed</span> <span class="s2">" # escape HTML (ampersand and quote done above) s#&gt;#</span><span class="se">\&amp;</span><span class="s2">gt;#g; s#&lt;#</span><span class="se">\&amp;</span><span class="s2">lt;#g; # handle truecolor s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">38;2;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#</span><span class="se">\</span><span class="s2"> &lt;span style=</span><span class="se">\"</span><span class="s2">color:rgb(</span><span class="se">\1\,\2\,\3\)\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">48;2;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#</span><span class="se">\</span><span class="s2"> &lt;span style=</span><span class="se">\"</span><span class="s2">background-color:rgb(</span><span class="se">\1\,\2\,\3\)\"</span><span class="s2">&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#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9;]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[34]8;5;[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\1</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">¬</span><span class="se">\2</span><span class="s2">m#g; t e s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[34]8;5;[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">¬</span><span class="se">\1</span><span class="s2">m#g; :c s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">;</span><span class="se">\(</span><span class="s2">[0-9;]</span><span class="se">\{</span><span class="s2">1,</span><span class="se">\}\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\1</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\2</span><span class="s2">m#g; t c # split combined s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">0</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\1</span><span class="s2">#g #strip leading 0 s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">1m</span><span class="se">\(\(</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">[4579]m</span><span class="se">\)</span><span class="s2">*</span><span class="se">\)</span><span class="s2">#</span><span class="se">\1</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">1m#g #bold last (with clr) s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">0m#g #add leading 0 to norm # undo any 256 color marking s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">¬</span><span class="se">\(</span><span class="s2">[34]8;5;[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="se">\1</span><span class="s2">m#g; # map 16 color codes to color + bold s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">9</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\1</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">1m#g; s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">10</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\1</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">1m#g; # change 'reset' code to </span><span class="se">\"</span><span class="s2">R s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">0m#</span><span class="se">\"</span><span class="s2">R;#g "</span> | <span class="c"># Convert SGR sequences to HTML</span> <span class="nb">sed</span> <span class="s2">" # common combinations to minimise html (optional) :f s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3[0-7]m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\1</span><span class="s2">m#g; t f :b s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4[0-7]m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\1</span><span class="s2">m#g; t b s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">f</span><span class="se">\1</span><span class="s2"> b</span><span class="se">\2\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\(</span><span class="s2">[0-7]</span><span class="se">\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">f</span><span class="se">\2</span><span class="s2"> b</span><span class="se">\1\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">1m#&lt;span class=</span><span class="se">\"</span><span class="s2">bold</span><span class="se">\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4m#&lt;span class=</span><span class="se">\"</span><span class="s2">underline</span><span class="se">\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">5m#&lt;span class=</span><span class="se">\"</span><span class="s2">blink</span><span class="se">\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">7m#&lt;span class=</span><span class="se">\"</span><span class="s2">reverse</span><span class="se">\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">9m#&lt;span class=</span><span class="se">\"</span><span class="s2">line-through</span><span class="se">\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">3</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">f</span><span class="se">\1\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">4</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">b</span><span class="se">\1\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">38;5;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">ef</span><span class="se">\1\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">48;5;</span><span class="se">\(</span><span class="s2">[0-9]</span><span class="se">\{</span><span class="s2">1,3</span><span class="se">\}\)</span><span class="s2">m#&lt;span class=</span><span class="se">\"</span><span class="s2">eb</span><span class="se">\1\"</span><span class="s2">&gt;#g s#</span><span class="k">${</span><span class="nv">p</span><span class="k">}</span><span class="s2">[0-9;]*m##g # strip unhandled codes "</span> | <span class="c"># Convert alternative character set and handle cursor movement codes</span> <span class="c"># Note we convert here, as if we do at start we have to worry about avoiding</span> <span class="c"># conversion of SGR codes etc., whereas doing here we only have to</span> <span class="c"># avoid conversions of stuff between &amp;...; or &lt;...&gt;</span> <span class="c">#</span> <span class="c"># Note we could use sed to do this based around:</span> <span class="c"># sed 'y/abcdefghijklmnopqrstuvwxyz{}`~/▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·/'</span> <span class="c"># However that would be very awkward as we need to only conv some input.</span> <span class="c"># The basic scheme that we do in the awk script below is:</span> <span class="c"># 1. enable transliterate once "T1; is seen</span> <span class="c"># 2. disable once "T0; is seen (may be on diff line)</span> <span class="c"># 3. never transliterate between &amp;; or &lt;&gt; chars</span> <span class="c"># 4. track x,y movements and active display mode at each position</span> <span class="c"># 5. buffer line/screen and dump when required</span> <span class="nb">sed</span> <span class="s2">" # change 'smacs' and 'rmacs' to </span><span class="se">\"</span><span class="s2">T1 and </span><span class="se">\"</span><span class="s2">T0 to simplify matching. s#</span><span class="se">\x</span><span class="s2">1b(0#</span><span class="se">\"</span><span class="s2">T1;#g; s#</span><span class="se">\x</span><span class="s2">0E#</span><span class="se">\"</span><span class="s2">T1;#g; s#</span><span class="se">\x</span><span class="s2">1b(B#</span><span class="se">\"</span><span class="s2">T0;#g s#</span><span class="se">\x</span><span class="s2">0F#</span><span class="se">\"</span><span class="s2">T0;#g "</span> | <span class="o">(</span> gawk <span class="s1">' function dump_line(l,del,c,blanks,ret) { for(c=1;c&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="" } if ((c SUBSEP l) in dump) { ret=ret blanks dump[c,l] if(del) delete dump[c,l] blanks="" } else blanks=blanks " " } if(alength(cur)) ret=ret blanks return ret } function dump_screen(l,ret) { for(l=1;l&lt;=maxY;l++) ret=ret dump_line(l,0) "\n" return ret fixas(cur, "") } function atos(a,i,ret) { for(i=1;i&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,"&gt;") for(i=1;i&lt;=spc;i++) { rm=rm?rm:(a[i]!=attr[i]"&gt;") if(rm) { ret=ret "&lt;/span&gt;" delete a[i]; } } for(i=1;i&lt;l;i++) { attr[i]=attr[i]"&gt;" 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&lt;=length(string);i++) { c=substr(string,i,1) if(state==2) { sc=sc c if(c==";") { c=sc state=last_mode } else continue } else { if(c=="\r") { x=1; continue } if(c=="&lt;") { # Change attributes - store current active # attributes in span array split(substr(string,i),cord,"&gt;"); i+=length(cord[1]) span[++spc]=cord[1] "&gt;" continue } else if(c=="&amp;") { # All goes to single position till we see a semicolon sc=c state=2 continue } else if(c=="\b") { # backspace move insertion point back 1 if(spc) attr[x,y]=atos(span) x=x&gt;1?x-1:1 continue } else if(c=="\"") { split(substr(string,i+2),cord,";") cc=substr(string,i+1,1); if(cc=="T") { # Transliterate on/off if(cord[1]==1&amp;&amp;state==3) last_mode=state=4 if(cord[1]==0&amp;&amp;state==4) last_mode=state=3 } else if(cc=="C") { # 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&lt;maxX;pos++) { dump[pos,y]=" " if (!spc) delete attr[pos,y] else attr[pos,y]=atos(span) } } } else if(cc=="J") { # Jump to x,y i+=length(cord[2])+1 # If line is higher - dump previous screen if(dumpStatus==dsActive&amp;&amp;cord[1]&lt;y) { ret=ret dump_screen(); dumpStatus=dsNew; } x=cord[2] if(length(cord[1]) &amp;&amp; y!=cord[1]){ y=cord[1] if(y&gt;maxY) maxY=y # Change y - start recording dumpStatus=dumpStatus?dumpStatus:dsReset } } else if(cc=="M") { # Move left/right on current line x+=cord[1] } else if(cc=="X") { # delete on right for(pos=x;pos&lt;=maxX;pos++) { nx=pos+cord[1] if(nx&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]=" " } } } else if(cc=="R") { # Reset attributes while(spc) delete span[spc--] } i+=length(cord[1])+2 continue } else if(state==4&amp;&amp;i&gt;=start&amp;&amp;i&lt;=end&amp;&amp;c in Trans) c=Trans[c] } if(dumpStatus==dsReset) { delete dump delete attr ret=ret"\n" dumpStatus=dsActive } if(dumpStatus==dsNew) { # After moving/clearing we are now ready to write # somthing to the screen so start recording now ret=ret"\n" 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&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&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="abcdefghijklmnopqrstuvwxyz{}`~" T="▒␉␌␍␊°±␤␋┘┐┌└┼⎺⎻─⎼⎽├┤┴┬│≤≥π£◆·" maxX=80 delete cur; x=y=1 for(i=1;i&lt;=length(F);i++)Trans[substr(F,i,1)]=substr(T,i,1); } { $0=encode($0) } 1 END { if(dumpStatus) { print dump_screen(); } }'</span> <span class="o">)</span> <span class="o">[</span> <span class="s2">"</span><span class="nv">$body_only</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="nb">printf</span> <span class="s1">'&lt;/pre&gt; &lt;/body&gt; &lt;/html&gt;\n'</span> </code></pre></div></div>

2022/12/27
阅读更多

SRT字幕文件转文本文件

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-获取字幕文件" id="markdown-toc-1-获取字幕文件">1. 获取字幕文件</a></li> <li><a href="#2-python脚本" id="markdown-toc-2-python脚本">2. python脚本</a></li> </ul> <h2 id="1-获取字幕文件">1. 获取字幕文件</h2> <p>一般来说,很多视频网站都会提供视频的字幕文件。有的可以直接下载,有的需要先下载视频,然后再使用字幕软件提取字幕文件。还有一些可以在Chrome浏览器中安装字幕插件,然后在视频播放页面中直接下载字幕文件。总而言之,需要先获取到字幕文件,然后才能进行下一步操作。<code class="language-plaintext highlighter-rouge">SRT</code>格式的字幕文件是最常见的,其格式如下所示:</p> <figure class="highlight"><pre><code class="language-txt" data-lang="txt"><table class="rouge-table"><tbody><tr><td class="gutter gl"><pre class="lineno">1 2 3 4 5 6 7 </pre></td><td class="code"><pre>1 00:00:00,000 --&gt; 00:00:02,000 Life is short 2 00:00:02,205 --&gt; 00:00:04,000 You need Python </pre></td></tr></tbody></table></code></pre></figure> <p>可以看到,字幕文件由多个字幕组成,每个字幕由两行组成,第一行是字幕的序号,第二行是字幕的时间轴,第三行是字幕的内容。字幕之间用空行分隔。所以,只需要先删除所有空行,然后对<code class="language-plaintext highlighter-rouge">line_num%3==0</code>的行进行处理,即可得到字幕的内容</p> <h2 id="2-python脚本">2. python脚本</h2> <p>文件内容如下:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python # -*- coding: utf-8 -*- # author: 'zfb' # time: 2019-10-26 17:17 </span> <span class="kn">import</span> <span class="nn">argparse</span> <span class="kn">import</span> <span class="nn">glob</span> <span class="kn">import</span> <span class="nn">os</span> <span class="c1"># 输出文件的头部信息,可以为空 </span><span class="n">header</span> <span class="o">=</span> <span class="s">"zfb 2019-10-26 17:17</span><span class="se">\n\n</span><span class="s">"</span> <span class="c1"># 段落开始符号 </span><span class="n">begin_para_symbol</span> <span class="o">=</span> <span class="s">" "</span> <span class="c1"># 拼接句子的符号 </span><span class="n">split_line_symbol</span> <span class="o">=</span> <span class="s">","</span> <span class="c1"># 拼接字幕文件的符号 </span><span class="n">split_file_symbol</span> <span class="o">=</span> <span class="s">"</span><span class="se">\n\n\n</span><span class="s">"</span> <span class="k">def</span> <span class="nf">read_toc</span><span class="p">(</span><span class="n">file_name</span><span class="p">):</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="s">"r"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"utf8"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span> <span class="n">lines</span> <span class="o">=</span> <span class="nb">file</span><span class="p">.</span><span class="n">readlines</span><span class="p">()</span> <span class="c1"># 去除所有空行 </span> <span class="n">strip_lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span><span class="o">+</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">())]</span> <span class="k">return</span> <span class="n">strip_lines</span> <span class="k">def</span> <span class="nf">read_srt</span><span class="p">(</span><span class="n">file_name</span><span class="p">):</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="s">"r"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"utf8"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span> <span class="n">lines</span> <span class="o">=</span> <span class="nb">file</span><span class="p">.</span><span class="n">readlines</span><span class="p">()</span> <span class="c1"># 去除所有空行 </span> <span class="n">strip_lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="n">strip</span><span class="p">())]</span> <span class="c1"># 根据文件格式,字幕文字所在行是3的倍数,从起始位置,到结束位置,间隔为3 </span> <span class="n">text_lines</span> <span class="o">=</span> <span class="n">strip_lines</span><span class="p">[</span><span class="mi">2</span><span class="p">::</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># 按照逗号拼接全文 </span> <span class="n">text</span> <span class="o">=</span> <span class="n">split_line_symbol</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">text_lines</span><span class="p">)</span> <span class="k">return</span> <span class="n">text</span> <span class="k">def</span> <span class="nf">get_files</span><span class="p">(</span><span class="n">directory</span><span class="p">):</span> <span class="c1"># 按文件名排序 </span> <span class="k">return</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">glob</span><span class="p">.</span><span class="n">glob</span><span class="p">(</span><span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">directory</span><span class="p">,</span> <span class="s">"*.srt"</span><span class="p">)))</span> <span class="k">def</span> <span class="nf">convert</span><span class="p">(</span><span class="n">srt_files</span><span class="p">,</span> <span class="n">toc_lines</span><span class="p">,</span> <span class="n">txt_name</span><span class="p">):</span> <span class="n">content</span> <span class="o">=</span> <span class="n">header</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">srt_files</span><span class="p">)):</span> <span class="n">content</span> <span class="o">=</span> <span class="n">content</span> <span class="o">+</span> <span class="n">toc_lines</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">begin_para_symbol</span> <span class="o">+</span> <span class="n">read_srt</span><span class="p">(</span><span class="n">srt_files</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="o">+</span> <span class="n">split_file_symbol</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">txt_name</span><span class="p">,</span> <span class="s">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span> <span class="nb">file</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="n">content</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="p">.</span><span class="n">ArgumentParser</span><span class="p">(</span> <span class="n">description</span><span class="o">=</span><span class="s">'SRT字幕文件转TXT文件'</span><span class="p">,</span> <span class="n">formatter_class</span><span class="o">=</span><span class="n">argparse</span><span class="p">.</span><span class="n">RawDescriptionHelpFormatter</span><span class="p">,</span> <span class="n">epilog</span><span class="o">=</span> <span class="s">'''</span><span class="se">\ </span><span class="s">用法示例: python srt2txt.py ./srt/ ./content.txt -t ./toc.txt python srt2txt.py ./srt/ ./content.txt python srt2txt.py '''</span> <span class="p">)</span> <span class="c1"># 可选参数 </span> <span class="n">parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span> <span class="s">"-s"</span><span class="p">,</span> <span class="s">"--srt_dir"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"./srt/"</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s">"*.srt字幕文件所在目录,默认为当前目录下的srt文件夹"</span> <span class="p">)</span> <span class="n">parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span> <span class="s">"-o"</span><span class="p">,</span> <span class="s">"--output_name"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"./content.txt"</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s">"输出文件名,默认为content.txt"</span> <span class="p">)</span> <span class="n">parser</span><span class="p">.</span><span class="n">add_argument</span><span class="p">(</span> <span class="s">"-t"</span><span class="p">,</span> <span class="s">"--toc"</span><span class="p">,</span> <span class="nb">type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="s">"./toc.txt"</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s">"目录文件名,默认为toc.txt, 如果没有,会根据字幕文件名生成"</span> <span class="p">)</span> <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="p">.</span><span class="n">parse_args</span><span class="p">()</span> <span class="c1"># 字幕文件所在目录 </span> <span class="n">srt_file_path</span> <span class="o">=</span> <span class="n">args</span><span class="p">.</span><span class="n">srt_dir</span> <span class="c1"># 目录文件,如果没有,会根据字幕文件名生成 </span> <span class="n">toc_file</span> <span class="o">=</span> <span class="n">args</span><span class="p">.</span><span class="n">toc</span> <span class="c1"># 输出文件 </span> <span class="n">txt_file</span> <span class="o">=</span> <span class="n">args</span><span class="p">.</span><span class="n">output_name</span> <span class="n">files</span> <span class="o">=</span> <span class="n">get_files</span><span class="p">(</span><span class="n">srt_file_path</span><span class="p">)</span> <span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">exists</span><span class="p">(</span><span class="n">toc_file</span><span class="p">):</span> <span class="c1"># 读取目录文件 </span> <span class="n">toc_lines</span> <span class="o">=</span> <span class="n">read_toc</span><span class="p">(</span><span class="n">toc_file</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="c1"># 根据srt文件名,生成目录文件 </span> <span class="n">toc_lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">basename</span><span class="p">(</span><span class="nb">file</span><span class="p">)</span> <span class="o">+</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span> <span class="k">for</span> <span class="nb">file</span> <span class="ow">in</span> <span class="n">files</span><span class="p">]</span> <span class="n">convert</span><span class="p">(</span><span class="n">files</span><span class="p">,</span> <span class="n">toc_lines</span><span class="p">,</span> <span class="n">txt_file</span><span class="p">)</span> </code></pre></div></div>

2022/12/27
阅读更多

在ubuntu系统安装配置heatererp软件

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#1-下载软件包并安装依赖" id="markdown-toc-1-下载软件包并安装依赖">1. 下载软件包并安装依赖</a></li> <li><a href="#2-配置heatererp" id="markdown-toc-2-配置heatererp">2. 配置heatererp</a></li> <li><a href="#3-创建文件夹保存运算结果" id="markdown-toc-3-创建文件夹保存运算结果">3. 创建文件夹保存运算结果</a></li> <li><a href="#4-运行测试" id="markdown-toc-4-运行测试">4. 运行测试</a></li> <li><a href="#5-注意" id="markdown-toc-5-注意">5. 注意</a></li> </ul> <h2 id="1-下载软件包并安装依赖">1. 下载软件包并安装依赖</h2> <p>安装需要依赖的软件,使用<code class="language-plaintext highlighter-rouge">nec2c</code>虽然运行慢,但是配置简单<br /> <code class="language-plaintext highlighter-rouge">sudo apt-get install zip nec2c octave</code><br /> 本项目代码仓库网址: <a href="https://gitlab.com/andrewsenior/heatererp" title="&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 &quot;">https://gitlab.com/andrewsenior/heatererp</a></p> <h2 id="2-配置heatererp">2. 配置heatererp</h2> <p>启动heatererp,步骤如下:<br /> <code class="language-plaintext highlighter-rouge">cd ~/heatererp-master/bin</code><br /> <code class="language-plaintext highlighter-rouge">chmod +x ./erpmodel.sh</code><br /> <code class="language-plaintext highlighter-rouge">./erpmodel.sh</code><br /> 然后会提示设置各种路径,可以随便弄,然后再修改<code class="language-plaintext highlighter-rouge">~/.config/heatererp/conf.m</code>文件中的路径<br /> 设置完以后保证<code class="language-plaintext highlighter-rouge">conf.m</code>的内容如下,注意<code class="language-plaintext highlighter-rouge">model_engine</code>设置为<code class="language-plaintext highlighter-rouge">nec2c</code></p> <div class="language-matlab highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">% Configuration script for Heater ERP model</span> <span class="n">model_dir</span><span class="o">=</span><span class="s1">'/home/zfb/heatererp-master/models'</span><span class="p">;</span> <span class="n">nec2_bin</span><span class="o">=</span><span class="s1">'/the/real/path/to/nec2'</span><span class="p">;</span> <span class="n">nec2c_bin</span><span class="o">=</span><span class="s1">'nec2c'</span><span class="p">;</span> <span class="n">model_engine</span><span class="o">=</span><span class="s1">'nec2c'</span><span class="p">;</span> <span class="n">log_dir</span><span class="o">=</span><span class="s1">'/home/zfb/heatererp/logs'</span><span class="p">;</span> <span class="n">results_dir</span><span class="o">=</span><span class="s1">'/home/zfb/heatererp/results'</span><span class="p">;</span> <span class="n">plots_dir</span><span class="o">=</span><span class="s1">'/home/zfb/heatererp/plots'</span><span class="p">;</span> </code></pre></div></div> <h2 id="3-创建文件夹保存运算结果">3. 创建文件夹保存运算结果</h2> <p>创建的文件夹要与<code class="language-plaintext highlighter-rouge">conf.m</code>文件中设置的相对应<br /> <code class="language-plaintext highlighter-rouge">cd ~ &amp;&amp; mkdir heatererp &amp;&amp; cd heatererp</code><br /> <code class="language-plaintext highlighter-rouge">mkdir logs plots results</code></p> <h2 id="4-运行测试">4. 运行测试</h2> <p>放置log文件,执行sh脚本运行模型<br /> <code class="language-plaintext highlighter-rouge">cp ~/heatererp-master/testing/1970-01-01_tx.log ~/heatererp/logs/</code><br /> <code class="language-plaintext highlighter-rouge">cd ~/heatererp-master/bin &amp;&amp; ./erpmodel.sh</code><br /> 在打开的octave软件的提示符里面输入以下内容即可计算<br /> <code class="language-plaintext highlighter-rouge">erpmodel('01-Jan-1970 00:00:00');erpmodel('01-Jan-1970 01:28:00');</code> 等待运行结束,在<code class="language-plaintext highlighter-rouge">/home/zfb/heatererp/</code>对应文件夹寻找结果</p> <h2 id="5-注意">5. 注意</h2> <ul> <li>在Ubuntu 18.04系统测试通过(Ubuntu 20.04好像不太行)</li> <li>如果系统有GUI,还会同时显示图片</li> <li><code class="language-plaintext highlighter-rouge">.log</code>文件的第一行是实验开始时间,<code class="language-plaintext highlighter-rouge">erpmodel()</code>的参数可以是那个时刻及以后的时刻</li> </ul>

2021/2/27
阅读更多

在linux系统监控某个程序的执行情况并通知用户

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#介绍" id="markdown-toc-介绍">介绍</a></li> <li><a href="#代码" id="markdown-toc-代码">代码</a></li> <li><a href="#运行监控代码文件" id="markdown-toc-运行监控代码文件">运行监控代码文件</a></li> </ul> <h2 id="介绍">介绍</h2> <p>如果有一个下载任务需要执行(<code class="language-plaintext highlighter-rouge">python3 download.py</code>),该任务会下载许多文件,一般将其放在后台执行。但是又需要知道它是否在某个时刻退出,可能是因为:</p> <ul> <li>任务执行完毕,正常结束运行</li> <li>任务异常退出,可能由于下载的网站爬虫策略限制,也可能是其他原因</li> </ul> <p>无论由于哪个原因,一旦程序停止,都需要立刻用户,所以编写以下代码来实现该功能</p> <h2 id="代码">代码</h2> <p>使用python语言编写监控程序<code class="language-plaintext highlighter-rouge">detect.py</code>文件:</p> <ul> <li>如果需要使用腾讯云发送短信通知,则安装库<code class="language-plaintext highlighter-rouge">qcloudsms_py</code></li> <li>如果需要使用twilio发送短信通知,则安装库<code class="language-plaintext highlighter-rouge">twilio</code></li> </ul> <p>文件内容如下:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#!/usr/bin/env python # -*- coding: utf-8 -*- # author: 'zfb' # time: 19-06-29 09:52 </span><span class="kn">import</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="nn">json</span> <span class="kn">import</span> <span class="nn">os</span> <span class="kn">import</span> <span class="nn">requests</span> <span class="kn">import</span> <span class="nn">socket</span> <span class="kn">import</span> <span class="nn">logging</span> <span class="kn">from</span> <span class="nn">logging.handlers</span> <span class="kn">import</span> <span class="n">RotatingFileHandler</span> <span class="kn">from</span> <span class="nn">qcloudsms_py</span> <span class="kn">import</span> <span class="n">SmsSingleSender</span> <span class="kn">from</span> <span class="nn">qcloudsms_py.httpclient</span> <span class="kn">import</span> <span class="n">HTTPError</span> <span class="n">LOG_FORMAT</span> <span class="o">=</span> <span class="s">"%(asctime)s [%(funcName)s: %(filename)s,%(lineno)d] - %(levelname)s : %(message)s"</span> <span class="n">DATE_FORMAT</span> <span class="o">=</span> <span class="s">"%m/%d/%Y %H:%M:%S"</span> <span class="n">LOG_PATH</span> <span class="o">=</span> <span class="s">"./log/"</span> <span class="c1"># 初始化日志文件配置 </span><span class="k">def</span> <span class="nf">initLog</span><span class="p">(</span><span class="n">fileName</span><span class="p">,</span><span class="n">logger</span><span class="p">):</span> <span class="c1"># 创建日志文件夹 </span> <span class="k">if</span> <span class="ow">not</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">exists</span><span class="p">(</span><span class="n">LOG_PATH</span><span class="p">):</span> <span class="n">os</span><span class="p">.</span><span class="n">mkdir</span><span class="p">(</span><span class="n">LOG_PATH</span><span class="p">)</span> <span class="n">myapp</span> <span class="o">=</span> <span class="n">logging</span><span class="p">.</span><span class="n">getLogger</span><span class="p">(</span><span class="n">logger</span><span class="p">)</span> <span class="n">myapp</span><span class="p">.</span><span class="n">setLevel</span><span class="p">(</span><span class="n">logging</span><span class="p">.</span><span class="n">DEBUG</span><span class="p">)</span> <span class="c1"># 切割日志文件 </span> <span class="n">handler</span> <span class="o">=</span> <span class="n">RotatingFileHandler</span><span class="p">(</span><span class="n">LOG_PATH</span><span class="o">+</span><span class="n">fileName</span><span class="p">,</span> <span class="n">maxBytes</span><span class="o">=</span><span class="mi">128</span><span class="o">*</span><span class="mi">1024</span><span class="p">,</span> <span class="n">backupCount</span><span class="o">=</span><span class="mi">60</span><span class="p">)</span> <span class="n">handler</span><span class="p">.</span><span class="n">setFormatter</span><span class="p">(</span><span class="n">logging</span><span class="p">.</span><span class="n">Formatter</span><span class="p">(</span><span class="n">LOG_FORMAT</span><span class="p">,</span><span class="n">DATE_FORMAT</span><span class="p">))</span> <span class="n">myapp</span><span class="p">.</span><span class="n">addHandler</span><span class="p">(</span><span class="n">handler</span><span class="p">)</span> <span class="k">return</span> <span class="n">myapp</span> <span class="n">logging</span> <span class="o">=</span> <span class="n">initLog</span><span class="p">(</span><span class="s">'detect.log'</span><span class="p">,</span> <span class="s">'detect'</span><span class="p">)</span> <span class="c1"># ------------ 使用腾讯云发送短信通知用户 ----------- </span><span class="n">APP_ID</span> <span class="o">=</span> <span class="mi">1412345678</span> <span class="n">APP_KEY</span> <span class="o">=</span> <span class="s">"3998d59614123456789b72dd5961405c"</span> <span class="n">TEMPLATE_ID</span> <span class="o">=</span> <span class="mi">101234</span> <span class="n">SMS_SIGN</span> <span class="o">=</span> <span class="s">"签名A"</span> <span class="c1"># ------------ 使用腾讯云发送短信通知用户 ----------- </span> <span class="c1"># ------------ 使用twilio发送短信 ------------------ </span><span class="n">SMS_SID</span> <span class="o">=</span> <span class="s">'ACb770c5f63aac91c44d97891234567890'</span> <span class="n">SMS_TOKEN</span> <span class="o">=</span> <span class="s">'42b1294966799e965883181234567890'</span> <span class="n">SMS_FROM_NUMBER</span> <span class="o">=</span> <span class="s">'+12512123456'</span> <span class="c1"># ------------ 使用twilio发送短信 ------------------ </span> <span class="c1"># ------------ 使用邮箱发信 ------------------------ </span><span class="n">EMAIL_FROM</span> <span class="o">=</span> <span class="s">'example@qq.com'</span> <span class="n">EMAIL_PWD</span> <span class="o">=</span> <span class="s">'123demo'</span> <span class="c1"># ------------ 使用邮箱发信 ------------------------ </span> <span class="k">def</span> <span class="nf">sendSMS</span><span class="p">(</span><span class="n">number</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">app_id</span><span class="o">=</span><span class="n">APP_ID</span><span class="p">,</span> <span class="n">key</span><span class="o">=</span><span class="n">APP_KEY</span><span class="p">,</span> <span class="n">template_id</span><span class="o">=</span><span class="n">TEMPLATE_ID</span><span class="p">,</span> <span class="n">sms_sign</span><span class="o">=</span><span class="n">SMS_SIGN</span><span class="p">):</span> <span class="n">ssender</span> <span class="o">=</span> <span class="n">SmsSingleSender</span><span class="p">(</span><span class="n">app_id</span><span class="p">,</span> <span class="n">key</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="n">result</span> <span class="o">=</span> <span class="n">ssender</span><span class="p">.</span><span class="n">send_with_param</span><span class="p">(</span><span class="mi">86</span><span class="p">,</span> <span class="n">number</span><span class="p">,</span> <span class="n">template_id</span><span class="p">,</span> <span class="n">params</span><span class="p">,</span> <span class="n">sign</span><span class="o">=</span><span class="n">sms_sign</span><span class="p">,</span> <span class="n">extend</span><span class="o">=</span><span class="s">""</span><span class="p">,</span> <span class="n">ext</span><span class="o">=</span><span class="s">""</span><span class="p">)</span> <span class="k">except</span> <span class="n">HTTPError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="n">log</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="k">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="n">log</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">e</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="k">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="n">log</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span> <span class="n">logging</span><span class="p">.</span><span class="n">debug</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="k">print</span><span class="p">(</span><span class="n">log</span><span class="p">)</span> <span class="c1"># 使用twilio的使用账户发送短信 </span><span class="k">def</span> <span class="nf">send_sms</span><span class="p">(</span><span class="n">phone</span><span class="p">,</span> <span class="n">content</span><span class="p">):</span> <span class="kn">from</span> <span class="nn">twilio.rest</span> <span class="kn">import</span> <span class="n">Client</span> <span class="c1"># 账户信息: twilio.com/console </span> <span class="n">account_sid</span> <span class="o">=</span> <span class="n">SMS_SID</span> <span class="n">auth_token</span> <span class="o">=</span> <span class="n">SMS_TOKEN</span> <span class="n">from_phone_num</span> <span class="o">=</span> <span class="n">SMS_FROM_NUMBER</span> <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">account_sid</span><span class="p">,</span> <span class="n">auth_token</span><span class="p">)</span> <span class="n">message</span> <span class="o">=</span> <span class="n">client</span><span class="p">.</span><span class="n">messages</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="n">body</span><span class="o">=</span><span class="n">content</span><span class="p">,</span> <span class="n">from_</span><span class="o">=</span><span class="n">from_phone_num</span><span class="p">,</span> <span class="n">to</span><span class="o">=</span><span class="n">phone</span><span class="p">)</span> <span class="k">print</span><span class="p">(</span><span class="n">message</span><span class="p">.</span><span class="n">sid</span><span class="p">)</span> <span class="c1"># 使用139邮箱的短信通知功能 </span><span class="k">def</span> <span class="nf">send_email</span><span class="p">(</span><span class="n">email</span><span class="p">,</span> <span class="n">subject</span><span class="p">,</span> <span class="n">msg</span><span class="p">):</span> <span class="kn">from</span> <span class="nn">smtplib</span> <span class="kn">import</span> <span class="n">SMTPException</span><span class="p">,</span> <span class="n">SMTP_SSL</span> <span class="kn">from</span> <span class="nn">email.mime.text</span> <span class="kn">import</span> <span class="n">MIMEText</span> <span class="kn">from</span> <span class="nn">email.header</span> <span class="kn">import</span> <span class="n">Header</span> <span class="c1"># 发件人 </span> <span class="n">sender</span> <span class="o">=</span> <span class="n">EMAIL_FROM</span> <span class="n">pwd</span> <span class="o">=</span> <span class="n">EMAIL_PWD</span> <span class="c1"># 三个参数:第一个为文本内容,第二个为plain设置文本格式,第三个为utf-8设置编码 </span> <span class="n">message</span> <span class="o">=</span> <span class="n">MIMEText</span><span class="p">(</span><span class="n">msg</span><span class="p">,</span><span class="s">"plain"</span><span class="p">,</span><span class="s">'utf-8'</span><span class="p">)</span> <span class="n">message</span> <span class="p">[</span><span class="s">'From'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Header</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span><span class="s">'utf-8'</span><span class="p">)</span> <span class="n">message</span> <span class="p">[</span><span class="s">'To'</span><span class="p">]</span> <span class="o">=</span> <span class="n">Header</span><span class="p">(</span><span class="n">email</span><span class="p">,</span><span class="s">'utf-8'</span><span class="p">)</span> <span class="n">message</span><span class="p">[</span><span class="s">"Subject"</span><span class="p">]</span> <span class="o">=</span> <span class="n">Header</span><span class="p">(</span><span class="n">subject</span><span class="p">,</span><span class="s">"utf-8"</span><span class="p">)</span> <span class="k">try</span><span class="p">:</span> <span class="c1"># 使用非本地服务器,需要建立ssl连接 </span> <span class="n">smtpObj</span> <span class="o">=</span> <span class="n">SMTP_SSL</span><span class="p">(</span><span class="s">"smtp.exmail.qq.com"</span><span class="p">,</span> <span class="mi">465</span><span class="p">)</span> <span class="n">smtpObj</span><span class="p">.</span><span class="n">login</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span><span class="n">pwd</span><span class="p">)</span> <span class="n">smtpObj</span><span class="p">.</span><span class="n">sendmail</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span><span class="n">email</span><span class="p">,</span><span class="n">message</span><span class="p">.</span><span class="n">as_string</span><span class="p">())</span> <span class="k">print</span><span class="p">(</span><span class="s">"邮件发送成功"</span><span class="p">)</span> <span class="k">except</span> <span class="n">SMTPException</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="k">print</span><span class="p">(</span><span class="s">"Error:无法发送邮件.Case:%s"</span><span class="o">%</span><span class="n">e</span><span class="p">)</span> <span class="c1"># 检测下载进程是否正在运行 </span><span class="k">def</span> <span class="nf">isRunning</span><span class="p">(</span><span class="n">search_param</span><span class="p">):</span> <span class="n">output</span> <span class="o">=</span> <span class="n">os</span><span class="p">.</span><span class="n">popen</span><span class="p">(</span><span class="s">'ps -ef | grep {}'</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">search_param</span><span class="p">))</span> <span class="n">length</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">output</span><span class="p">:</span> <span class="c1"># print(line) </span> <span class="k">if</span> <span class="s">"/bin/sh"</span> <span class="ow">in</span> <span class="n">line</span> <span class="ow">or</span> <span class="s">"grep"</span> <span class="ow">in</span> <span class="n">line</span> <span class="ow">or</span> <span class="s">"Terminated"</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span> <span class="k">continue</span> <span class="n">length</span> <span class="o">=</span> <span class="n">length</span> <span class="o">+</span> <span class="mi">1</span> <span class="c1"># print(length) </span> <span class="k">return</span> <span class="bp">True</span> <span class="k">if</span> <span class="n">length</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="bp">False</span> <span class="c1"># 获取系统用户名和ip </span><span class="k">def</span> <span class="nf">getInfomation</span><span class="p">():</span> <span class="n">user</span> <span class="o">=</span> <span class="n">socket</span><span class="p">.</span><span class="n">gethostname</span><span class="p">()</span> <span class="c1"># 创建socket访问DNS来获取本机的IP,如果是NAT的话,则是局域网IP </span> <span class="n">local_ip</span> <span class="o">=</span> <span class="s">"127.0.0.1"</span> <span class="k">try</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="n">socket</span><span class="p">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="p">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="p">.</span><span class="n">SOCK_DGRAM</span><span class="p">)</span> <span class="n">s</span><span class="p">.</span><span class="n">connect</span><span class="p">((</span><span class="s">'1.1.1.1'</span><span class="p">,</span> <span class="mi">80</span><span class="p">))</span> <span class="n">local_ip</span> <span class="o">=</span> <span class="n">s</span><span class="p">.</span><span class="n">getsockname</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span> <span class="k">finally</span><span class="p">:</span> <span class="n">s</span><span class="p">.</span><span class="n">close</span><span class="p">()</span> <span class="c1"># 访问www.ip.cn网站获取公网IP </span> <span class="n">net_ip</span> <span class="o">=</span> <span class="s">"127.0.0.1"</span> <span class="k">try</span><span class="p">:</span> <span class="n">net_ip</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">'https://api.ipify.org'</span><span class="p">).</span><span class="n">text</span> <span class="k">finally</span><span class="p">:</span> <span class="k">pass</span> <span class="k">return</span> <span class="p">(</span><span class="n">user</span><span class="p">,</span> <span class="n">local_ip</span><span class="p">,</span> <span class="n">net_ip</span><span class="p">)</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span> <span class="n">status</span> <span class="o">=</span> <span class="n">isRunning</span><span class="p">(</span><span class="s">"download.py"</span><span class="p">)</span> <span class="n">flag_file</span> <span class="o">=</span> <span class="s">"/home/ubuntu/flag"</span> <span class="c1"># now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") </span> <span class="k">if</span> <span class="n">status</span><span class="p">:</span> <span class="n">logging</span><span class="p">.</span><span class="n">debug</span><span class="p">(</span><span class="s">"program is running"</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">if</span> <span class="n">os</span><span class="p">.</span><span class="n">path</span><span class="p">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">flag_file</span><span class="p">):</span> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">"program stopped, nobody fixed it."</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="n">info</span> <span class="o">=</span> <span class="n">getInfomation</span><span class="p">()</span> <span class="n">msg</span> <span class="o">=</span> <span class="s">"您的主机{},公网IP地址为{},局域网IP为{},下载进程已中断"</span><span class="p">.</span><span class="nb">format</span><span class="p">(</span><span class="n">info</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">info</span><span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="n">info</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="n">phone</span> <span class="o">=</span> <span class="s">"13612345678"</span> <span class="n">sendSMS</span><span class="p">(</span><span class="n">phone</span><span class="p">,</span> <span class="p">[</span><span class="s">'spy'</span><span class="p">,</span> <span class="n">msg</span><span class="p">])</span> <span class="n">send_sms</span><span class="p">(</span><span class="n">phone</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="n">send_email</span><span class="p">(</span><span class="s">"user@qq.com"</span><span class="p">,</span> <span class="s">"spy"</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span> <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">flag_file</span><span class="p">,</span> <span class="s">"w+"</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span> <span class="nb">file</span><span class="p">.</span><span class="n">write</span><span class="p">(</span><span class="s">"Please delete me after restarting the download program."</span><span class="p">)</span> <span class="n">logging</span><span class="p">.</span><span class="n">error</span><span class="p">(</span><span class="s">"program stopped"</span><span class="p">)</span> </code></pre></div></div> <h2 id="运行监控代码文件">运行监控代码文件</h2> <p>在终端输入<code class="language-plaintext highlighter-rouge">crontab -e</code>打开定时管理任务,然后在文件中最后添加一行,内容如下:<br /> <code class="language-plaintext highlighter-rouge">*/30 * * * * python3 /home/ubuntu/detect.py</code><br /> 此代码表示每隔30min运行一次<br /> <strong>注意</strong>:每次重新启动下载进程之后,务必删除<code class="language-plaintext highlighter-rouge">flag</code>文件(为了防止因为没有及时重启下载进程而浪费短信资源,在主目录<code class="language-plaintext highlighter-rouge">~</code>下输入<code class="language-plaintext highlighter-rouge">rm flag</code>即可删除此文件)</p>

2021/2/11
阅读更多

在linux系统使用expect命令自动填充ssh或scp等命令的密码

<h2 class="no_toc" id="目录">目录</h2> <ul id="markdown-toc"> <li><a href="#expect命令使用范例" id="markdown-toc-expect命令使用范例">expect命令使用范例</a></li> </ul> <h2 id="expect命令使用范例">expect命令使用范例</h2> <p>shell脚本文件的名称为<code class="language-plaintext highlighter-rouge">download.sh</code>,内容如下:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span> <span class="c"># 任何一句命令执行出错,都会终止该脚本</span> <span class="nb">set</span> <span class="nt">-e</span> <span class="c"># 设置为调试模式,在执行过程中会同时输出各变量的值</span> <span class="c"># set -x</span> <span class="c"># 连接scp</span> <span class="c">#######################</span> <span class="c"># expect {</span> <span class="c"># -re ".*es.*o.*" {</span> <span class="c"># exp_send "yes\r"</span> <span class="c"># exp_continue</span> <span class="c"># }</span> <span class="c"># -re ".*sword.*" {</span> <span class="c"># exp_send "mypwd12345\r"</span> <span class="c"># }</span> <span class="c"># }</span> <span class="c"># 把远程机器上的文件下载到本地机器</span> <span class="c"># 参数1: 远程机器上的文件(或文件夹)的绝对路径</span> <span class="c"># 参数2: 存放位置,即本地机器上的文件夹</span> <span class="c"># 当scp下载大文件时,需要耗费更多时间,设置timeout</span> <span class="k">function </span>scp_download<span class="o">(){</span> <span class="nv">src</span><span class="o">=</span><span class="nv">$1</span> <span class="nv">dst</span><span class="o">=</span><span class="nv">$2</span> <span class="k">if</span> <span class="o">[</span> <span class="nv">$# </span><span class="nt">-eq</span> 2 <span class="o">]</span> <span class="k">then </span><span class="nv">need_ssh</span><span class="o">=</span>0 <span class="k">else </span><span class="nv">need_ssh</span><span class="o">=</span><span class="nv">$3</span> <span class="k">fi </span><span class="nv">name</span><span class="o">=</span>zfb <span class="nv">host</span><span class="o">=</span><span class="s2">"192.168.1.56"</span> <span class="nv">passwd</span><span class="o">=</span><span class="s2">"1234567890pwd"</span> <span class="k">if</span> <span class="o">[</span> <span class="nv">$3</span> <span class="nt">-eq</span> 1 <span class="o">]</span> <span class="k">then</span> <span class="c"># ssh登录远程机器,为目标文件添加读写执行权限</span> /usr/bin/expect<span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> spawn ssh </span><span class="nv">$name</span><span class="sh">@</span><span class="nv">$host</span><span class="sh"> expect { -timeout -1 "*yes/no" { send "yes</span><span class="se">\r</span><span class="sh">";exp_continue } "*password:" { send "</span><span class="nv">$passwd</span><span class="se">\r</span><span class="sh">" # zfb@my-Server:~$ expect "~.*</span><span class="nv">$"</span><span class="sh"> send "sudo chmod 777 </span><span class="nv">$src</span><span class="se">\r</span><span class="sh">" expect "*assword:" send "</span><span class="nv">$passwd</span><span class="se">\r</span><span class="sh">" expect "~.*</span><span class="nv">$"</span><span class="sh"> send "exit</span><span class="se">\r</span><span class="sh">" expect eof } } </span><span class="no">EOF </span><span class="k">fi</span> <span class="c"># 使用scp自动下载文件</span> /usr/bin/expect<span class="o">&lt;&lt;</span><span class="no">EOF</span><span class="sh"> set timeout 600 spawn scp -r </span><span class="nv">$name</span><span class="sh">@</span><span class="nv">$host</span><span class="sh">:</span><span class="nv">$src</span><span class="sh"> </span><span class="nv">$dst</span><span class="sh"> expect { "*yes/no" { send "yes</span><span class="se">\r</span><span class="sh">";exp_continue } "*password:" { send "</span><span class="nv">$passwd</span><span class="se">\r</span><span class="sh">" expect eof } } </span><span class="no">EOF </span><span class="o">}</span> <span class="c"># 脚本运行参数</span> <span class="c"># 参数1: 远程机器的文件(夹)绝对路径, 例如 /media/data/test/a.txt</span> <span class="c"># 参数2:保存位置,即本地路径</span> <span class="c"># 若本地不存在,则创建目录</span> <span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-d</span> <span class="nv">$2</span> <span class="o">]</span> <span class="k">then </span><span class="nb">echo</span> <span class="nv">$2</span><span class="s2">" does not exist, ready to mkdir "</span><span class="nv">$2</span> <span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nv">$2</span> <span class="nb">echo</span> <span class="s2">"mkdir successfully!"</span> <span class="k">fi </span><span class="nv">data</span><span class="o">=</span><span class="nv">$2</span>/opendata <span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-d</span> <span class="nv">$data</span> <span class="o">]</span> <span class="k">then </span><span class="nb">echo</span> <span class="nv">$data</span><span class="s2">" does not exist, ready to mkdir "</span><span class="nv">$data</span> <span class="nb">mkdir</span> <span class="nt">-p</span> <span class="nv">$data</span> <span class="nb">echo</span> <span class="s2">"mkdir successfully!"</span> <span class="k">fi </span>scp_download <span class="nv">$1</span>/test.txt <span class="nv">$2</span> scp_download <span class="nv">$1</span>/test/testaa.py <span class="nv">$2</span> <span class="nb">mv</span> <span class="nv">$2</span>/testaa.py <span class="nv">$2</span>/testbb.py scp_download <span class="nv">$1</span>/test/opendata/testcc.txt <span class="nv">$data</span> <span class="c"># testdd.txt在远程机器上,无读取权限,需要ssh进行chmod添加权限</span> scp_download <span class="nv">$1</span>/test/opendata/testdd.txt <span class="nv">$data</span> 1 </code></pre></div></div> <p>使用方法示例:<br /> <code class="language-plaintext highlighter-rouge">./download.sh /media/data/test ./</code></p>

2021/1/16
阅读更多