当前位置: 首页 > news >正文

Vins_Fusion_gpu中source setup.bash

文章目录

  • source setup.bash
    • setup.bash
    • setup.sh
      • 脚本的主要功能
      • 脚本的详细解释
        • 1. **初始化和检查**
        • 2. **检测操作系统**
        • 3. **设置环境变量**
        • 4. **记住 shell 类型**
        • 5. **调用 Python 脚本生成环境变量**
        • 6. **加载环境钩子**
        • 7. **清理**
      • 总结
    • _setup_util.py
      • `_setup_util.py` 的完整功能解析
      • 文件结构与功能
        • 1. **全局变量和常量**
        • 2. **环境变量子目录映射**
        • 3. **命令行参数解析**
        • 4. **主程序逻辑**
      • **主程序的主要步骤**
      • 关键函数解析
        • 1. **`rollback_env_variables`**
        • 2. **`_rollback_env_variable`**
        • 3. **`_get_workspaces`**
        • 4. **`prepend_env_variables`**
        • 5. **`_prefix_env_variable`**
        • 6. **`find_env_hooks`**
      • 总结

source setup.bash

每次运行都需要source setup.bash,不太懂这个文件干什么的,就学习了一下。

setup.bash

#!/usr/bin/env bash
# generated from catkin/cmake/templates/setup.bash.inCATKIN_SHELL=bash# source setup.sh from same directory as this file
_CATKIN_SETUP_DIR=$(builtin cd "`dirname "${BASH_SOURCE[0]}"`" > /dev/null && pwd)
. "$_CATKIN_SETUP_DIR/setup.sh"

该文件就是调用setup.sh

setup.sh

#!/usr/bin/env sh
# generated from catkin/cmake/template/setup.sh.in# Sets various environment variables and sources additional environment hooks.
# It tries it's best to undo changes from a previously sourced setup file before.
# Supported command line options:
# --extend: skips the undoing of changes from a previously sourced setup file
# --local: only considers this workspace but not the chained ones
# In plain sh shell which doesn't support arguments for sourced scripts you can
# set the environment variable `CATKIN_SETUP_UTIL_ARGS=--extend/--local` instead.# since this file is sourced either use the provided _CATKIN_SETUP_DIR
# or fall back to the destination set at configure time
: ${_CATKIN_SETUP_DIR:=/home/ssmec/catkin_ws/devel}
_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py"
unset _CATKIN_SETUP_DIRif [ ! -f "$_SETUP_UTIL" ]; thenecho "Missing Python script: $_SETUP_UTIL"return 22
fi# detect if running on Darwin platform
_UNAME=`uname -s`
_IS_DARWIN=0
if [ "$_UNAME" = "Darwin" ]; then_IS_DARWIN=1
fi
unset _UNAME# make sure to export all environment variables
export CMAKE_PREFIX_PATH
if [ $_IS_DARWIN -eq 0 ]; thenexport LD_LIBRARY_PATH
elseexport DYLD_LIBRARY_PATH
fi
unset _IS_DARWIN
export PATH
export PKG_CONFIG_PATH
export PYTHONPATH# remember type of shell if not already set
if [ -z "$CATKIN_SHELL" ]; thenCATKIN_SHELL=sh
fi# invoke Python script to generate necessary exports of environment variables
# use TMPDIR if it exists, otherwise fall back to /tmp
if [ -d "${TMPDIR:-}" ]; then_TMPDIR="${TMPDIR}"
else_TMPDIR=/tmp
fi
_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"`
unset _TMPDIR
if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; thenecho "Could not create temporary file: $_SETUP_TMP"return 1
fi
CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP"
_RC=$?
if [ $_RC -ne 0 ]; thenif [ $_RC -eq 2 ]; thenecho "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?"elseecho "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC"fiunset _RCunset _SETUP_UTILrm -f "$_SETUP_TMP"unset _SETUP_TMPreturn 1
fi
unset _RC
unset _SETUP_UTIL
. "$_SETUP_TMP"
rm -f "$_SETUP_TMP"
unset _SETUP_TMP# source all environment hooks
_i=0
while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; doeval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_iunset _CATKIN_ENVIRONMENT_HOOKS_$_ieval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACEunset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE# set workspace for environment hookCATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace. "$_envfile"unset CATKIN_ENV_HOOK_WORKSPACE_i=$((_i + 1))
done
unset _iunset _CATKIN_ENVIRONMENT_HOOKS_COUNT

这个脚本是 ROS(Robot Operating System)中 catkin 工作空间的 setup.sh 文件,它的主要作用是设置和更新环境变量,使得用户可以在当前终端会话中使用该工作空间中的工具、库和包。它还会处理一些复杂的环境配置,例如确保多个工作空间之间的依赖关系正确,以及撤销之前可能已经设置的其他工作空间的环境变量。

脚本的主要功能

  1. 设置环境变量:脚本会设置一系列环境变量,如 CMAKE_PREFIX_PATHLD_LIBRARY_PATH(Linux)、DYLD_LIBRARY_PATH(macOS)、PATHPKG_CONFIG_PATHPYTHONPATH。这些环境变量对于找到编译工具、库文件、可执行文件和其他资源非常重要。

  2. 处理多工作空间链:ROS 支持多个 catkin 工作空间的叠加使用。每个工作空间可以依赖于其他工作空间中的包。setup.sh 会根据命令行参数(如 --extend--local)来决定是否覆盖或扩展已有的环境变量。--extend 参数允许当前工作空间的环境变量与之前工作空间的环境变量共存,而 --local 参数则只考虑当前工作空间,忽略链中的其他工作空间。

  3. 调用 Python 脚本生成环境变量:脚本会调用一个 Python 脚本 _setup_util.py 来生成必要的环境变量导出命令。这个 Python 脚本会根据当前工作空间的状态动态生成正确的环境变量设置,并将结果写入一个临时文件。然后,setup.sh 会读取并执行这个临时文件中的命令。

  4. 加载环境钩子catkin 允许包提供“环境钩子”(environment hooks),即一些额外的脚本,用于在 setup.sh 执行时进一步修改环境。这些钩子可以用来设置特定包所需的环境变量或其他配置。setup.sh 会遍历所有找到的环境钩子,并依次执行它们。

  5. 处理平台差异:脚本会检测当前操作系统(如 Linux 或 macOS),并根据平台的不同设置相应的环境变量。例如,在 Linux 上设置 LD_LIBRARY_PATH,而在 macOS 上设置 DYLD_LIBRARY_PATH

脚本的详细解释

1. 初始化和检查
: ${_CATKIN_SETUP_DIR:=/home/ssmec/catkin_ws/devel}
_SETUP_UTIL="$_CATKIN_SETUP_DIR/_setup_util.py"
unset _CATKIN_SETUP_DIRif [ ! -f "$_SETUP_UTIL" ]; thenecho "Missing Python script: $_SETUP_UTIL"return 22
fi
  • 这段代码首先设置了 _CATKIN_SETUP_DIR 变量,指向当前 catkin 工作空间的 devel 目录。如果该变量已经存在,则保持不变;否则,使用默认路径 /home/ssmec/catkin_ws/devel
  • 然后,它定义了 _SETUP_UTIL 变量,指向 devel 目录下的 _setup_util.py Python 脚本。
  • 接下来,它检查 _setup_util.py 是否存在。如果不存在,脚本会输出错误信息并返回状态码 22,表示失败。
