平时遇到的各种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. fastkmlxml.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.sitewww.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(&quot;copy-link&quot;, &quot;复制成功&quot;)">
      <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了.
  • 解决办法
    1. 找到另一个shell路径:.\\git_sdk_64\\usr\\bin\\bash.exe
    2. 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",
    3. 重启vscode, 即可在vscode内的集成终端里使用bash了.

      参考

git-UsrBin-bash无法正确读取环境变量的问题

  • 系统环境: Win11系统中安装了git-SDK环境.

  • 问题描述:在vscode内的集成终端里打开bash.exe, 出现无法找到cygpath命令, 导致win11的环境变量PATH转译失败的情况:

    git-bash-env-var-error

    这就导致我好多依靠PATH才能找到的命令无法使用, 如"D:\my_apps\for_produce\Nodejs\npm".
    但是我在win11系统的终端工具中打开同样的这个bash.exe时, 却又一切正常.

  • 原因:未知.

  • 解决办法:在需要用到那些因为找不到路径而报错的命令时, 就别在vscode的集成终端里吧.

其他配置问题

写博客时遇到的

非常奇怪的bug: `jQuery`字符串(区分大小写)不能单独作为二级目录,否则整篇文章图片无法被懒加载

计算机使用中的一些小毛病

外接设备的问题

键盘

  • Win键被锁了
    猫从键盘上踩过, Win就失灵了. 我的是okko键盘, Fn + 左Win就是上锁, Fn + 右Win就是解锁.

Static Badge Static Badge Static Badge Static Badge
Copyright © 2023-2024 Raymond H., All Rights Reserved.