<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>shensunbo Blog</title>
    <description>沈孙博的博客 | C++ and Rendering Development Blog</description>
    <link>https://shensunbo.github.io/</link>
    <atom:link href="https://shensunbo.github.io/feed.xml" rel="self" type="application/rss+xml" />
    <pubDate>Tue, 27 Oct 2026 07:23:00 +0000</pubDate>
    <lastBuildDate>Tue, 27 Oct 2026 07:23:00 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
    
      <item>
        <title>公司开启连接网络设备认证后台架如何连接网络</title>
        <description>&lt;p&gt;IT 开启MAC 地址准入控制（MAC Authentication / MAC-based Access Control，但台架使用随机MAC地址和自己的笔记本使用USB转接器来连接网络，导致无法通过认证。&lt;/p&gt;

&lt;h1 id=&quot;台架使用随机mac&quot;&gt;台架使用随机MAC&lt;/h1&gt;
&lt;p&gt;android台架使用随机MAC地址之后，每次连接WIFI的时候可能MAC地址都会变化，或者无法设置成本机的MAC地址，导致无法通过认证。可以使用脚本修改为固定的MAC地址，然后使用脚本进行网络连接，参考脚本&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-euo&lt;/span&gt; pipefail

&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPENAI_WIFI_SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;Opus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;-Office&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPENAI_WIFI_MAC&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;00&lt;/span&gt;:08:22:bc:aa:fb&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPENAI_WIFI_PASSWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;TIMEOUT_SECONDS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;OPENAI_WIFI_TIMEOUT&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-z&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-t&lt;/span&gt; 0 &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Password for &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;: &quot;&lt;/span&gt; PASSWORD
    &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\n&apos;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Set OPENAI_WIFI_PASSWORD before running this script.\n&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;2
  &lt;span class=&quot;k&quot;&gt;fi
fi

&lt;/span&gt;adb wait-for-device

&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Waiting for Android to finish booting...\n&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;i &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i &amp;lt; 60&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i++&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;adb shell getprop sys.boot_completed 2&amp;gt;/dev/null | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;break
  &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sleep &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;done

if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;adb shell getprop sys.boot_completed 2&amp;gt;/dev/null | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Android did not finish booting within 60 seconds.\n&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Preparing Wi-Fi configuration...\n&apos;&lt;/span&gt;
adb shell cmd wifi set-wifi-enabled disabled &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null

&lt;span class=&quot;c&quot;&gt;# Remove the saved target so auto-join cannot race ahead with another MAC.&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;read&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; network_id&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;network_id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;continue
  &lt;/span&gt;adb shell cmd wifi forget-network &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;network_id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt; &amp;lt; &amp;lt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
  adb shell cmd wifi list-networks |
    &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ssid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$2 == ssid { print $1 }&apos;&lt;/span&gt; |
    &lt;span class=&quot;nb&quot;&gt;sort&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-u&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

adb shell settings put global wifi_connected_mac_randomization_enabled 0
adb shell settings put global wifi_scan_mac_randomization_enabled 0
adb shell cmd wifi force-overlay-config-value &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  bool config_wifi_connected_mac_randomization_supported enabled &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null

adb shell cmd wifi set-wifi-enabled enabled &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null

&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Waiting for the Wi-Fi client interface...\n&apos;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;mac_set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;i &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i &amp;lt; 30&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i++&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;adb shell cmd wifi status 2&amp;gt;/dev/null | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Fq&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;iface=wlan0&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
    adb shell su 0 ip &lt;span class=&quot;nb&quot;&gt;link set &lt;/span&gt;dev wlan0 address &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;actual_mac&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;
      adb shell &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /sys/class/net/wlan0/address 2&amp;gt;/dev/null |
        &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt; |
        &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[:upper:]&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[:lower:]&apos;&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;actual_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mac_set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true
      break
    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi
  fi
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sleep &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;done

if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mac_set&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Failed to set wlan0 MAC to %s.\n&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
  &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Connecting to %s with MAC %s...\n&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