2. 检测操作系统
_UNAME=`uname -s`
_IS_DARWIN=0
if [ "$_UNAME" = "Darwin" ]; then_IS_DARWIN=1
fi
unset _UNAME
  • 这段代码使用 uname -s 命令检测当前操作系统。如果操作系统是 macOS(Darwin),则将 _IS_DARWIN 设置为 1,否则保持为 0
  • 之后,它清除了 _UNAME 变量,因为它不再需要。
3. 设置环境变量
export CMAKE_PREFIX_PATH
if [ $_IS_DARWIN -eq 0 ]; thenexport LD_LIBRARY_PATH
elseexport DYLD_LIBRARY_PATH
fi
unset _IS_DARWIN
export PATH
export PKG_CONFIG_PATH
export PYTHONPATH
  • 这段代码导出了几个关键的环境变量:
    • CMAKE_PREFIX_PATH:用于指定 CMake 应查找的安装前缀。
    • LD_LIBRARY_PATH(Linux)或 DYLD_LIBRARY_PATH(macOS):用于指定动态链接器应查找的库路径。
    • PATH:用于指定可执行文件的搜索路径。
    • PKG_CONFIG_PATH:用于指定 pkg-config 应查找的 .pc 文件路径。
    • PYTHONPATH:用于指定 Python 解释器应查找的模块路径。
4. 记住 shell 类型
if [ -z "$CATKIN_SHELL" ]; thenCATKIN_SHELL=sh
fi
  • 如果 CATKIN_SHELL 环境变量未设置,则将其设置为 sh。这个变量用于告诉 _setup_util.py 当前使用的 shell 类型,以便生成正确的 shell 语法。
5. 调用 Python 脚本生成环境变量
if [ -d "${TMPDIR:-}" ]; then_TMPDIR="${TMPDIR}"
else_TMPDIR=/tmp
fi
_SETUP_TMP=`mktemp "${_TMPDIR}/setup.sh.XXXXXXXXXX"`
unset _TMPDIR
if [ $? -ne 0 -o ! -f "$_SETUP_TMP" ]; thenecho "Could not create temporary file: $_SETUP_TMP"return 1
fi
CATKIN_SHELL=$CATKIN_SHELL "$_SETUP_UTIL" $@ ${CATKIN_SETUP_UTIL_ARGS:-} >> "$_SETUP_TMP"
_RC=$?
if [ $_RC -ne 0 ]; thenif [ $_RC -eq 2 ]; thenecho "Could not write the output of '$_SETUP_UTIL' to temporary file '$_SETUP_TMP': may be the disk if full?"elseecho "Failed to run '\"$_SETUP_UTIL\" $@': return code $_RC"fiunset _RCunset _SETUP_UTILrm -f "$_SETUP_TMP"unset _SETUP_TMPreturn 1
fi
unset _RC
unset _SETUP_UTIL
. "$_SETUP_TMP"
rm -f "$_SETUP_TMP"
unset _SETUP_TMP
  • 这段代码创建了一个临时文件 _SETUP_TMP,用于存储 _setup_util.py 生成的环境变量导出命令。
  • 它调用 _setup_util.py,并将生成的命令追加到临时文件中。$@ 表示传递给 setup.sh 的所有命令行参数,CATKIN_SETUP_UTIL_ARGS 是一个环境变量,允许用户通过设置它来传递额外的参数(如 --extend--local)。
  • 如果 _setup_util.py 执行失败,脚本会输出错误信息并返回非零状态码。
  • 如果成功,脚本会读取并执行临时文件中的命令,从而应用生成的环境变量设置。
  • 最后,它删除临时文件并清理相关变量。
6. 加载环境钩子
_i=0
while [ $_i -lt $_CATKIN_ENVIRONMENT_HOOKS_COUNT ]; doeval _envfile=\$_CATKIN_ENVIRONMENT_HOOKS_$_iunset _CATKIN_ENVIRONMENT_HOOKS_$_ieval _envfile_workspace=\$_CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACEunset _CATKIN_ENVIRONMENT_HOOKS_${_i}_WORKSPACE# set workspace for environment hookCATKIN_ENV_HOOK_WORKSPACE=$_envfile_workspace. "$_envfile"unset CATKIN_ENV_HOOK_WORKSPACE_i=$((_i + 1))
done
unset _i
  • 这段代码遍历所有找到的环境钩子(通过 _CATKIN_ENVIRONMENT_HOOKS_COUNT 变量确定数量),并依次执行每个钩子。
  • 每个钩子是一个脚本文件,_envfile 包含钩子的路径,_envfile_workspace 包含钩子所属的工作空间路径。
  • 在执行每个钩子之前,脚本会设置 CATKIN_ENV_HOOK_WORKSPACE 变量,以便钩子知道它属于哪个工作空间。
  • 执行完钩子后,脚本会清除相关变量,继续处理下一个钩子。
7. 清理
unset _CATKIN_ENVIRONMENT_HOOKS_COUNT
  • 最后,脚本会清除 _CATKIN_ENVIRONMENT_HOOKS_COUNT 变量,以确保没有残留的环境变量。

总结

setup.sh 是一个非常重要的脚本,它负责为当前终端会话设置正确的环境变量,使得用户可以在该工作空间中使用 ROS 包和工具。它不仅设置了基本的环境变量,还处理了多工作空间的依赖关系,并加载了所有相关的环境钩子。通过这种方式,setup.sh 确保了 ROS 环境的正确配置,使得开发和运行 ROS 节点变得更加方便。

