当前位置: 首页 > 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 的完整…...

怎么理解大模型推理时的Top_P参数?

本篇博客介绍一下大模型推理时的Top_P参数,Top_P与Top_K,Beamsearch,temperature 都是什么关系以及该如何选择Top_P参数。 文章目录 一、什么是Top_P参数?二、工作原理三、top_p和top_k是什么关系?四、Top_P和BeamSea…...

hive+hadoop架构数仓使用问题记录

使用问题记录 问题1:5条数据的表执行count(*)函数,很慢,43s才出结果? 该数仓的分析计算是基于hadoop的mapreduce分布式计算框架运行的,适用于大量/海量数据,少量数据,还是使用单体数据库快。也…...

前端的 Python 入门指南(三):数据类型对比 - 彻底的一切皆对象实现和包装对象异同

《前端的 Python 入门指南》系列文章: (一):常用语法和关键字对比(二):函数的定义、参数、作用域对比(三):数据类型对比 - 彻底的一切皆对象实现和包装对象异…...

Axios结合Typescript 二次封装完整详细场景使用案例

Axios 是一个基于 promise 的 HTTP 客户端,用于浏览器和 node.js。二次封装 Axios 主要是为了统一管理 HTTP 请求,例如设置统一的请求前缀、头部、超时时间,统一处理请求和响应的格式,以及错误处理等。 以下是一个使用 TypeScrip…...

基于Kubesphere实现微服务的CI/CD——部署微服务项目(三)

目录 一、kubesphere安装 1、安装本地持久存储 1.1、default-storage-class.yaml 1.2、 openebs-operator.yaml 1.3、安装 Default StorageClass 2、安装kubesphere 2.1、安装Helm 2.2、安装kubesphere 二、配置kubesphere 1、安装插件 2、创建devops项目 3、配置…...

【使用webrtc-streamer解析rtsp视频流】

webrtc-streamer WebRTC (Web Real-Time Communications) 是一项实时通讯技术,它允许网络应用或者站点,在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流和(或&a…...

element左侧导航栏

由element组件搭建的左侧导航栏 预览: html代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>首页</title><style> /*<!-- 调整页面背景颜色-->*/body{background-colo…...

【金融贷后】贷后运营精细化管理

文章目录 一、贷后专业术语讲解① 什么是贷后&#xff0c;贷后部是干什么的&#xff1f;② 贷后部门常见组织架构&#xff1f;③ 贷后专业术语有哪些&#xff1f; 二、贷后常用作业手段介绍① 贷后产品形态介绍&#xff1f;② 催收常用的方法&#xff1f; 三、贷后策略岗位介绍…...

学习CSS第七天

学习文章目录 一.交集选择器 一.交集选择器 使用多个条件符合的元素&#xff0c;可提高区分的精准度 元素配合类名是使用场景最多的 &#xff08;元素必须是第一位&#xff0c;ID一般不写&#xff09; <!DOCTYPE html> <html lang"zh-CN"> <head>…...

Image Stitching using OpenCV

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

CentOS7 安装Selenium(使用webdriver_manager自动安装ChromeDriver)

在 CentOS 7 上安装 Selenium 通常涉及几个步骤&#xff0c;包括安装 Python、安装 Selenium 库、安装 WebDriver 以及配置环境。以下是详细的步骤&#xff1a; 1. 安装 Python 和 pip 如果你的系统中还没有安装 Python 和 pip&#xff0c;可以使用以下命令进行安装&#xff…...

鸿蒙手机文件目录

最近在开发鸿蒙&#xff0c;想把文件从电脑上发送到鸿蒙上我的手机APP的根目录&#xff0c;但是试了几次目录都不对&#xff0c;最后终于找到了&#xff0c;在这里记录一下 鸿蒙手机路径: /storage/media/100/local/files/Docs 将文件从电脑发送到手机&#xff1a;hdc file s…...

泷羽Sec学习笔记-Bp中ip伪造、爬虫审计

ip伪造与爬虫审计 ip伪造 下载插件&#xff1a;burpFakeIP 地址&#xff1a;GitHub - TheKingOfDuck/burpFakeIP: 服务端配置错误情况下用于伪造ip地址进行测试的Burp Suite插件 python版需要配置jython&#xff1a;下载地址&#xff1a;Maven Central: org.python:jython-…...

电子电工一课一得

首语 在现代社会中&#xff0c;电子电工技术已经渗透到我们生活的方方面面&#xff0c;从家用电器到工业自动化&#xff0c;从通信设备到智能系统&#xff0c;无一不依赖于电子电工技术。因此&#xff0c;掌握电子电工的基础知识&#xff0c;不仅对理工科学生至关重要&#xf…...

Cesium 限制相机倾斜角(pitch)滑动范围

1.效果 2.思路 在项目开发的时候&#xff0c;有一个需求是限制相机倾斜角&#xff0c;也就是鼠标中键调整视图俯角时&#xff0c;不能过大&#xff0c;一般 pitch 角度范围在 0 至 -90之间&#xff0c;-90刚好为正俯视。 在网上查阅了很多资料&#xff0c;发现并没有一个合适的…...

配置ssh-key连接github

GitHub 通过在 2022 年 3 月 15 日删除旧的、不安全的密钥类型来提高安全性。 具体内容参考如下链接 https://docs.github.com/zh/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent mac配置 ssh-keygen -t ed25519 -C …...

Linux——进程控制模拟shell

1.进程创建 我们在之前的文章中介绍过进程创建的方法&#xff0c;可以通过系统调用接口fork来创建新的进程。 fork在创建完新的子进程之后&#xff0c;返回值是一个pid&#xff0c;对于父进程返回子进程的pid&#xff0c;对于子进程返回0。fork函数后父子进程共享代码&#xff…...

【HarmonyOS】鸿蒙应用实现手机摇一摇功能

【HarmonyOS】鸿蒙应用实现手机摇一摇功能 一、前言 手机摇一摇功能&#xff0c;是通过获取手机设备&#xff0c;加速度传感器接口&#xff0c;获取其中的数值&#xff0c;进行逻辑判断实现的功能。 在鸿蒙中手机设备传感器ohos.sensor (传感器)的系统API监听有以下&#xf…...

Kael‘thas Sunstrider Ashes of Al‘ar

Kaelthas Sunstrider 凯尔萨斯逐日者 <血精灵之王> Kaelthas Sunstrider - NPC - 魔兽世界怀旧服TBC数据库_WOW2.43数据库_70级《燃烧的远征》数据库 Ashes of Alar 奥的灰烬 &#xff08;凤凰 310%速度&#xff09; Ashes of Alar - Item - 魔兽世界怀旧服TBC数据…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)

参考官方文档&#xff1a;https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java&#xff08;供 Kotlin 使用&#xff09; 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...