平时遇到的各种bug及解决办法收录。【环境、命令、报错现象、原因、解决】
python相关
调试场景
- [UI] 带参数的调试:直接在
launch.json
中加入键值对:"args": [ "--arg1", "val1", "--arg2", "val2", ]
第三方库的使用bug
gdal
osgeo.ogr组件读写kml文件的困惑
环境: wsl2-Ubuntu20.04, python3.9.17(miniconda), gdal=3.6.2
问题:
- 当我用如下代码生成
test.kml
时, 很顺利.# 逻辑: 制作一个图层(layer)👉 图层上制作一个要素(feature)👉 要素里有`一个四边形(polygon)`,`两个自定义属性字段(field)`
from osgeo import ogr
driver= ogr.GetDriverByName("KML")
ds= driver.CreateDataSource("test.kml")
layer = ds.CreateLayer("test_")
layer.CreateField(ogr.FieldDefn("label", ogr.OFTInteger))
layer.CreateField(ogr.FieldDefn("width", ogr.OFTReal))
ring= ogr.Geometry(ogr.wkbLinearRing)
points = [(0, 0),(10, 0),(10, 10),(0, 10),(0, 0)]
for x, y in points:
ring.AddPoint(x, y)
poly= ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)
feature= ogr.Feature(layer.GetLayerDefn())
feature.SetGeometry(poly)
feature.SetField("label", 1)
feature.SetField("width", 10)
layer.CreateFeature(feature)
ds=None - 当我再用
ogr
读取这个生成的文件时, 代码和报错如下:path_kml = "test.kml"
driver = ogr.GetDriverByName("KML")
dataSource = driver.Open(path_kml, 0)
if dataSource is None:
print("Could not open file")
exit(1)
layer = dataSource.GetLayer()
for feature in layer:
print("Feature:")
for i in range(feature.GetFieldCount()):
field_name = feature.GetFieldDefnRef(i).GetName()
field_value = feature.GetField(i)
print(f" {field_name}: {field_value}")
# 输出:
#Feature:
# Name:
# Description:
# 再次执行:
layer[0].GetField(2)
# 报错: Invalid index : 2 (表明除了Name和Description, 没有更多字段) - 百思不解, gdal作为一个强大的工具, 为什么自己写的文件, 自己读不了?
- 当我用如下代码生成
原因:
官网对kml-driver的介绍指明了一些方向, 概括来说就是该工具就是在对kml
的兼容上阉割了不少功能.正当我准备放弃, 改用其他库(e.g.
fastkml
、xml.etree
)时, 突然在刚才那个页面找到个用来How to dump contents of .kml file as OGR sees it
的命令:ogrinfo -al test.kml
执行后输出:INFO: Open of `test.kml'
using driver `LIBKML' successful.
1: test_好像是在告诉我, 得更换
driver
呀.解决:
将上述读取文件的代码的第二行, 即driver = ogr.GetDriverByName("KML")
中的"KML"
改为"LIBKML"
, 就能顺利读取所有自定义字段啦.
osgeo.ogr的几何对象需要clone的问题
环境: wsl2-Ubuntu20.04, python3.9.17(miniconda), gdal=3.6.2
问题:
geoms = []
driver = ogr.GetDriverByName('LIBKML')
datasource = driver.Open(kml_path, 0)
for layer in datasource:
if need_spatial_ref:
spatial_ref= layer.GetSpatialRef()
for feature in layer:
geometry= feature.geometry()
if geometry.GetPointCount() == 0:
for sub_geometry in geometry:
geoms.append(sub_geometry)
else:
geoms.append(geometry)
# 后续对geoms操作:
for geom in geoms:
print(geom.GetPoint(0))- 背景知识:
ogr
会将矢量文件(e.g.kml
)中的层次关系转义为,ogr.DataSource
(整个文件) 👉ogr.Layer
(图层) 👉ogr.Feature
(要素) 👉ogr.Geometry
(几何对象, 该对象可能还有嵌套的子对象
) +ogr.FieldDefn
(字段定义)
你可以直接用类似for feat in layer
的语法直接遍历下层对象. - 上述代码的逻辑: 用
ogr
遍历出所有的底层几何对象
存到一个list
中, 再进行其他后续操作. - 遇到的BUG:
在执行最后一句的时候, 程序直接crash.
事实上,geoms
除了最后一个元素, 任何其他元素的访问都将crash.
而在生成list过程中的那些for循环里, 是能够正常访问sub_geometry
等的.
- 背景知识:
原因: 访问到了无效内存地址
这是一个
循环和引用
的问题, 比如在for sub_geometry in geometry
循环中,sub_geometry 是一个引用,而不是独立的对象副本。每次循环时,它指向几何对象中的不同子几何体.那我们添加到geoms列表的, 实际上只是一个引用. 当引用在下个循环里更新, 直接造成之前存储的引用
无效
,导致访问时崩溃。解决: 很简单, 用
对象克隆
, 把append语句改为geoms.append(sub_geometry.Clone())
即可.
docker相关
命令相关
`docker login`命令的报错
- 环境:wsl2, docker
- 重现:执行
docker login
- 报错:
Error saving credentials: error storing credentials
err: exec: "docker-credential-desktop.exe": executable file not found in $PATH, out: '' - 原因:旧的Docker 凭据产生了冲突,清除掉,重新登录即可。
- 解决:
rm ~/.docker/config.json
docker logout
docker login
连接docker守护进程被拒
- 环境:wsl2, docker
- 重现:执行
docker run ...
- 报错:
docker: permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create": dial unix /var/run/docker.sock: connect: permission denied.
- 原因:你的用户(james)没有足够的权限连接到 Docker 守护进程。通常情况下,这是因为用户没有加入 docker 组
- 解决:
sudo usermod -aG docker $USER # 入组
newgrp docker # 重载
Linux相关
IO相关
- echo命令不宜用来写入文件: 当内容过长或其他未知原因,
echo $str > file
会报错编码问题
.
解决方法: 用echo $str | tee file
.
ssh相关
- 当连接远程失败、连接重置:
- 先考虑服务端的
ssh服务
是否开启:sudo service ssh status/start
- 先考虑服务端的
- 当无法锁定问题,用
-v
参数查看详细信息。
Windows编程相关
batch脚本语言(CMD)
激活conda环境的命令
- 报错场景:在CMD中,
activate base
命令可正常开启base虚拟环境,但放入.bat
文件中执行会导致闪退。 - 解决办法:语句改为
call activate base
。 - 注意事项:
conda activate base
在CMD中是没有效果的。
网络连接相关
url访问报错
一个url本身可被访问,但置于另一网页则无法被加载的问题
- 场景:我的七牛云图床中一张图片的url可以打开查看,但将该url放到我博客文章里时,博客网页无法加载对应图片,浏览器控制台报错
forbidden 403
- 原因:七牛云图床有
防盗链
设置,且博客域名没有加入白名单。 - 解决办法:将你想要的域名放入白名单即可。注意,经测试
*.taddream.site
无效,应用taddream.site
和www.taddream.site
;另外最好加上127.0.0.1
,用以本地调试。
前端相关
隐藏的内容无法复制到剪切板
问题描述:有一个元素, 内含
id
属性、value
属性、style="display: none;"
属性. 我无法用document.execCommand("Copy")
方法来实现复制value
到剪贴板的操作.场景:在博客主题stellar的源码中,作者在
stellar\layout\_partial\main\article\article_footer.ejs
的’分享文章’模块有一个class="social share-item link"
的图标按钮,点击该按钮后,会将文章永久链接复制到剪贴板。具体实现方式为:- 先在
分享文章
模块中把文章的永久链接显示出来:article_footer.ejs <div class="link">
<input class="copy-area" readonly="" id="copy-link" value="${page.permalink}">
</div> - 然后对
social share-item link
按钮实现复制到剪贴板的功能:其中,article_footer.ejs <a class="social share-item link" onclick="util.copy("copy-link", "复制成功")">
<img 。。。>
</a>util.copy
函数的作用是, 通过id="copy-link"
找到存放永久链接的元素,将其value
属性的值复制到剪贴板,源码如下:但是,stellar/source/js/main.js copy: (id, msg) => {
const el = document.getElementById(id);
if (el) {
el.select();
document.execCommand("Copy");
if (msg && msg.length > 0) {
hud.toast(msg, 2500);
}
}
},
当我自定义这个模块, 在class="link"
那个元素中增加style="display: none;"
属性,即隐藏了链接后,发现点击class="social share-item link"
按钮就不能把文章链接复制到剪贴板了。
- 先在
原因:隐藏的元素无法通过
document.execCommand("Copy")
实现复制操作。chatGPT的解释: 是由于浏览器安全策略的限制。可以考虑使用更先进的 Clipboard API 或其他现代的方法。
解决办法:将
copy
函数中的el.select(); document.execCommand("Copy");
替换为navigator.clipboard.writeText(el.value)
即可。
VSCode
以下是vscode-windows-desktop使用中遇到的bug及解决办法.
配置问题
Git-bash终端的集成问题
- 系统环境: Win11系统中安装了
git-SDK
环境. (我装的不是更简单的git
环境, 因为我想要一个更完整的仿Linux环境) - 问题描述:,且环境变量能找到
git-bash.exe
的路径。我想在vscode内的集成终端里打开git-bash.exe
, 但是实际是总会打开git-bash的独立窗口。 - 原因:
git-SDK
安装目录里有很多shell相关的可执行文件, 而似乎./git-bash.exe
只能通过独立窗口打开, 只能配置其他shell了. - 解决办法:
- 找到另一个shell路径:
.\\git_sdk_64\\usr\\bin\\bash.exe
- 在
settings.json
中配置:"terminal.integrated.profiles.windows": {
"PowerShell": {},
"Command Prompt": {},
"git-UsrBin-bash.exe": {
"path": ["D:\\my_apps\\for_produce\\git-sdk-64\\usr\\bin\\bash.exe"],
"args": [],
"icon": "terminal-bash",
//"source": "Git Bash" // 如果git的安装是默认路径,则可使用source,否则使用"path"
}
},
"terminal.integrated.defaultProfile.windows": "git-UsrBin-bash.exe", - 重启vscode, 即可在vscode内的集成终端里使用bash了.
- 找到另一个shell路径:
git-UsrBin-bash无法正确读取环境变量的问题
系统环境: Win11系统中安装了
git-SDK
环境.问题描述:在vscode内的集成终端里打开
bash.exe
, 出现无法找到cygpath
命令, 导致win11的环境变量PATH
转译失败的情况:这就导致我好多依靠
PATH
才能找到的命令无法使用, 如"D:\my_apps\for_produce\Nodejs\npm"
.
但是我在win11系统的终端工具中打开同样的这个bash.exe
时, 却又一切正常.原因:未知.
解决办法:在需要用到那些因为
找不到路径而报错
的命令时, 就别在vscode的集成终端里吧.
其他配置问题
写博客时遇到的
非常奇怪的bug: `jQuery`字符串(区分大小写)不能单独作为二级目录,否则整篇文章图片无法被懒加载
- 场景:该页面
- 原因:未知。
计算机使用中的一些小毛病
外接设备的问题
键盘
Win
键被锁了
猫从键盘上踩过,Win
就失灵了. 我的是okko
键盘,Fn + 左Win
就是上锁,Fn + 右Win
就是解锁.