_setup_util.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-# Software License Agreement (BSD License)
#
# Copyright (c) 2012, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE."""This file generates shell code for the setup.SHELL scripts to set environment variables."""from __future__ import print_functionimport argparse
import copy
import errno
import os
import platform
import sysCATKIN_MARKER_FILE = '.catkin'system = platform.system()
IS_DARWIN = (system == 'Darwin')
IS_WINDOWS = (system == 'Windows')PATH_TO_ADD_SUFFIX = ['bin']
if IS_WINDOWS:# while catkin recommends putting dll's into bin, 3rd party packages often put dll's into lib# since Windows finds dll's via the PATH variable, prepend it with path to libPATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'aarch64-linux-gnu')]])# subfolder of workspace prepended to CMAKE_PREFIX_PATH
ENV_VAR_SUBFOLDERS = {'CMAKE_PREFIX_PATH': '','LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'aarch64-linux-gnu')],'PATH': PATH_TO_ADD_SUFFIX,'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'aarch64-linux-gnu', 'pkgconfig')],'PYTHONPATH': 'lib/python3/dist-packages',
}def rollback_env_variables(environ, env_var_subfolders):"""Generate shell code to reset environment variables.by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH.This does not cover modifications performed by environment hooks."""lines = []unmodified_environ = copy.copy(environ)for key in sorted(env_var_subfolders.keys()):subfolders = env_var_subfolders[key]if not isinstance(subfolders, list):subfolders = [subfolders]value = _rollback_env_variable(unmodified_environ, key, subfolders)if value is not None:environ[key] = valuelines.append(assignment(key, value))if lines:lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH'))return linesdef _rollback_env_variable(environ, name, subfolders):"""For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder.:param subfolders: list of str '' or subfoldername that may start with '/':returns: the updated value of the environment variable."""value = environ[name] if name in environ else ''env_paths = [path for path in value.split(os.pathsep) if path]value_modified = Falsefor subfolder in subfolders:if subfolder:if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)):subfolder = subfolder[1:]if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)):subfolder = subfolder[:-1]for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True):path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_pathpath_to_remove = Nonefor env_path in env_paths:env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_pathif env_path_clean == path_to_find:path_to_remove = env_pathbreakif path_to_remove:env_paths.remove(path_to_remove)value_modified = Truenew_value = os.pathsep.join(env_paths)return new_value if value_modified else Nonedef _get_workspaces(environ, include_fuerte=False, include_non_existing=False):"""Based on CMAKE_PREFIX_PATH return all catkin workspaces.:param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool``"""# get all cmake prefix pathsenv_name = 'CMAKE_PREFIX_PATH'value = environ[env_name] if env_name in environ else ''paths = [path for path in value.split(os.pathsep) if path]# remove non-workspace pathsworkspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))]return workspacesdef prepend_env_variables(environ, env_var_subfolders, workspaces):"""Generate shell code to prepend environment variables for the all workspaces."""lines = []lines.append(comment('prepend folders of workspaces to environment variables'))paths = [path for path in workspaces.split(os.pathsep) if path]prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '')lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix))for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'):subfolder = env_var_subfolders[key]prefix = _prefix_env_variable(environ, key, paths, subfolder)lines.append(prepend(environ, key, prefix))return linesdef _prefix_env_variable(environ, name, paths, subfolders):"""Return the prefix to prepend to the environment variable NAME.Adding any path in NEW_PATHS_STR without creating duplicate or empty items."""value = environ[name] if name in environ else ''environ_paths = [path for path in value.split(os.pathsep) if path]checked_paths = []for path in paths:if not isinstance(subfolders, list):subfolders = [subfolders]for subfolder in subfolders:path_tmp = pathif subfolder:path_tmp = os.path.join(path_tmp, subfolder)# skip nonexistent pathsif not os.path.exists(path_tmp):continue# exclude any path already in env and any path we already addedif path_tmp not in environ_paths and path_tmp not in checked_paths:checked_paths.append(path_tmp)prefix_str = os.pathsep.join(checked_paths)if prefix_str != '' and environ_paths:prefix_str += os.pathsepreturn prefix_strdef assignment(key, value):if not IS_WINDOWS:return 'export %s="%s"' % (key, value)else:return 'set %s=%s' % (key, value)def comment(msg):if not IS_WINDOWS:return '# %s' % msgelse:return 'REM %s' % msgdef prepend(environ, key, prefix):if key not in environ or not environ[key]:return assignment(key, prefix)if not IS_WINDOWS:return 'export %s="%s$%s"' % (key, prefix, key)else:return 'set %s=%s%%%s%%' % (key, prefix, key)def find_env_hooks(environ, cmake_prefix_path):"""Generate shell code with found environment hooks for the all workspaces."""lines = []lines.append(comment('found environment hooks in workspaces'))generic_env_hooks = []generic_env_hooks_workspace = []specific_env_hooks = []specific_env_hooks_workspace = []generic_env_hooks_by_filename = {}specific_env_hooks_by_filename = {}generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh'specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else None# remove non-workspace pathsworkspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))]for workspace in reversed(workspaces):env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d')if os.path.isdir(env_hook_dir):for filename in sorted(os.listdir(env_hook_dir)):if filename.endswith('.%s' % generic_env_hook_ext):# remove previous env hook with same name if presentif filename in generic_env_hooks_by_filename:i = generic_env_hooks.index(generic_env_hooks_by_filename[filename])generic_env_hooks.pop(i)generic_env_hooks_workspace.pop(i)# append env hookgeneric_env_hooks.append(os.path.join(env_hook_dir, filename))generic_env_hooks_workspace.append(workspace)generic_env_hooks_by_filename[filename] = generic_env_hooks[-1]elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext):# remove previous env hook with same name if presentif filename in specific_env_hooks_by_filename:i = specific_env_hooks.index(specific_env_hooks_by_filename[filename])specific_env_hooks.pop(i)specific_env_hooks_workspace.pop(i)# append env hookspecific_env_hooks.append(os.path.join(env_hook_dir, filename))specific_env_hooks_workspace.append(workspace)specific_env_hooks_by_filename[filename] = specific_env_hooks[-1]env_hooks = generic_env_hooks + specific_env_hooksenv_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspacecount = len(env_hooks)lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count))for i in range(count):lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i]))lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i]))return linesdef _parse_arguments(args=None):parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.')parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context')parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment')return parser.parse_known_args(args=args)[0]if __name__ == '__main__':try:try:args = _parse_arguments()except Exception as e:print(e, file=sys.stderr)sys.exit(1)if not args.local:# environment at generation timeCMAKE_PREFIX_PATH = r'/home/ssmec/catkin_ws/install;/home/ssmec/catkin_ws/devel;/opt/ros/noetic'.split(';')else:# don't consider any other prefix path than this oneCMAKE_PREFIX_PATH = []# prepend current workspace if not already part of CPPbase_path = os.path.dirname(__file__)# CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent# base_path on Windows contains backward slashes, need to be converted to forward slashes before comparisonif os.path.sep != '/':base_path = base_path.replace(os.path.sep, '/')if base_path not in CMAKE_PREFIX_PATH:CMAKE_PREFIX_PATH.insert(0, base_path)CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH)environ = dict(os.environ)lines = []if not args.extend:lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS)lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH)lines += find_env_hooks(environ, CMAKE_PREFIX_PATH)print('\n'.join(lines))# need to explicitly flush the outputsys.stdout.flush()except IOError as e:# and catch potential "broken pipe" if stdout is not writable# which can happen when piping the output to a file but the disk is fullif e.errno == errno.EPIPE:print(e, file=sys.stderr)sys.exit(2)raisesys.exit(0)

_setup_util.py 的完整功能解析

_setup_util.py 是 ROS(Robot Operating System)中 catkin 工作空间的一部分,它的主要职责是生成用于设置环境变量的 shell 代码。这个 Python 脚本被 setup.sh 调用,以确保当前终端会话中的环境变量正确配置,使得用户可以在该工作空间中使用 ROS 包和工具。

文件结构与功能