adb shell cmd wifi connect-network &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; wpa2 &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; none

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;i &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i &amp;lt; TIMEOUT_SECONDS&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; i++&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;adb shell cmd wifi status 2&amp;gt;/dev/null | &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Fq&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Wifi is connected to &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;current_mac&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;
      adb shell &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /sys/class/net/wlan0/address 2&amp;gt;/dev/null |
        &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt; |
        &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[:upper:]&apos;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;[:lower:]&apos;&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;current_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;MAC&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,,&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
      &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Connected with unexpected MAC %s.\n&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;current_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
      &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
    &lt;span class=&quot;k&quot;&gt;fi

    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ip_address&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;
      adb shell ip &lt;span class=&quot;nt&quot;&gt;-4&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; addr show dev wlan0 2&amp;gt;/dev/null |
        &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;{print $4}&apos;&lt;/span&gt; |
        &lt;span class=&quot;nb&quot;&gt;tr&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\r&apos;&lt;/span&gt;
    &lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Connected: SSID=%s MAC=%s IP=%s\n&apos;&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SSID&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;current_mac&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ip_address&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unknown&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;0
  &lt;span class=&quot;k&quot;&gt;fi
  &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sleep &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;done

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;printf&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;Connection timed out after %s seconds.\n&apos;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;TIMEOUT_SECONDS&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
adb shell cmd wifi status &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
&lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;笔记本使用转接器连接网络&quot;&gt;笔记本使用转接器连接网络&lt;/h1&gt;
&lt;p&gt;USB转接器连接网络，使用的MAC地址是转接器的MAC地址，而不是笔记本的网卡的MAC地址，导致无法通过认证。需要修改笔记本的网卡的MAC地址为转接器的MAC地址，才能通过认证。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;查询网卡mac地址
```bash
➜  ~ ip link
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
  link/ether 28:c5:c8:d5:d6:ac brd ff:ff:ff:ff:ff:ff
  altname enp3s0
4: wlo1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
  link/ether 98:bd:80:95:be:e2 brd ff:ff:ff:ff:ff:ff
  altname wlp0s20f3
26: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
  link/ether 66:5b:34:98:71:fd brd ff:ff:ff:ff:ff:ff&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;- 设置mac地址
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;sudo ip link set eno1 down
sudo ip link set eth0 down
sudo ip link set eth0 address 28:c5:c8:d5:d6:ac
sudo ip link set eth0 up&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-`&quot;&gt;- 设置之后的状态
```bash
➜  ~ ip link                   
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eno1: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc fq_codel state DOWN mode DEFAULT group default qlen 1000
    link/ether 28:c5:c8:d5:d6:ac brd ff:ff:ff:ff:ff:ff
    altname enp3s0
4: wlo1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP mode DORMANT group default qlen 1000
    link/ether 98:bd:80:95:be:e2 brd ff:ff:ff:ff:ff:ff
    altname wlp0s20f3
26: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether 28:c5:c8:d5:d6:ac brd ff:ff:ff:ff:ff:ff
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
  &lt;p&gt;重新拔插之后失效&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;其他方式如果确定不再用自带的网口了&quot;&gt;其他方式，如果确定不再用自带的网口了&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;复制以下内容到终端执行：
sudo tee /etc/systemd/network/10-usb-eth0.link &amp;gt; /dev/null &amp;lt;&amp;lt;&apos;EOF&apos;
[Match]
Driver=r8152
[Link]
MACAddress=28:c5:c8:d5:d6:ac
EOF
sudo udevadm control --reload &amp;amp;&amp;amp; sudo udevadm trigger
验证（拔插一次或重启后）：
cat /sys/class/net/eth0/address        # 应为 28:c5:c8:d5:d6:ac
cat /sys/class/net/eth0/addr_assign_type  # 应为 3 (SET)，不再是 1 (RANDOM)
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Wed, 29 Jul 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/07/29/wlan/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/07/29/wlan/</guid>
        
        <category>tools</category>
        
        
      </item>
    
      <item>
        <title>买二手车</title>
        <description>&lt;h1 id=&quot;检查内容&quot;&gt;检查内容&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;出险记录&lt;/li&gt;
  &lt;li&gt;维保记录&lt;/li&gt;
  &lt;li&gt;机动车行驶证，使用性质非营运&lt;/li&gt;
  &lt;li&gt;抵押登记，解除抵押&lt;/li&gt;
  &lt;li&gt;转移登记&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;？ 第三方检测&lt;/p&gt;

&lt;h1 id=&quot;准备材料&quot;&gt;准备材料&lt;/h1&gt;

&lt;h1 id=&quot;注意事项&quot;&gt;注意事项&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;先过户后付款&lt;/li&gt;
  &lt;li&gt;如果需要先付款：备注：如无法过户，需全额退款&lt;/li&gt;
  &lt;li&gt;绿本&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;验车步骤&quot;&gt;验车步骤&lt;/h1&gt;

&lt;h1 id=&quot;询问&quot;&gt;询问&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;上次保养时间和项目，查看记录&lt;/li&gt;
  &lt;li&gt;轮胎年限&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;买之后的整备&quot;&gt;买之后的整备&lt;/h1&gt;
&lt;h2 id=&quot;保养&quot;&gt;保养&lt;/h2&gt;
&lt;p&gt;[ ] 机油+机滤	   ✅ 必做
[ ] 空气/空调滤芯   ✅ 必做 自己买
[ ] 刹车油/防冻液   ✅ 必做
[ ] 变速箱油（干式双离合）✅ 必做
[ ] 正时皮带套装    ✅ 必做
[ ] 底盘胶套/摆臂   ✅ 检查后决
[ ] 清洗积碳（挖煤） ✅ 可选&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/07/21/usedCar/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/07/21/usedCar/</guid>
        
        <category>tools</category>
        
        
      </item>
    
      <item>
        <title>C++ 静态链接时自注册对象被裁剪的问题</title>
        <description>&lt;h2 id=&quot;现象&quot;&gt;现象&lt;/h2&gt;

&lt;p&gt;某 TCP 命令系统注册了一个全局静态对象，期望在 main() 之前自动注册到命令注册表：&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Command&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// 全局静态变量，构造函数会执行注册&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Command&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g_myCmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;代码编译为静态库（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.a&lt;/code&gt;），最终链接到可执行文件或共享库（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.so&lt;/code&gt;）。运行时发送 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hello&lt;/code&gt; 命令，返回：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;hello&quot; is not recognized as a valid command.
Type &quot;help&quot; to get a list of all available commands
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;命令没有被注册。&lt;/p&gt;

&lt;h2 id=&quot;为什么&quot;&gt;为什么&lt;/h2&gt;

&lt;h3 id=&quot;静态库的按需提取机制&quot;&gt;静态库的”按需提取”机制&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.a&lt;/code&gt; 文件本质是目标文件（&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.o&lt;/code&gt;）的归档包。链接器处理静态库时，不会把整个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.a&lt;/code&gt; 都链接进去，而是遍历每个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.o&lt;/code&gt;，只提取那些&lt;strong&gt;提供了被其他已链接代码引用的符号&lt;/strong&gt;的目标文件。&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# 伪代码
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;定义了&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;needed&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;中任意符号&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;提取&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;链接到最终产物&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;跳过&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 没被任何人引用
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;链接器只看符号，不看副作用。&lt;/p&gt;

&lt;h3 id=&quot;c-自注册模式的盲区&quot;&gt;C++ 自注册模式的盲区&lt;/h3&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// 编译为 cmd_registry.cpp → cmd_registry.o&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;Command&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;g_myCmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// 从未直接引用 g_myCmd&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Registry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.o&lt;/code&gt; 引用了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Registry::get()&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Registry::dispatch()&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd_registry.o&lt;/code&gt; 定义了 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g_myCmd&lt;/code&gt; 的构造函数，但 &lt;strong&gt;没有其他 .o 引用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;g_myCmd&lt;/code&gt; 这个符号&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;链接器视角：没人要这个符号 → 跳过 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd_registry.o&lt;/code&gt; → 构造函数永远不执行。&lt;/p&gt;

&lt;p&gt;注册的副作用对链接器完全透明。&lt;/p&gt;

&lt;h3 id=&quot;加上---gc-sections-更彻底&quot;&gt;加上 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--gc-sections&lt;/code&gt; 更彻底&lt;/h3&gt;

&lt;p&gt;Android NDK 等工具链默认开启：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;-ffunction-sections -fdata-sections -Wl,--gc-sections
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;每个函数和全局变量被分配到独立段。即使之前被”按需提取”的 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.o&lt;/code&gt;，如果其中某个段没有被其他段引用，该段也可能被逐个裁剪。双重过滤下，纯副作用的自注册对象更难存活。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;注：debug 和 release 构建都默认开启此选项。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;解决方案&quot;&gt;解决方案&lt;/h2&gt;

&lt;h3 id=&quot;方案一--whole-archive推荐&quot;&gt;方案一：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--whole-archive&lt;/code&gt;（推荐）&lt;/h3&gt;

&lt;p&gt;链接时强制包含整个静态库：&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;my_target PRIVATE
    &lt;span class=&quot;s2&quot;&gt;&quot;-Wl,--whole-archive&quot;&lt;/span&gt; my_lib &lt;span class=&quot;s2&quot;&gt;&quot;-Wl,--no-whole-archive&quot;&lt;/span&gt;
    other_libs...&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--whole-archive&lt;/code&gt; 告诉链接器：不要检查引用，把这个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.a&lt;/code&gt; 里所有 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.o&lt;/code&gt; 都包含进来。&lt;/p&gt;

&lt;h3 id=&quot;方案二显式引用&quot;&gt;方案二：显式引用&lt;/h3&gt;

&lt;p&gt;在入口点代码中引用关键符号，让链接器知道它有用：&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// main.cpp — 在任意被引用的编译单元中&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Command&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;g_myCmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keep_myCmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;g_myCmd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// 强制包含 cmd_registry.o&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;方案三改用-object-库&quot;&gt;方案三：改用 OBJECT 库&lt;/h3&gt;

&lt;p&gt;CMake OBJECT 库的所有 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.o&lt;/code&gt; 总是会被包含：&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# 改为 OBJECT 库&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;add_library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;my_lib OBJECT &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;SOURCES&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# 链接时直接引用对象&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;my_target PRIVATE $&amp;lt;TARGET_OBJECTS:my_lib&amp;gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;如何验证&quot;&gt;如何验证&lt;/h2&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# 检查静态库中是否有该符号&lt;/span&gt;
nm libmy_lib.a | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;g_myCmd

&lt;span class=&quot;c&quot;&gt;# 检查最终产物中是否有该符号&lt;/span&gt;
nm libmy_target.so | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;g_myCmd
&lt;span class=&quot;c&quot;&gt;# 如果 .a 中有但 .so 中没有 → 被裁剪了&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;总结&quot;&gt;总结&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;情况&lt;/th&gt;
      &lt;th style=&quot;text-align: center&quot;&gt;结果&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;同一编译单元内直接调用&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;✅ 正常&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;被其他 .o 引用的函数&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;✅ 正常&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;仅通过全局静态对象构造注册&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;❌ 被裁剪&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;加上 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--whole-archive&lt;/code&gt;&lt;/td&gt;
      &lt;td style=&quot;text-align: center&quot;&gt;✅ 强制包含&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;自注册模式是 C++ 中常见的”隐式约定”，但链接器只承认符号引用。理解静态库的按需提取行为，才能在设计插件系统、命令框架、工厂注册等场景时避开这个坑。&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/07/21/static-link-self-register/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/07/21/static-link-self-register/</guid>
        
        <category>c++</category>
        
        <category>linker</category>
        
        
      </item>
    
      <item>
        <title>git bisect 定位哪个 commit 引入了 bug</title>
        <description>&lt;h1 id=&quot;step-1&quot;&gt;step 1&lt;/h1&gt;
&lt;p&gt;确定一个已知的坏的 commit（包含 bug）和一个已知的好的 commit（不包含 bug）。&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;git bisect start
git bisect bad HEAD
git bisect good v1.0
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;step-2&quot;&gt;step 2&lt;/h1&gt;
&lt;p&gt;Git 会自动切换到一个中间的 commit，运行测试或检查代码以确定该 commit 是否包含 bug。根据结果标记该 commit 为好或坏：&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;git bisect good  &lt;span class=&quot;c&quot;&gt;# 如果该 commit 没有 bug&lt;/span&gt;
git bisect bad   &lt;span class=&quot;c&quot;&gt;# 如果该 commit 有 bug&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h1 id=&quot;step-3&quot;&gt;step 3&lt;/h1&gt;
&lt;p&gt;重复步骤 2，Git 会继续缩小范围，直到找到引入 bug 的具体 commit。最终，Git 会输出引入 bug 的 commit 的哈希值和提交信息。&lt;/p&gt;

&lt;p&gt;todo: real eg.&lt;/p&gt;
</description>
        <pubDate>Thu, 25 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/06/25/gitBisect/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/06/25/gitBisect/</guid>
        
        <category>tools</category>
        
        
      </item>
    
      <item>
        <title>android 使用adb命令修改VHAL属性</title>
        <description>&lt;p&gt;命令：&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;adb shell dumpsys activity service com.android.car inject-vhal-event 0x26400241 0x10 1
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;参数说明：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x26400241&lt;/code&gt;：VHAL 属性 ID。从 ID 格式看，属于 OEM 自定义范围（标准 Android 属性通常在 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x01000000&lt;/code&gt;-&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x06000000&lt;/code&gt;）。具体含义取决于车型定义，可能表示某个车门、车窗或座舱功能。&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x10&lt;/code&gt;：Area ID，表示操作的区域。常见值：
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x01&lt;/code&gt;：前排左侧&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x02&lt;/code&gt;：前排右侧&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x10&lt;/code&gt;：可能表示全车或特定区域&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;1&lt;/code&gt;：注入的值，通常是布尔值（0 = 关闭/false，1 = 开启/true）或状态值&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;前置条件&quot;&gt;前置条件&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;UserDebug 或 Eng 版本
    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;adb shell getprop ro.build.type
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;
</description>
        <pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/06/02/VHAL/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/06/02/VHAL/</guid>
        
        <category>android</category>
        
        
      </item>
    
      <item>
        <title>android 浮窗视图圆角bugfix</title>
        <description>&lt;p&gt;目前实现浮窗视图的方式是通过在android侧创建一个透明的egl surface，在C++侧完成绘制后，android的窗口管理器会根据surface上的内容与背景进行混合，如果alpha的值不为0，混合后的结果会有一个半透明的效果。&lt;br /&gt;
这个会导致一个问题，在不是圆角的部分，如果有半透明物体，比如打开了透明底盘模式，在混合的时候会混合android的后台界面。如果使用OSG的默认混合模式，就会有这种现象。&lt;br /&gt;
解决方法是将透明度混合模式也单独设置,保证混合之后的透明度值为1：&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt; osg::ref_ptr&amp;lt;osg::BlendFunc&amp;gt; tmp_bf = new osg::BlendFunc(
    osg::BlendFunc::SRC_ALPHA, 
    osg::BlendFunc::ONE_MINUS_SRC_ALPHA,
    osg::BlendFunc::ZERO,
    osg::BlendFunc::ONE
  );
  tmp_pSt-&amp;gt;setAttributeAndModes(tmp_bf.get(), osg::StateAttribute::ON);
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果不设置透明度混合模式，默认RGB 和 Alpha 使用相同因子，即混合后alpha值不为1&lt;/p&gt;
</description>
        <pubDate>Wed, 20 May 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/05/20/floatView/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/05/20/floatView/</guid>
        
        <category>graphics</category>
        
        <category>android</category>
        
        
      </item>
    
      <item>
        <title>渲染器使用的模型格式由fbx修改为glb</title>
        <description>&lt;p&gt;参考 &lt;a href=&quot;https://github.com/shensunbo/render_explore_by_opengl&quot;&gt;renderer demo&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;模型处理&quot;&gt;模型处理&lt;/h1&gt;
&lt;h2 id=&quot;问题&quot;&gt;问题&lt;/h2&gt;
&lt;ol&gt;
  &lt;li&gt;使用blender导出为GLB之后，在渲染器中加载，模型变得很肖，可能是单位的问题
    &lt;ul&gt;
      &lt;li&gt;Blender exports GLB/glTF files in meters by default&lt;/li&gt;
      &lt;li&gt;fbx 一般是cm&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;使用assimp加载glb，模型材质解析部分报错
    &lt;ul&gt;
      &lt;li&gt;FBX 使用 Phong 材质模型 → AI_MATKEY_COLOR_SPECULAR、AI_MATKEY_COLOR_AMBIENT 等属性存在&lt;/li&gt;
      &lt;li&gt;GLB/glTF 使用 PBR（基于物理的渲染）材质模型 → 这些 Phong 式属性在格式中根本不存在，Assimp 解析后这些 key 无法获取&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;效果&quot;&gt;效果&lt;/h2&gt;
&lt;h3 id=&quot;加载时间显著减少同样使用assimp&quot;&gt;加载时间显著减少(同样使用assimp)&lt;/h3&gt;
&lt;h4 id=&quot;x86&quot;&gt;x86&lt;/h4&gt;
&lt;ul&gt;
  &lt;li&gt;fbx：380ms&lt;/li&gt;
  &lt;li&gt;glb：180ms&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;ti-tda4&quot;&gt;TI TDA4&lt;/h4&gt;
</description>
        <pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/04/23/glb/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/04/23/glb/</guid>
        
        <category>graphics</category>
        
        <category>tools</category>
        
        
      </item>
    
      <item>
        <title>网络相关问题排查</title>
        <description>&lt;p&gt;最近在调试TBOX，遇到了一些网络相关的问题，记录一下排查过程和解决方案。&lt;/p&gt;

&lt;h1 id=&quot;issues&quot;&gt;issues&lt;/h1&gt;
&lt;ol&gt;
  &lt;li&gt;ping可以通，TBOX发送的someip offer消息主机可以收到，主机向TBOX发送握手消息没回复，TBOX端可以抓到握手消息，但TBOX没有回复。
    &lt;ul&gt;
      &lt;li&gt;ping走的是ICMP协议，不需要握手，ping可以通不代表TCP/UDP协议也能通。&lt;/li&gt;
      &lt;li&gt;确认TBOX是否监听了对应的端口，确认协议栈是否正常工作。&lt;/li&gt;
      &lt;li&gt;尝试编写一个测试bin，向不同的端口发送握手消息，看是否都没有回复&lt;/li&gt;
      &lt;li&gt;关闭防火墙，关闭selinux权限，都没有用&lt;/li&gt;
      &lt;li&gt;TBOX端收到没有任何回复，说明消息本身有问题，checksum不对，导致直接被丢弃了。
        &lt;ul&gt;
          &lt;li&gt;与应用无关&lt;/li&gt;
          &lt;li&gt;检查协议栈网卡等，解决checksum问题&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;checksum不对对接收端的影响和对tcpdump抓包的影响：
        &lt;ul&gt;
          &lt;li&gt;对接收端的影响：如果checksum不正确，接收端会认为数据包已经损坏，并且会丢弃这个数据包。这是因为checksum是用来验证数据包在传输过程中是否发生了错误的，如果checksum不匹配，接收端就无法确定数据包的完整性和正确性，因此会选择丢弃它。且不会有任何ACK回复。&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;使用其他环境double check， 比如其他板子，或者直接连接到PC上，如果正常工作，说明问题出在环境上，可能是网卡驱动或者协议栈的问题。&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;tools&quot;&gt;tools&lt;/h1&gt;
&lt;h2 id=&quot;tcpdump&quot;&gt;tcpdump&lt;/h2&gt;
&lt;p&gt;tcpdump基本指令，可以直接在终端查看也可以输出到文件&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;查看某个端口的流量
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 port 12345&lt;/li&gt;
      &lt;li&gt;tcpdump -i any&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;指定ip
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 host 192.168.1.1&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;输出到文件
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 port 12345 -w output.pcap&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;直接在终端查看数据包内容()
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 port 12345 -A
  -e：在输出中显示链路层头信息（MAC 地址、ethertype、VLAN 等）。
  -n：不要解析主机名（显示数字 IP）&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;输出详细程序
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 port 12345 -v /-vv/-vvv&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;指定协议
    &lt;ul&gt;
      &lt;li&gt;tcpdump -i eth0 udp port 12345&lt;/li&gt;
      &lt;li&gt;tcpdump -i eth0 tcp port 12345&lt;/li&gt;
      &lt;li&gt;tcpdump -i eth0 icmp&lt;/li&gt;
      &lt;li&gt;tcpdump -i eth0 arp&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;demo&quot;&gt;demo&lt;/h2&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;shensunbo@DLFGVL3T3:~$ sudo tcpdump -i lo -nn -s 0 -c 50 tcp port 12345 -A
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:26:23.390606 IP 127.0.0.1.46470 &amp;gt; 127.0.0.1.12345: Flags [S], seq 4160873182, win 65495, options [mss 65495,sackOK,TS val 94209927 ecr 0,nop,wscale 7], length 0
E..&amp;lt;.}@.@.q&amp;lt;..........09.............0.........
............
11:26:23.390617 IP 127.0.0.1.12345 &amp;gt; 127.0.0.1.46470: Flags [S.], seq 2949431771, ack 4160873183, win 65483, options [mss 65495,sackOK,TS val 94209927 ecr 94209927,nop,wscale 7], length 0
E..&amp;lt;..@.@.&amp;lt;.........09...............0.........
............
11:26:23.390624 IP 127.0.0.1.46470 &amp;gt; 127.0.0.1.12345: Flags [.], ack 1, win 512, options [nop,nop,TS val 94209927 ecr 94209927], length 0
E..4.~@.@.qC..........09.............(.....
........
11:26:23.390660 IP 127.0.0.1.46470 &amp;gt; 127.0.0.1.12345: Flags [P.], seq 1:11, ack 1, win 512, options [nop,nop,TS val 94209927 ecr 94209927], length 10
E..&amp;gt;..@.@.q8..........09.............2.....
........hello tcp

11:26:23.390692 IP 127.0.0.1.12345 &amp;gt; 127.0.0.1.46470: Flags [.], ack 11, win 512, options [nop,nop,TS val 94209927 ecr 94209927], length 0
E..4E.@.@...........09...............(.....
........
11:27:08.566088 IP 127.0.0.1.46470 &amp;gt; 127.0.0.1.12345: Flags [F.], seq 11, ack 1, win 512, options [nop,nop,TS val 94253172 ecr 94209927], length 0
E..4..@.@.qA..........09.............(.....
..0t....
11:27:08.566154 IP 127.0.0.1.12345 &amp;gt; 127.0.0.1.46470: Flags [F.], seq 1, ack 12, win 512, options [nop,nop,TS val 94253172 ecr 94253172], length 0
E..4E.@.@...........09...............(.....
..0t..0t
11:27:08.566173 IP 127.0.0.1.46470 &amp;gt; 127.0.0.1.12345: Flags [.], ack 2, win 512, options [nop,nop,TS val 94253172 ecr 94253172], length 0
E..4..@.@.q@..........09.............(.....
..0t..0t


^C
8 packets captured
16 packets received by filter
0 packets dropped by kernel
shensunbo@DLFGVL3T3:~$ sudo tcpdump -i lo -n  -evv tcp port 12345
tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:28:07.942173 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 504, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.41664 &amp;gt; 127.0.0.1.12345: Flags [S], cksum 0xfe30 (incorrect -&amp;gt; 0xb551), seq 4206673420, win 65495, options [mss 65495,sackOK,TS val 94308686 ecr 0,nop,wscale 7], length 0
11:28:07.942183 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 54: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
    127.0.0.1.12345 &amp;gt; 127.0.0.1.41664: Flags [R.], cksum 0x260a (correct), seq 0, ack 4206673421, win 0, length 0
11:28:14.660441 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 21702, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.41676 &amp;gt; 127.0.0.1.12345: Flags [S], cksum 0xfe30 (incorrect -&amp;gt; 0x7269), seq 3015650728, win 65495, options [mss 65495,sackOK,TS val 94315404 ecr 0,nop,wscale 7], length 0
11:28:14.660456 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    127.0.0.1.12345 &amp;gt; 127.0.0.1.41676: Flags [S.], cksum 0xfe30 (incorrect -&amp;gt; 0xec66), seq 1587215927, ack 3015650729, win 65483, options [mss 65495,sackOK,TS val 94315404 ecr 94315404,nop,wscale 7], length 0
11:28:14.660466 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 21703, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.41676 &amp;gt; 127.0.0.1.12345: Flags [.], cksum 0xfe28 (incorrect -&amp;gt; 0x1323), seq 1, ack 1, win 512, options [nop,nop,TS val 94315404 ecr 94315404], length 0
11:28:14.660542 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 76: (tos 0x0, ttl 64, id 21704, offset 0, flags [DF], proto TCP (6), length 62)
    127.0.0.1.41676 &amp;gt; 127.0.0.1.12345: Flags [P.], cksum 0xfe32 (incorrect -&amp;gt; 0xeaaf), seq 1:11, ack 1, win 512, options [nop,nop,TS val 94315405 ecr 94315404], length 10
11:28:14.660549 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 14014, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.12345 &amp;gt; 127.0.0.1.41676: Flags [.], cksum 0xfe28 (incorrect -&amp;gt; 0x1317), seq 1, ack 11, win 512, options [nop,nop,TS val 94315405 ecr 94315405], length 0
^C
7 packets captured
14 packets received by filter
0 packets dropped by kernel
shensunbo@DLFGVL3T3:~$ sudo tcpdump -i lo -n  -e tcp port 12345
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:29:55.115405 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 127.0.0.1.59950 &amp;gt; 127.0.0.1.12345: Flags [S], seq 2116896596, win 65495, options [mss 65495,sackOK,TS val 94410072 ecr 0,nop,wscale 7], length 0
11:29:55.115415 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 74: 127.0.0.1.12345 &amp;gt; 127.0.0.1.59950: Flags [S.], seq 3888045621, ack 2116896597, win 65483, options [mss 65495,sackOK,TS val 94410072 ecr 94410072,nop,wscale 7], length 0
11:29:55.115421 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 127.0.0.1.59950 &amp;gt; 127.0.0.1.12345: Flags [.], ack 1, win 512, options [nop,nop,TS val 94410072 ecr 94410072], length 0
11:29:55.115458 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 76: 127.0.0.1.59950 &amp;gt; 127.0.0.1.12345: Flags [P.], seq 1:11, ack 1, win 512, options [nop,nop,TS val 94410072 ecr 94410072], length 10
11:29:55.115461 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: 127.0.0.1.12345 &amp;gt; 127.0.0.1.59950: Flags [.], ack 11, win 512, options [nop,nop,TS val 94410072 ecr 94410072], length 0
^C
5 packets captured
10 packets received by filter
0 packets dropped by kernel
shensunbo@DLFGVL3T3:~$ sudo tcpdump -i lo -n  -ev tcp port 12345
tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:30:31.252594 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 45612, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.44044 &amp;gt; 127.0.0.1.12345: Flags [F.], cksum 0xfe28 (incorrect -&amp;gt; 0x0573), seq 422335109, ack 2476240385, win 512, options [nop,nop,TS val 94444283 ecr 94437753], length 0
11:30:31.252714 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 766, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.12345 &amp;gt; 127.0.0.1.44044: Flags [F.], cksum 0xfe28 (incorrect -&amp;gt; 0xebef), seq 1, ack 1, win 512, options [nop,nop,TS val 94444283 ecr 94444283], length 0
11:30:31.252735 00:00:00:00:00:00 &amp;gt; 00:00:00:00:00:00, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 45613, offset 0, flags [DF], proto TCP (6), length 52)
    127.0.0.1.44044 &amp;gt; 127.0.0.1.12345: Flags [.], cksum 0xfe28 (incorrect -&amp;gt; 0xebef), ack 2, win 512, options [nop,nop,TS val 94444283 ecr 94444283], length 0
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/04/17/netIssue/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/04/17/netIssue/</guid>
        
        <category>linux</category>
        
        
      </item>
    
      <item>
        <title>使用trash-cli代替rm</title>
        <description>&lt;p&gt;使用rm删除文件的时候有时候会误删，且无法恢复，尝试给使用mv替代rm，但有时候还是会有一些问题。ubuntu上有直接可用的安全删除文件的工具trash-cli&lt;/p&gt;

&lt;h1 id=&quot;install&quot;&gt;install&lt;/h1&gt;
&lt;p&gt;sudo apt install trash-cli&lt;/p&gt;

&lt;h1 id=&quot;常用命令&quot;&gt;常用命令&lt;/h1&gt;
&lt;ul&gt;
  &lt;li&gt;删除文件
    &lt;ul&gt;
      &lt;li&gt;trash filename&lt;/li&gt;
      &lt;li&gt;trash foldername/&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;查看回收站
    &lt;ul&gt;
      &lt;li&gt;trash-list&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;恢复
    &lt;ul&gt;
      &lt;li&gt;trash-restore&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;情况回收站
    &lt;ul&gt;
      &lt;li&gt;trash-empty&lt;/li&gt;
      &lt;li&gt;trash-empty 7 清除超过7天前的文件&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
  &lt;p&gt;也可以使用这个代替rm，给rm起个别名&lt;/p&gt;
  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;echo &quot;alias rm=&apos;trash&apos;&quot; &amp;gt;&amp;gt; ~/.bashrc
source ~/.bashrc
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/04/14/trash/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/04/14/trash/</guid>
        
        <category>tools</category>
        
        
      </item>
    
      <item>
        <title>png纹理转换为ktx</title>
        <description>&lt;h1 id=&quot;ktx-工具实战从安装到批量转换&quot;&gt;KTX 工具实战：从安装到批量转换&lt;/h1&gt;

&lt;p&gt;如果你在做图形渲染资源优化，&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx&lt;/code&gt; 是一个非常值得掌握的命令行工具。它可以把 PNG/JPG 等纹理转成 GPU 友好的 KTX/KTX2 格式，并支持压缩、mipmap、色彩空间标记等关键能力。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;1-ktx-是什么常见类型有哪些&quot;&gt;1. KTX 是什么？常见类型有哪些？&lt;/h2&gt;

&lt;h3 id=&quot;11-容器格式层面&quot;&gt;1.1 容器格式层面&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;类型&lt;/th&gt;
      &lt;th&gt;后缀&lt;/th&gt;
      &lt;th&gt;说明&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;KTX1&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ktx&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;早期格式，兼容性历史包袱较多&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;KTX2&lt;/td&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.ktx2&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;新一代格式，推荐优先使用&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;通常新项目建议直接用 &lt;strong&gt;KTX2&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;12-压缩编码层面ktx2-常见&quot;&gt;1.2 压缩编码层面（KTX2 常见）&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;编码&lt;/th&gt;
      &lt;th&gt;特点&lt;/th&gt;
      &lt;th&gt;适合场景&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;UASTC&lt;/td&gt;
      &lt;td&gt;画质高、细节好，体积通常更大&lt;/td&gt;
      &lt;td&gt;法线贴图、近景高质量材质&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;ETC1S&lt;/td&gt;
      &lt;td&gt;压缩率高、体积小，质量相对保守&lt;/td&gt;
      &lt;td&gt;包体敏感、移动端大规模分发&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;简单理解：&lt;strong&gt;要质量选 UASTC，要体积选 ETC1S&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;2-如何安装-ktx-工具&quot;&gt;2. 如何安装 KTX 工具&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx&lt;/code&gt; 来自 Khronos 的 KTX-Software。&lt;/p&gt;

&lt;h3 id=&quot;ubuntu--debian&quot;&gt;Ubuntu / Debian&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt update
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;apt &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; ktx-tools
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;macoshomebrew&quot;&gt;macOS（Homebrew）&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;brew &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;ktx
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;windows&quot;&gt;Windows&lt;/h3&gt;

&lt;p&gt;从 KTX-Software 的 GitHub Releases 下载预编译包，解压后把可执行文件目录加入 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PATH&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&quot;验证安装&quot;&gt;验证安装&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;ktx &lt;span class=&quot;nt&quot;&gt;--help&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;看到帮助输出即安装成功。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;3-ktx-最常用命令&quot;&gt;3. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx&lt;/code&gt; 最常用命令&lt;/h2&gt;

&lt;p&gt;不同版本子命令可能略有差异，但核心思路一致：&lt;strong&gt;创建（create）→ 检查（info）→ 转码/优化（视版本支持）&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;31-单张图片转-ktx2uastc&quot;&gt;3.1 单张图片转 KTX2（UASTC）&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;ktx create &lt;span class=&quot;nt&quot;&gt;--encode&lt;/span&gt; uastc &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; R8G8B8A8_SRGB &lt;span class=&quot;nt&quot;&gt;--generate-mipmap&lt;/span&gt; input.png output.ktx2
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;参数要点：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--encode uastc&lt;/code&gt;：使用 UASTC 编码&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--format ...&lt;/code&gt;：显式指定像素格式（非常重要）&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--generate-mipmap&lt;/code&gt;：自动生成 mip 链&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;32-单张图片转-ktx2etc1s&quot;&gt;3.2 单张图片转 KTX2（ETC1S）&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;ktx create &lt;span class=&quot;nt&quot;&gt;--encode&lt;/span&gt; etc1s &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; R8G8B8A8_SRGB &lt;span class=&quot;nt&quot;&gt;--generate-mipmap&lt;/span&gt; input.png output.ktx2
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;33-查看文件信息&quot;&gt;3.3 查看文件信息&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;ktx info output.ktx2
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;可用于确认编码类型、mipmap 层级、颜色空间标记等。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;4-批量转换纯命令行方案&quot;&gt;4. 批量转换：纯命令行方案&lt;/h2&gt;

&lt;h3 id=&quot;linux--macosbash&quot;&gt;Linux / macOS（Bash）&lt;/h3&gt;

&lt;h4 id=&quot;41-批量转-uastc颜色纹理srgb&quot;&gt;4.1 批量转 UASTC（颜色纹理，sRGB）&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; out_ktx2
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;f &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;textures/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.png&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; .png&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  ktx create &lt;span class=&quot;nt&quot;&gt;--encode&lt;/span&gt; uastc &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; R8G8B8A8_SRGB &lt;span class=&quot;nt&quot;&gt;--generate-mipmap&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;out_ktx2/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ktx2&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;42-批量转-etc1s颜色纹理srgb&quot;&gt;4.2 批量转 ETC1S（颜色纹理，sRGB）&lt;/h4&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; out_ktx2
&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;f &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;textures/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.png&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; .png&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  ktx create &lt;span class=&quot;nt&quot;&gt;--encode&lt;/span&gt; etc1s &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; R8G8B8A8_SRGB &lt;span class=&quot;nt&quot;&gt;--generate-mipmap&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;out_ktx2/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ktx2&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;5-颜色空间与贴图类型最容易出错的地方&quot;&gt;5. 颜色空间与贴图类型：最容易出错的地方&lt;/h2&gt;

&lt;h3 id=&quot;51-颜色纹理basecolor--emissive&quot;&gt;5.1 颜色纹理（BaseColor / Emissive）&lt;/h3&gt;

&lt;p&gt;一般用 sRGB 格式，例如：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R8G8B8_SRGB&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R8G8B8A8_SRGB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;52-数据纹理normal--roughness--metallic--ao&quot;&gt;5.2 数据纹理（Normal / Roughness / Metallic / AO）&lt;/h3&gt;

&lt;p&gt;一般用线性 UNORM：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R8G8B8_UNORM&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;R8G8B8A8_UNORM&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;不要把法线、粗糙度等数据图当 sRGB。&lt;/strong&gt;&lt;br /&gt;
否则常见症状是：高光异常、法线方向怪异、材质能量失真。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;6-常见问题与对应处理方式&quot;&gt;6. 常见问题与对应处理方式&lt;/h2&gt;

&lt;h3 id=&quot;问题-1ktx-command-not-found&quot;&gt;问题 1：&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx: command not found&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：未安装或 PATH 未配置。&lt;br /&gt;
&lt;strong&gt;处理&lt;/strong&gt;：重新安装，并确认 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx --help&lt;/code&gt; 能输出。&lt;/p&gt;

&lt;h3 id=&quot;问题-2转换成功但画面发灰过亮&quot;&gt;问题 2：转换成功但画面发灰/过亮&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：色彩空间选错（把颜色图当线性，或反过来）。&lt;br /&gt;
&lt;strong&gt;处理&lt;/strong&gt;：颜色图用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_SRGB&lt;/code&gt;，数据图用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;*_UNORM&lt;/code&gt;。&lt;/p&gt;

&lt;h3 id=&quot;问题-3体积太大&quot;&gt;问题 3：体积太大&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：使用了 UASTC 或纹理分辨率过高。&lt;br /&gt;
&lt;strong&gt;处理&lt;/strong&gt;：改用 ETC1S；必要时先降采样再编码。&lt;/p&gt;

&lt;h3 id=&quot;问题-4细节损失明显&quot;&gt;问题 4：细节损失明显&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：ETC1S 对高频细节保真较弱。&lt;br /&gt;
&lt;strong&gt;处理&lt;/strong&gt;：改用 UASTC，或对关键纹理单独走高质量策略。&lt;/p&gt;

&lt;h3 id=&quot;问题-5运行时加载失败&quot;&gt;问题 5：运行时加载失败&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;原因&lt;/strong&gt;：引擎/驱动对目标格式支持不一致，或元数据不匹配。&lt;br /&gt;
&lt;strong&gt;处理&lt;/strong&gt;：先 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx info&lt;/code&gt; 检查文件，再验证运行时支持矩阵（API/平台/GPU）。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;7-一套可落地的选择建议&quot;&gt;7. 一套可落地的选择建议&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;默认输出 &lt;strong&gt;KTX2&lt;/strong&gt;。&lt;/li&gt;
  &lt;li&gt;颜色图和数据图分开处理，明确 sRGB/UNORM。&lt;/li&gt;
  &lt;li&gt;大多数贴图用 ETC1S 控体积，关键质量贴图用 UASTC。&lt;/li&gt;
  &lt;li&gt;始终生成 mipmap，减少闪烁与采样噪点。&lt;/li&gt;
  &lt;li&gt;每批次抽样用 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ktx info&lt;/code&gt; + 引擎实机检查。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;按这套流程，你就能把 KTX 工具稳定纳入资源管线：&lt;strong&gt;体积、质量、加载效率三者可控&lt;/strong&gt;。&lt;/p&gt;

&lt;h1 id=&quot;参考脚本&quot;&gt;参考脚本&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_to_ktx2.sh&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Convert PNG textures to KTX2 (UASTC supercompression) for GPU-native loading.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Output goes to textures_ktx/ alongside the original textures/ folder.&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Usage: ./scripts/convert_to_ktx2.sh [texture_dir]&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;#   texture_dir defaults to res/model/halo/textures&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-euo&lt;/span&gt; pipefail

&lt;span class=&quot;nv&quot;&gt;SRC_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:-&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/model/halo/textures&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;DST_DIR&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SRC_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/textures_ktx&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; ktx &amp;amp;&amp;gt;/dev/null&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ERROR: &apos;ktx&apos; tool not found. Install KTX-Software.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi

if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; identify &amp;amp;&amp;gt;/dev/null&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ERROR: &apos;identify&apos; (ImageMagick) not found.&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
    &lt;span class=&quot;nb&quot;&gt;exit &lt;/span&gt;1
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DST_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Textures that represent color data and must be tagged sRGB:&lt;/span&gt;
is_srgb&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;local &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$1&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;BaseColor&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;Colour&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;Specular&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;Emissive&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;shopt&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; nullglob
&lt;span class=&quot;nv&quot;&gt;ok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;fail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;0

&lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;src &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SRC_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.png &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$SRC_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.PNG&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; .png&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;basename&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; .PNG&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DST_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.ktx2&quot;&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Detect alpha channel via ImageMagick identify&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;identify &lt;span class=&quot;nt&quot;&gt;-format&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%[channels]&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class=&quot;nb&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nv&quot;&gt;has_alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$channels&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;has_alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;

    &lt;span class=&quot;c&quot;&gt;# Select VkFormat based on color space and alpha&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;is_srgb &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$has_alpha&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;R8G8B8A8_SRGB&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;R8G8B8_SRGB&quot;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;tf_flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$has_alpha&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;R8G8B8A8_UNORM&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;R8G8B8_UNORM&quot;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;tf_flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;--assign-tf linear&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;fi

    &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;[ktx2] &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$name&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;  fmt=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fmt&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;ktx create &lt;span class=&quot;nt&quot;&gt;--encode&lt;/span&gt; uastc &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fmt&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$tf_flag&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;--generate-mipmap&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$out&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; ok++ &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else
        &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;  FAILED: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$src&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2
        &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt; fail++ &lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true
    &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fi
done

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Done. Converted: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ok&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;  Failed: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$fail&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Output: &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$DST_DIR&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        <pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://shensunbo.github.io/2026/04/11/ktx/</link>
        <guid isPermaLink="true">https://shensunbo.github.io/2026/04/11/ktx/</guid>
        
        <category>graphics</category>
        
        
      </item>
    
  </channel>
</rss>