1. 全局变量和常量
CATKIN_MARKER_FILE = '.catkin'
system = platform.system()
IS_DARWIN = (system == 'Darwin')
IS_WINDOWS = (system == 'Windows')
PATH_TO_ADD_SUFFIX = ['bin']
if IS_WINDOWS:PATH_TO_ADD_SUFFIX.extend([['lib', os.path.join('lib', 'aarch64-linux-gnu')]])
  • CATKIN_MARKER_FILE:定义了标记文件 .catkin,用于识别 catkin 工作空间。
  • system:获取当前操作系统名称。
  • IS_DARWINIS_WINDOWS:分别标识是否为 macOS 和 Windows 系统。
  • PATH_TO_ADD_SUFFIX:定义了要添加到 PATH 环境变量的子目录,默认是 bin。在 Windows 上,还会添加 liblib/aarch64-linux-gnu
2. 环境变量子目录映射
ENV_VAR_SUBFOLDERS = {'CMAKE_PREFIX_PATH': '','LD_LIBRARY_PATH' if not IS_DARWIN else 'DYLD_LIBRARY_PATH': ['lib', os.path.join('lib', 'aarch64-linux-gnu')],'PATH': PATH_TO_ADD_SUFFIX,'PKG_CONFIG_PATH': [os.path.join('lib', 'pkgconfig'), os.path.join('lib', 'aarch64-linux-gnu', 'pkgconfig')],'PYTHONPATH': 'lib/python3/dist-packages',
}
  • ENV_VAR_SUBFOLDERS:定义了每个环境变量对应的子目录。例如,CMAKE_PREFIX_PATH 没有子目录,而 LD_LIBRARY_PATH(或 macOS 上的 DYLD_LIBRARY_PATH)对应 liblib/aarch64-linux-gnu 子目录。PATH 对应 binPKG_CONFIG_PATH 对应 lib/pkgconfiglib/aarch64-linux-gnu/pkgconfigPYTHONPATH 对应 lib/python3/dist-packages
3. 命令行参数解析
def _parse_arguments(args=None):parser = argparse.ArgumentParser(description='Generates code blocks for the setup.SHELL script.')parser.add_argument('--extend', action='store_true', help='Skip unsetting previous environment variables to extend context')parser.add_argument('--local', action='store_true', help='Only consider this prefix path and ignore other prefix path in the environment')return parser.parse_known_args(args=args)[0]
  • _parse_arguments:解析命令行参数。支持两个选项:
    • --extend:跳过撤销之前设置的环境变量,直接扩展当前环境。
    • --local:只考虑当前工作空间,忽略链中的其他工作空间。
4. 主程序逻辑
if __name__ == '__main__':try:try:args = _parse_arguments()except Exception as e:print(e, file=sys.stderr)sys.exit(1)if not args.local:# environment at generation timeCMAKE_PREFIX_PATH = r'/home/ssmec/catkin_ws/install;/home/ssmec/catkin_ws/devel;/opt/ros/noetic'.split(';')else:# don't consider any other prefix path than this oneCMAKE_PREFIX_PATH = []# prepend current workspace if not already part of CPPbase_path = os.path.dirname(__file__)# CMAKE_PREFIX_PATH uses forward slash on all platforms, but __file__ is platform dependent# base_path on Windows contains backward slashes, need to be converted to forward slashes before comparisonif os.path.sep != '/':base_path = base_path.replace(os.path.sep, '/')if base_path not in CMAKE_PREFIX_PATH:CMAKE_PREFIX_PATH.insert(0, base_path)CMAKE_PREFIX_PATH = os.pathsep.join(CMAKE_PREFIX_PATH)environ = dict(os.environ)lines = []if not args.extend:lines += rollback_env_variables(environ, ENV_VAR_SUBFOLDERS)lines += prepend_env_variables(environ, ENV_VAR_SUBFOLDERS, CMAKE_PREFIX_PATH)lines += find_env_hooks(environ, CMAKE_PREFIX_PATH)print('\n'.join(lines))# need to explicitly flush the outputsys.stdout.flush()except IOError as e:# and catch potential "broken pipe" if stdout is not writable# which can happen when piping the output to a file but the disk is fullif e.errno == errno.EPIPE:print(e, file=sys.stderr)sys.exit(2)raisesys.exit(0)

主程序的主要步骤

  1. 解析命令行参数

    • 使用 _parse_arguments 函数解析命令行参数,获取 --extend--local 选项。
  2. 确定 CMAKE_PREFIX_PATH

    • 如果没有指定 --local 选项,则 CMAKE_PREFIX_PATH 包含当前工作空间的 installdevel 目录,以及系统安装的 ROS 版本路径(如 /opt/ros/noetic)。
    • 如果指定了 --local 选项,则 CMAKE_PREFIX_PATH 只包含当前工作空间的路径,忽略其他工作空间。
  3. 处理当前工作空间路径

    • 获取当前脚本所在的目录(即当前工作空间的路径),并将其转换为使用正斜杠(/),以便与 CMAKE_PREFIX_PATH 中的路径格式一致。
    • 如果当前工作空间路径不在 CMAKE_PREFIX_PATH 中,则将其插入到 CMAKE_PREFIX_PATH 的首位。
  4. 生成环境变量设置代码

    • 撤销之前的环境变量修改:如果未指定 --extend 选项,则调用 rollback_env_variables 函数,撤销之前可能已经设置的环境变量修改。
    • 前置当前工作空间的路径:调用 prepend_env_variables 函数,将当前工作空间的路径前置到各个环境变量中(如 CMAKE_PREFIX_PATHLD_LIBRARY_PATHPATH 等)。
    • 查找并加载环境钩子:调用 find_env_hooks 函数,查找并加载所有找到的环境钩子(environment hooks),这些钩子可以进一步修改环境变量或其他配置。
  5. 输出生成的 shell 代码

    • 将生成的所有 shell 代码行连接成一个字符串,并打印到标准输出。
    • 显式刷新标准输出,确保所有内容都被写入。
  6. 异常处理

    • 捕获潜在的 I/O 错误,特别是当标准输出不可写时(例如磁盘已满的情况),并返回相应的错误码。
  7. 退出程序

    • 正常情况下,程序以状态码 0 退出,表示成功执行。

关键函数解析

1. rollback_env_variables
def rollback_env_variables(environ, env_var_subfolders):"""Generate shell code to reset environment variables.by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH.This does not cover modifications performed by environment hooks."""lines = []unmodified_environ = copy.copy(environ)for key in sorted(env_var_subfolders.keys()):subfolders = env_var_subfolders[key]if not isinstance(subfolders, list):subfolders = [subfolders]value = _rollback_env_variable(unmodified_environ, key, subfolders)if value is not None:environ[key] = valuelines.append(assignment(key, value))if lines:lines.insert(0, comment('reset environment variables by unrolling modifications based on all workspaces in CMAKE_PREFIX_PATH'))return lines
  • 功能:生成用于重置环境变量的 shell 代码,撤销基于 CMAKE_PREFIX_PATH 中所有工作空间的修改。
  • 逻辑:遍历 env_var_subfolders 中定义的环境变量,调用 _rollback_env_variable 函数移除与每个工作空间相关的路径,然后生成相应的 shell 代码。
2. _rollback_env_variable
def _rollback_env_variable(environ, name, subfolders):"""For each catkin workspace in CMAKE_PREFIX_PATH remove the first entry from env[NAME] matching workspace + subfolder.:param subfolders: list of str '' or subfoldername that may start with '/':returns: the updated value of the environment variable."""value = environ[name] if name in environ else ''env_paths = [path for path in value.split(os.pathsep) if path]value_modified = Falsefor subfolder in subfolders:if subfolder:if subfolder.startswith(os.path.sep) or (os.path.altsep and subfolder.startswith(os.path.altsep)):subfolder = subfolder[1:]if subfolder.endswith(os.path.sep) or (os.path.altsep and subfolder.endswith(os.path.altsep)):subfolder = subfolder[:-1]for ws_path in _get_workspaces(environ, include_fuerte=True, include_non_existing=True):path_to_find = os.path.join(ws_path, subfolder) if subfolder else ws_pathpath_to_remove = Nonefor env_path in env_paths:env_path_clean = env_path[:-1] if env_path and env_path[-1] in [os.path.sep, os.path.altsep] else env_pathif env_path_clean == path_to_find:path_to_remove = env_pathbreakif path_to_remove:env_paths.remove(path_to_remove)value_modified = Truenew_value = os.pathsep.join(env_paths)return new_value if value_modified else None
  • 功能:从环境变量中移除与每个 catkin 工作空间相关的路径。
  • 逻辑:遍历 CMAKE_PREFIX_PATH 中的工作空间路径,检查环境变量中是否有与工作空间子目录匹配的路径,如果有则移除该路径,并返回更新后的环境变量值。
3. _get_workspaces
def _get_workspaces(environ, include_fuerte=False, include_non_existing=False):"""Based on CMAKE_PREFIX_PATH return all catkin workspaces.:param include_fuerte: The flag if paths starting with '/opt/ros/fuerte' should be considered workspaces, ``bool``"""# get all cmake prefix pathsenv_name = 'CMAKE_PREFIX_PATH'value = environ[env_name] if env_name in environ else ''paths = [path for path in value.split(os.pathsep) if path]# remove non-workspace pathsworkspaces = [path for path in paths if os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE)) or (include_fuerte and path.startswith('/opt/ros/fuerte')) or (include_non_existing and not os.path.exists(path))]return workspaces
  • 功能:根据 CMAKE_PREFIX_PATH 返回所有 catkin 工作空间的路径。
  • 逻辑:遍历 CMAKE_PREFIX_PATH 中的路径,检查每个路径是否包含 .catkin 标记文件,或者是否符合特定条件(如 /opt/ros/fuerte),并返回符合条件的工作空间路径。
4. prepend_env_variables
def prepend_env_variables(environ, env_var_subfolders, workspaces):"""Generate shell code to prepend environment variables for the all workspaces."""lines = []lines.append(comment('prepend folders of workspaces to environment variables'))paths = [path for path in workspaces.split(os.pathsep) if path]prefix = _prefix_env_variable(environ, 'CMAKE_PREFIX_PATH', paths, '')lines.append(prepend(environ, 'CMAKE_PREFIX_PATH', prefix))for key in sorted(key for key in env_var_subfolders.keys() if key != 'CMAKE_PREFIX_PATH'):subfolder = env_var_subfolders[key]prefix = _prefix_env_variable(environ, key, paths, subfolder)lines.append(prepend(environ, key, prefix))return lines
  • 功能:生成用于前置环境变量的 shell 代码,将当前工作空间的路径添加到各个环境变量中。
  • 逻辑:遍历 env_var_subfolders 中定义的环境变量,调用 _prefix_env_variable 函数生成前置路径,然后生成相应的 shell 代码。
5. _prefix_env_variable
def _prefix_env_variable(environ, name, paths, subfolders):"""Return the prefix to prepend to the environment variable NAME.Adding any path in NEW_PATHS_STR without creating duplicate or empty items."""value = environ[name] if name in environ else ''environ_paths = [path for path in value.split(os.pathsep) if path]checked_paths = []for path in paths:if not isinstance(subfolders, list):subfolders = [subfolders]for subfolder in subfolders:path_tmp = pathif subfolder:path_tmp = os.path.join(path_tmp, subfolder)# skip nonexistent pathsif not os.path.exists(path_tmp):continue# exclude any path already in env and any path we already addedif path_tmp not in environ_paths and path_tmp not in checked_paths:checked_paths.append(path_tmp)prefix_str = os.pathsep.join(checked_paths)if prefix_str != '' and environ_paths:prefix_str += os.pathsepreturn prefix_str
  • 功能:生成要前置到环境变量的路径字符串,确保不会添加重复或无效的路径。
  • 逻辑:遍历 paths 中的路径,检查每个路径是否存在,并确保不会添加已经存在于环境变量中的路径,最后返回前置路径字符串。
6. find_env_hooks
def find_env_hooks(environ, cmake_prefix_path):"""Generate shell code with found environment hooks for the all workspaces."""lines = []lines.append(comment('found environment hooks in workspaces'))generic_env_hooks = []generic_env_hooks_workspace = []specific_env_hooks = []specific_env_hooks_workspace = []generic_env_hooks_by_filename = {}specific_env_hooks_by_filename = {}generic_env_hook_ext = 'bat' if IS_WINDOWS else 'sh'specific_env_hook_ext = environ['CATKIN_SHELL'] if not IS_WINDOWS and 'CATKIN_SHELL' in environ and environ['CATKIN_SHELL'] else Noneworkspaces = [path for path in cmake_prefix_path.split(os.pathsep) if path and os.path.isfile(os.path.join(path, CATKIN_MARKER_FILE))]for workspace in reversed(workspaces):env_hook_dir = os.path.join(workspace, 'etc', 'catkin', 'profile.d')if os.path.isdir(env_hook_dir):for filename in sorted(os.listdir(env_hook_dir)):if filename.endswith('.%s' % generic_env_hook_ext):# remove previous env hook with same name if presentif filename in generic_env_hooks_by_filename:i = generic_env_hooks.index(generic_env_hooks_by_filename[filename])generic_env_hooks.pop(i)generic_env_hooks_workspace.pop(i)# append env hookgeneric_env_hooks.append(os.path.join(env_hook_dir, filename))generic_env_hooks_workspace.append(workspace)generic_env_hooks_by_filename[filename] = generic_env_hooks[-1]elif specific_env_hook_ext is not None and filename.endswith('.%s' % specific_env_hook_ext):# remove previous env hook with same name if presentif filename in specific_env_hooks_by_filename:i = specific_env_hooks.index(specific_env_hooks_by_filename[filename])specific_env_hooks.pop(i)specific_env_hooks_workspace.pop(i)# append env hookspecific_env_hooks.append(os.path.join(env_hook_dir, filename))specific_env_hooks_workspace.append(workspace)specific_env_hooks_by_filename[filename] = specific_env_hooks[-1]env_hooks = generic_env_hooks + specific_env_hooksenv_hooks_workspace = generic_env_hooks_workspace + specific_env_hooks_workspacecount = len(env_hooks)lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_COUNT', count))for i in range(count):lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d' % i, env_hooks[i]))lines.append(assignment('_CATKIN_ENVIRONMENT_HOOKS_%d_WORKSPACE' % i, env_hooks_workspace[i]))return lines
  • 功能:查找并加载所有找到的环境钩子(environment hooks),生成相应的 shell 代码。
  • 逻辑:遍历 CMAKE_PREFIX_PATH 中的工作空间,查找 etc/catkin/profile.d 目录下的环境钩子文件(如 .sh.bat),并生成用于加载这些钩子的 shell 代码。确保不会加载重复的钩子文件,并且优先加载当前工作空间的钩子。

总结

_setup_util.py 的主要作用是生成用于设置环境变量的 shell 代码,确保当前终端会话中的环境变量正确配置,使得用户可以在 catkin 工作空间中使用 ROS 包和工具。它通过以下步骤实现这一目标:

  1. 解析命令行参数:决定是否扩展或覆盖已有的环境变量。
  2. 确定 CMAKE_PREFIX_PATH:根据 --local 选项决定是否只考虑当前工作空间。
  3. 处理当前工作空间路径:确保当前工作空间的路径被正确添加到 CMAKE_PREFIX_PATH 中。
  4. 生成环境变量设置代码:撤销之前的环境变量修改,前置当前工作空间的路径,并查找并加载环境钩子。
  5. 输出生成的 shell 代码:将生成的 shell 代码打印到标准输出,供 setup.sh 等脚本使用。

通过这种方式,_setup_util.py 确保了 ROS 环境的正确配置,使得开发和运行 ROS 节点变得更加方便。

相关文章:

Vins_Fusion_gpu中source setup.bash

文章目录 source setup.bashsetup.bashsetup.sh脚本的主要功能脚本的详细解释1. **初始化和检查**2. **检测操作系统**3. **设置环境变量**4. **记住 shell 类型**5. **调用 Python 脚本生成环境变量**6. **加载环境钩子**7. **清理** 总结 _setup_util.py_setup_util.py 的完整…...

appium学习之二:adb命令

1、查看设备 adb devices 2、连接 adb connect IP:端口 3、安装 adb install xxx.apk 4、卸载 adb uninstall 【包名】 5、把对应目录下的1.txt文件传到手机sdcard下 adb push 1.txt /sdcard 6、进入对应的设备里 adb shell 7、切入sdcard目录 cd /sdcard 8、ls 查…...

Docker 安装 sentinel

Docker 安装系列 1、拉取 [rootTseng ~]# docker pull bladex/sentinel-dashboard Using default tag: latest latest: Pulling from bladex/sentinel-dashboard 4abcf2066143: Pull complete 1ec1e81da383: Pull complete 56bccb36a894: Pull complete 7cc80011dc6f: Pull…...

selinux

项目使用: neverallow 报错: 改法:typeattribute system_server system_writes_mnt_vendor_violators; selinux目录: Android/lagvm/LINUX/android/device/qcom/sepolicy_vndr Android/lagvm/LINUX/android/vendor/jidu/sepoli…...

C++11新特性之线程std::atomic

C std::atomic C 中 std::atomic 的定义及功能 std::atomic 是 C 标准库中提供的一种模板类,主要用于实现 原子操作,以保证多线程环境下对共享变量的安全操作。它提供了一种无需使用互斥锁即可安全访问共享数据的机制,避免了竞争条件。 特…...

MySQL中的通配符

1. 百分号 % 内部工作原理: 代表零个、一个或多个任意字符。LIKE A%:MySQL会从索引(如果存在)中查找所有以 "A" 开头的记录。如果没有索引,则需要扫描整个表。MySQL解析器将模式转换为可执行的形式&#x…...

【ETCD】【源码阅读】stepWithWaitOption方法解析

在分布式系统中,ETCD 作为一个强一致性、高可用的 key-value 存储系统,广泛应用于服务发现、配置管理等场景。ETCD 在内部采用了 Raft 协议来保证集群的一致性,而日志预提案(log proposal)是 Raft 协议中至关重要的一部…...

F12抓包01:启动、面板功能介绍、语言设置、前端样式调试

浏览器检查工具通常用来作为浏览器web服务测试过程中,辅助测试、排查问题、定位缺陷的工具。 本文以mac系统下,当前比较常用的Chrome浏览器为例,讲解“检查”工具的常用功能操作方法。 一、打开方式 **1、****鼠标操作:**浏览器…...

用前端html如何实现2024烟花效果

用HTML、CSS和JavaScript编写的网页&#xff0c;主要用于展示“2024新年快乐&#xff01;”的文字形式烟花效果。下面是对代码主要部分的分析&#xff1a; HTML结构 包含三个<canvas>元素&#xff0c;用于绘制动画。引入百度统计的脚本。 CSS样式 设置body的背景为黑…...

Maven学习(传统Jar包管理、Maven依赖管理(导入坐标)、快速下载指定jar包)

目录 一、传统Jar包管理。 &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;传统的Jar包导入方法。 1、手动寻找Jar包。并放置到指定目录下。 2、使用IDEA的库管理功能。 3、配置环境变量。 &#xff08;3&#xff09;传统的Jar包管理缺点。 二、Maven。 &#…...

mac电脑吧iso文件制作成u盘启动

1 查看u盘的具体路径 diskutil list 根据容量确认路径 /dev/disk2 2、卸载u盘 diskutil unmountDisk /dev/disk2 3、把iso文件写入u盘 sudo dd if/Users/dengjinshan/Downloads/Win11_24H2_Chinese_Simplified_x64.iso of/dev/disk2 bs1m 4、弹出u盘 diskutil eject /dev/dis…...

MySQL数据库的数据类型

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 MySQL数据库的数据类型 收录于专栏[MySQL] 本专栏旨在分享学习MySQL的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 数据类型分类 ​…...

【golang】匿名内部协程,值传递与参数传递

代码例子 下面代码的区别是直接调用循环变量&#xff0c;这里使用的就是这个变量的引用&#xff0c;而不是将参数的副本传递给协程执行 for task : range taskChan {wg.Add(1)go func() {defer wg.Done()task.Do() // 使用外部循环变量}() }func DistributeTasks(taskChan &…...

ByteByteGo-Top 9 HTTP Request Methods 9种HTTP请求方法

更详细准确的描述直接参考 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods/CONNECT ​​​​​本片文章出自 EP85: Top 9 HTTP Request Methods - ByteByteGo Newsletter http request methods 1&#xff0c;GET 从服务器获取资源。 具有幂等性&#xff08;idempo…...

vue3实际案例分析:展示Vue拖拽功能的实现和效果

在现代前端开发中&#xff0c;交互式的用户界面是提升用户体验的关键因素之一。Vue.js&#xff0c;作为一个渐进式JavaScript框架&#xff0c;提供了灵活的组件系统和响应式数据绑定&#xff0c;使得实现复杂的用户交互变得简单。拖拽功能是其中一个常见的交互模式&#xff0c;…...

EasyExcel使用管道流连接InputStream和OutputStream

前言 Java中的InputSteam 是程序从其中读取数据&#xff0c; OutputSteam是程序可以往里面写入数据。 如果我们有在项目中读取数据库的记录&#xff0c; 在转存成Excel文件, 再把文件转存到OSS中。 生成Excel使用的是阿里的EasyExcel 。 他支持Output的方式写出文件内容。 而…...

源码分析之Openlayers中的ZoomToExtent控件

概述 在 Openlayers 中&#xff0c;ZoomToExtent控件可能用的不是很多&#xff0c;它主要用于将地图视图缩放到指定范围&#xff0c;应用场景就是重置地图、恢复初始状态。但是一般情况下&#xff0c;重置地图可能还会有其它操作&#xff0c;比如清除地图上绘制的点线面或者显…...

Acwing 算法基础课 数学知识 线性筛

线性筛素数 也叫欧拉筛。 int pr[maxn]; bool flg[maxn]; int main() {for (int i 2; i < maxn; i) {if (!flg[i]) pr[pr[0]] i;for (int j 1; i * pr[j] < n && j < pr[0]; j) {flg[i * pr[j]] 1;if (i % pr[j] 0) break; // 重点}} }这样筛的话&…...

K8s驱逐阈值调整

要在 Kubernetes 中调整 kubelet 驱逐阈值&#xff0c;特别是针对 imagefs 和 nodefs 的大小阈值&#xff0c;你可以通过修改 kubelet 的启动参数来实现。这些参数定义了在触发 Pod 驱逐之前&#xff0c;节点上的资源使用情况必须满足的硬性条件。 根据你提供的文件内容&#…...

【密码学】BUUCTF Crypto 1 - 12 题 WriteUp

今天&#xff0c;我在 BUUCTF 网站的 crypto section 开启了一场充满挑战的密码学之旅。 这次我一口气完成了 12 个板块的任务&#xff0c;虽然耗时较长&#xff0c;但每一次解密成功的瞬间都让我无比满足&#xff0c;那种沉浸在密码世界里的感觉真的很棒。 接下来&#xff0…...

【文献阅读】使用深度语音后验改进独立于说话者的构音障碍可懂度分类

原文名称: IMPROVED SPEAKER INDEPENDENT DYSARTHRIA INTELLIGIBILITY CLASSIFICATION USING DEEPSPEECH POSTERIORS 本文探讨了利用DeepSpeech后验概率改进说话人无关的构音障碍可理解性分类方法。作者提出了一个基于DeepSpeech(一种端到端的语音转文本引擎)输出的新特征集…...

Image Stitching using OpenCV

文章目录 简介图像拼接管道特征检测和提取特征检测特征提取 特征匹配强力匹配FLANN&#xff08;近似最近邻快速库&#xff09;匹配 单应性估计扭曲和混合结论 使用opencv进行图像拼接 原为url: https://medium.com/paulsonpremsingh7/image-stitching-using-opencv-a-step-by-s…...

如何将CSDN的文章保存为PDF?

目录 1、打开CSDN文章2、按F12或者鼠标右键选择检查并进入控制台3、在控制台输入以下代码4、然后回车&#xff08;Enter&#xff09;如果纵向显示不全就横向 1、打开CSDN文章 2、按F12或者鼠标右键选择检查并进入控制台 3、在控制台输入以下代码 (function(){ $("#side&q…...

设计模式之工厂模式:从汽车工厂到代码工厂

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 工厂模式概述 想象一下你走进一家4S店准备买车。作为顾客&#xff0c;你不需要知道汽车是如何被制造出来的&#xff0c;你只需要告诉销售顾问&a…...

在 Ubuntu 20.04 上离线安装和配置 Redis

下面是从零开始配置 Redis 的完整步骤&#xff0c;包括从安装 Redis 到离线安装 Redis 包的步骤。本文将覆盖如何从下载 Redis 安装包、手动安装 Redis、创建所需目录、配置 Redis、以及如何配置 Redis 为系统服务&#xff0c;确保服务可以在启动时自动运行。 步骤 1: 准备环境…...

Redis的哨兵机制

目录 1. 文章前言2. 基本概念2.1 主从复制的问题2.2 人工恢复主节点故障2.3 哨兵机制自动恢复主节点故障 3. 安装部署哨兵&#xff08;基于docker&#xff09;3.1 安装docker3.2 编排redis主从节点3.3 编排redis-sentinel节点 4. 重新选举5. 选举原理6. 总结 1. 文章前言 &…...

服务器数据恢复—热备盘上线过程中硬盘离线导致raid5阵列崩溃的数据恢复案例

服务器数据恢复环境&#xff1a; 两组分别由4块SAS接口硬盘组建的raid5阵列&#xff0c;两组raid5阵列划分LUN并由LVM管理&#xff0c;格式化为EXT3文件系统。 服务器故障&#xff1a; RAID5阵列中一块硬盘未知原因离线&#xff0c;热备盘自动激活上线替换离线硬盘。在热备盘上…...

Android12 设置无home属性的apk为launcher

目标apk的包类名 QSSI.12/device/qcom/qssi/system.prop// add start target_app_package_name=com.mangechargespot.app target_app_class_name=com.mangechargespot.app.ui.activity.SplashActivity // add end...

STM32F407+LAN8720A +LWIP +FreeRTOS ping通

使用STM32CUBEIDE自带的 LWIP和FreeROTS 版本说明STM32CUBEIDE 操作如下1. 配置RCC/SYS2. 配置ETH/USART3. 配置EHT_RESET/LED4. 配置FreeRTOS5. 配置LWIP6. 配置时钟7. 生成单独的源文件和头文件,并生成代码8. printf重定义9. ethernetif.c添加lan8720a复位10. MY_LWIP_Init …...

构建虚幻引擎中的HUD与UI

在游戏开发中,用户界面(UI)和头部显示(HUD)是玩家体验的重要组成部分。它们提供了关键信息,并增强了游戏的互动性。虚幻引擎(Unreal Engine, UE)以其强大的可视化脚本系统Blueprint和C++ API支持,为开发者提供了一个灵活且功能丰富的环境来创建复杂的UI和HUD元素。 本…...

EXCEL数据清洗的几个功能总结备忘

目录 0 参考教材 1 用EXCEL进行数据清洗的几个功能 2 删除重复值&#xff1a; 3 找到缺失值等 4 大小写转换 5 类型转化 6 识别空格 0 参考教材 精通EXCEL数据统计与分析&#xff0c;中国&#xff0c;李宗璋用EXCEL学统计学&#xff0c;日EXCEL统计分析与决策&#x…...

【CSS in Depth 2 精译_076】12.4 @font-face 的工作原理

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第四部分 视觉增强技术 ✔️【第 12 章 CSS 排版与间距】 ✔️ 12.1 间距设置 12.1.1 使用 em 还是 px12.1.2 对行高的深入思考12.1.3 行内元素的间距设置 12.2 Web 字体12.3 谷歌字体12.4 font-fac…...

深入源码解析:Spring Boot 如何加载 Servlet 、Filter 与 Listener

我们知道&#xff0c;Spring Boot 是在 Spring MVC 的基础上进行了封装&#xff0c;以简化开发者的工作量。尽管如此&#xff0c;Spring Boot 的底层架构依然离不开 Spring MVC 的核心组件&#xff0c;如 Servlet、Filter、Listener&#xff0c;以及RequestMappingHandlerMappi…...

Vue 让视图区域滑到指定位置、回到顶部

滑倒指定位置&#xff1a;获取指定的dom&#xff0c;然后用scrollIntoView使dom出现在视图区域 回到顶部&#xff1a;操作父级dom的scrollTop 0&#xff0c;让该父级下的列表回到顶部 代码如下 <template><div class"testDemo"><div><el-bu…...

C# 属性(Property)

C# 属性(Property) C# 中的属性(Property)是一种用于访问和设置类或结构成员的值的特殊类型的方法。属性允许开发者以字段的形式访问方法,提供了更为安全和灵活的数据封装。在本文中,我们将深入探讨 C# 属性的概念、用途、以及如何有效地使用它们。 属性的定义 属性由…...

Ubuntu20.04调整swap分区大小笔记

Ubuntu20.04调整swap分区大小笔记 参考&#xff1a;https://blog.csdn.net/sunyuhua_keyboard/article/details/142485764 第一步 禁用swap $ cat /etc/fstab # /etc/fstab: static file system information. # # Use blkid to print the universally unique identifier fo…...

【 JAVA中常见的集合操作】

JAVA中常见的集合操作 Java 提供了丰富的集合框架&#xff08;Java Collections Framework&#xff09;&#xff0c;包括多种集合接口和实现类。集合操作可以分为基本操作和高级操作。下面介绍一些常见的集合操作&#xff0c;并给出相应的代码示例。 基本集合操作 创建集合 …...

Kudu 源码编译-aarch架构 1.17.1版本

跟着官方文档编译 第一个问题&#xff1a;在make阶段时会报的问题&#xff1a; kudu/src/kudu/util/block_bloom_filter.cc:210:3: error: ‘vst1q_u32_x2’ was not declared in this scope kudu/src/kudu/util/block_bloom_filter.cc:436:5: error: ‘vst1q_u8_x2’ was no…...

JavaEE多线程案例之阻塞队列

上文我们了解了多线程案例中的单例模式&#xff0c;此文我们来探讨多线程案例之阻塞队列吧 1. 阻塞队列是什么&#xff1f; 阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则. 阻塞队列是⼀种线程安全的数据结构,并且具有以下特性: 当队列满的时候,继续⼊队列就会…...

Java Web 开发学习中:过滤器与 Ajax 异步请求

一、过滤器 Filter&#xff1a; 过滤器的概念与用途 在一个庞大的 Web 应用中&#xff0c;有许多资源需要受到保护或进行特定的预处理。过滤器就像是一位智能的守卫&#xff0c;站在资源的入口处&#xff0c;根据预先设定的规则&#xff0c;决定哪些请求可以顺利访问资源&…...

git SSL certificate problem: unable to get local issuer certificate

Git 客户端将会验证服务器端提供的SSL证书是否由受信任的证书颁发机构&#xff08;Certification Authority&#xff0c;CA&#xff09;签发。如果Git客户端无法找到或验证本地签发者证书&#xff0c;就会出现 unable to get local issuer certificate 或类似的错误。 该问题一…...

Vue.js 响应接口

Vue.js 响应接口 Vue.js,作为一个流行的前端JavaScript框架,以其响应式数据绑定和组件化开发而闻名。响应式系统是Vue.js的核心特性之一,它允许开发者创建高度动态和交互式的用户界面。本文将深入探讨Vue.js的响应接口,包括其工作原理、使用方法和最佳实践。 响应式原理 …...

vue2-代理打包问题;CORS针对AJAX 请求,而不适用于资源请求

打包后请求被转发出现问题&#xff08;如返回 405 Method Not Allowed&#xff09;&#xff0c;通常是由以下原因导致的&#xff1a; 1. 代理配置未生效 原因分析 在开发环境中&#xff0c;Vue CLI 的 devServer.proxy 仅在本地开发服务器&#xff08;npm run serve&#xff…...

websocket 服务 pinia 全局配置

websocket 方法类 // stores/webSocketStore.ts import { defineStore } from "pinia";interface WebSocketStoreState {ws: WebSocket | null; // WebSocket 实例callbacks: ((message: string) > void)[]; // 消息回调函数列表connected: boolean; // 连接状态…...

YOLO系列正传(二)YOLOv3论文精解(上)——从FPN到darknet-53

系列文章 YOLO系列基础 YOLO系列基础合集——小白也看得懂的论文精解-CSDN博客 YOLO系列正传 YOLO系列正传系列&#xff08;一&#xff09;类别损失与MSE损失函数、交叉熵损失函数-CSDN博客 背景 随着YOLOv11版本的发布&#xff0c;YOLO算法在视觉检测领域独领风骚&#x…...

可视化建模与UML《部署图实验报告》

一、实验目的&#xff1a; 1、熟悉部署图的基本功能和使用方法。 2、掌握使用建模工具软件绘制部署图的方法 二、实验环境&#xff1a; window11 EA15 三、实验内容&#xff1a; 根据以下的描述&#xff0c;绘制部署图。 网上选课系统在服务器端使用了两台主机&#xff0c;一…...

详解RabbitMQ在Ubuntu上的安装

​​​​​​​ 目录 Ubuntu 环境安装 安装Erlang 查看Erlang版本 退出命令 ​编辑安装RabbitMQ 确认安装结果 安装RabbitMQ管理界面 启动服务 查看服务状态 通过IP:port访问 添加管理员用户 给用户添加权限 再次访问 Ubuntu 环境安装 安装Erlang RabbitMq需要…...

SQL 快速参考

SQL 快速参考 引言 SQL&#xff08;Structured Query Language&#xff09;是一种用于管理关系数据库管理系统&#xff08;RDBMS&#xff09;的标准编程语言。它被广泛用于数据查询、数据更新、数据库维护以及访问控制。本快速参考指南旨在提供SQL的基本概念和常用命令的概览…...

数据结构--树和二叉树

树和二叉树的定义 树的定义 树是一种非线性的数据结构&#xff0c;它模拟了具有层次关系的数据的集合。在树结构中&#xff0c;存在以下基本概念&#xff1a; 节点&#xff08;Node&#xff09;&#xff1a;树的每个元素被称为节点。根节点&#xff08;Root Node&#xff09…...

R语言的数据结构-向量

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 在R语言中&#xff0c;数据结构是非常关键的部分&#xff0c;它提…...