修复shell脚本失败的修改

复制代码
报错的版本:
#!/bin/bash
set -euo pipefail   # 启用严格模式,但后续会临时关闭 -u 以兼容外部脚本

# 获取脚本所在目录(绝对路径)
SHELL_FOLDER=$(dirname "$(readlink -f "$0")")
cd "$SHELL_FOLDER" || { echo "错误:无法进入目录 $SHELL_FOLDER"; exit 1; }

# 设置环境变量(注意:如果后续 source 会覆盖 LD_LIBRARY_PATH,可考虑放在 source 之后)
export AMSR_DISABLE_INTEGRITY_CHECK=1
export AMSR_PROCESS_SHORT_NAME_PATH=""

# 临时关闭未定义变量检查,以兼容某些外部脚本
set +u

# 加载依赖环境(先检查文件是否存在)
if [ -f "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash" ]; then
    source "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash"
else
    echo "警告:未找到 senseauto-rscl 的 setup.bash,可能影响运行"
fi

if [ -f "/opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash" ]; then
    source "/opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash"
else
    echo "警告:未找到 senseauto-framework-sdk 的 setup.bash,可能影响运行"
fi

# 恢复未定义变量检查
set -u

# 现在设置 LD_LIBRARY_PATH(放在 source 之后,避免被覆盖)
export LD_LIBRARY_PATH="/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:${LD_LIBRARY_PATH:-}"

# 定义目录和文件夹名称
SOURCE_DIR="./AdaptiveApplications/Transmsg/gen"
TARGET_DIR="./AdaptiveApplications/output/opt/Transmsg"
FOLDER_NAME="etc"

# 确保目标目录存在
mkdir -p "${TARGET_DIR}"

# 检查目标目录中是否存在指定文件夹
if [ ! -d "${TARGET_DIR}/${FOLDER_NAME}" ]; then
    echo "文件夹 ${FOLDER_NAME} 不存在,正在从 ${SOURCE_DIR} 拷贝..."

    # 检查源文件夹是否存在
    if [ -d "${SOURCE_DIR}/${FOLDER_NAME}" ]; then
        # 使用 cp 命令拷贝文件夹(-r 递归,-p 保留属性)
        cp -r "${SOURCE_DIR}/${FOLDER_NAME}" "${TARGET_DIR}/"
        echo "拷贝成功!"
    else
        echo "错误:源文件夹 ${SOURCE_DIR}/${FOLDER_NAME} 不存在!"
        exit 1
    fi
else
    echo "文件夹 ${FOLDER_NAME} 已存在,跳过拷贝。"
fi

# 进入程序目录并启动
cd "./AdaptiveApplications/output/opt/Transmsg" || { echo "错误:无法进入程序目录"; exit 1; }

# 检查可执行文件是否存在并有执行权限
if [ ! -x "./bin/Transmsg" ]; then
    echo "错误:可执行文件 ./bin/Transmsg 不存在或没有执行权限"
    exit 1
fi

./bin/Transmsg

报错版本2:

SHELL_FOLDER=$(dirname $(readlink -f "$0"))
cd $SHELL_FOLDER

export AMSR_DISABLE_INTEGRITY_CHECK=1
export AMSR_PROCESS_SHORT_NAME_PATH=""
export LD_LIBRARY_PATH=/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:$LD_LIBRARY_PATH

source /opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash
source /opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash
# 定义目录和文件夹名称
SOURCE_DIR="./AdaptiveApplications/Transmsg/gen"
TARGET_DIR="./AdaptiveApplications/output/opt/Transmsg"
FOLDER_NAME="etc"

# 检查目标目录中是否存在指定文件夹
if [ ! -d "${TARGET_DIR}/${FOLDER_NAME}" ]; then
    echo "文件夹 ${FOLDER_NAME} 不存在,正在从 ${SOURCE_DIR} 拷贝..."
    
    # 检查源文件夹是否存在
    if [ -d "${SOURCE_DIR}/${FOLDER_NAME}" ]; then
        # 使用cp命令拷贝文件夹
        cp -r "${SOURCE_DIR}/${FOLDER_NAME}" "${TARGET_DIR}/"
        
        # 可选:检查拷贝是否成功
        if [ $? -eq 0 ]; then
            echo "拷贝成功!"
        else
            echo "拷贝失败!"
            exit 1
        fi
    else
        echo "错误:源文件夹 ${SOURCE_DIR}/${FOLDER_NAME} 不存在!"
        exit 1
    fi
else
    echo "文件夹 ${FOLDER_NAME} 已存在,跳过拷贝。"
fi



cd ./AdaptiveApplications/output/opt/Transmsg
./bin/Transmsg

最后修改后能跑的版本:
#!/bin/bash
set -euo pipefail   # 启用严格模式,但后续会临时关闭 -u 以兼容外部脚本

# 获取脚本所在目录(绝对路径)
SHELL_FOLDER=$(dirname "$(readlink -f "$0")")
cd "$SHELL_FOLDER" || { echo "错误:无法进入目录 $SHELL_FOLDER"; exit 1; }

# 设置环境变量(注意:如果后续 source 会覆盖 LD_LIBRARY_PATH,可考虑放在 source 之后)
export AMSR_DISABLE_INTEGRITY_CHECK=1
export AMSR_PROCESS_SHORT_NAME_PATH=""

# 临时关闭未定义变量检查,以兼容某些外部脚本
set +u

# 加载依赖环境(先检查文件是否存在)
if [ -f "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash" ]; then
    source "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash"
else
    echo "警告:未找到 senseauto-rscl 的 setup.bash,可能影响运行"
fi

if [ -f "/opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash" ]; then
    source "/opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash"
else
    echo "警告:未找到 senseauto-framework-sdk 的 setup.bash,可能影响运行"
fi

# 恢复未定义变量检查
set -u

# 现在设置 LD_LIBRARY_PATH(放在 source 之后,避免被覆盖)
export LD_LIBRARY_PATH="/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:${LD_LIBRARY_PATH:-}"

# 定义目录和文件夹名称
SOURCE_DIR="./AdaptiveApplications/Transmsg/gen"
TARGET_DIR="./AdaptiveApplications/output/opt/Transmsg"
FOLDER_NAME="etc"

# 确保目标目录存在
mkdir -p "${TARGET_DIR}"

# 检查目标目录中是否存在指定文件夹
if [ ! -d "${TARGET_DIR}/${FOLDER_NAME}" ]; then
    echo "文件夹 ${FOLDER_NAME} 不存在,正在从 ${SOURCE_DIR} 拷贝..."

    # 检查源文件夹是否存在
    if [ -d "${SOURCE_DIR}/${FOLDER_NAME}" ]; then
        # 使用 cp 命令拷贝文件夹(-r 递归,-p 保留属性)
        cp -r "${SOURCE_DIR}/${FOLDER_NAME}" "${TARGET_DIR}/"
        echo "拷贝成功!"
    else
        echo "错误:源文件夹 ${SOURCE_DIR}/${FOLDER_NAME} 不存在!"
        exit 1
    fi
else
    echo "文件夹 ${FOLDER_NAME} 已存在,跳过拷贝。"
fi

# 进入程序目录并启动
cd "./AdaptiveApplications/output/opt/Transmsg" || { echo "错误:无法进入程序目录"; exit 1; }

# 检查可执行文件是否存在并有执行权限
if [ ! -x "./bin/Transmsg" ]; then
    echo "错误:可执行文件 ./bin/Transmsg 不存在或没有执行权限"
    exit 1
fi

./bin/Transmsg

报错现象1:

复制代码
nvidia@tegra-ubuntu:/ota/ws_usharing/transmsg_l29_m18 _mcu$ ./start_transmsg_l29.sh 
./start_transmsg_l29.sh: line 3: cd: too many arguments
文件夹 etc 已存在,跳过拷贝。
./bin/Transmsg: error while loading shared libraries: libTransmsgCM.so.1: cannot open shared object file: No such file or directory

报错现象2:

复制代码
nvidia@tegra-ubuntu:/ota/ws_usharing/transmsg_l29_m18_mcu_version$ ./start_transmsg_l29.sh 
文件夹 etc 已存在,跳过拷贝。
Log sink failed to initialize:
Error Message: kInitializationFailedUnableToOpenSinkFile: There was an error opening the specified file for the file sink
User Message: Invalid argument
ara::core::Initialize() failed! Error in amsr::log::internal::InitializeComponent(). Result contains: kInitializationFailedUnableToOpenSinkFile: There was an error opening the specified file for the file sink, Invalid argument
Initialization for Adaptive Application failed.
Result contains: kInitializationFailedUnableToOpenSinkFile: There was an error opening the specified file for the file sink, Invalid argument
Could not initialize Adaptive Application!
./start_transmsg_l29.sh: line 43: 17096 Aborted                 ./bin/Transmsg

==============修改解决的最关键的部分===============================

1. 解决 cd: too many arguments 错误

报错版本2(简单版)

bash

复制代码
SHELL_FOLDER=$(dirname $(readlink -f "$0"))
cd $SHELL_FOLDER
  • 变量未加引号,如果路径包含空格,cd 会收到多个参数,直接报错退出。

正常版本

bash

复制代码
SHELL_FOLDER=$(dirname "$(readlink -f "$0")")
cd "$SHELL_FOLDER" || { echo "错误:无法进入目录 $SHELL_FOLDER"; exit 1; }
  • 所有变量都加了双引号,并增加错误处理,确保工作目录正确切换。

2. 解决 libTransmsgCM.so.1: cannot open shared object file 和 "Log sink failed" 错误

2.1 LD_LIBRARY_PATH 设置时机错误

报错版本2(简单版)

bash

复制代码
export LD_LIBRARY_PATH=/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:$LD_LIBRARY_PATH

source /opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash
source /opt/senseauto/senseauto-framework-sdk/active/resource/scripts/setup.bash
  • LD_LIBRARY_PATHsource 之前设置,外部脚本很可能覆盖它,导致程序运行时找不到动态库。

正常版本

bash

复制代码
# 临时关闭未定义变量检查,以兼容某些外部脚本
set +u

# 加载依赖环境(先检查文件是否存在)
if [ -f "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash" ]; then
    source "/opt/senseauto/senseauto-rscl/active/resource/scripts/setup.bash"
else
    echo "警告:未找到 senseauto-rscl 的 setup.bash,可能影响运行"
fi

# ... 第二个 source ...

# 恢复未定义变量检查
set -u

# 现在设置 LD_LIBRARY_PATH(放在 source 之后,避免被覆盖)
export LD_LIBRARY_PATH="/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:${LD_LIBRARY_PATH:-}"
  • LD_LIBRARY_PATH 移到 source 之后,保证外部脚本的修改不会冲掉我们需要的库路径。

2.2 未定义变量导致脚本退出

报错版本1(严格模式)

bash

复制代码
export LD_LIBRARY_PATH="/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:${LD_LIBRARY_PATH}"
  • set -u 模式下,如果 LD_LIBRARY_PATH 之前未定义,${LD_LIBRARY_PATH} 会触发"unbound variable"错误,脚本直接退出,根本不会启动程序。

正常版本

bash

复制代码
export LD_LIBRARY_PATH="/svp/lib:${SHELL_FOLDER}/AdaptiveApplications/Transmsg/lib:${LD_LIBRARY_PATH:-}"
  • 使用 ${LD_LIBRARY_PATH:-} 语法,当变量未定义时自动展开为空字符串,避免了脚本因未定义变量而退出。

=================================================================

为什么其他修改不是"一下就能跑"的决定性因素?

  • set +u / set -u 包裹 source:这个在报错版本1中已经存在,但它只是防止外部脚本的未定义变量导致脚本中断;如果库路径问题没解决,程序依然无法运行。

  • mkdir -p可执行文件检查:这些是健壮性增强,但原程序如果已经存在目录和文件,它们不会成为启动的障碍。

  • 文件存在性检查 :同样属于健壮性改进,即使没有这些检查,只要文件存在,source 仍会执行。

总结

让脚本"一下就能跑"的两个最直接的修改:

错误现象 错误代码(报错版本) 修复代码(正常版本)
cd: too many arguments cd $SHELL_FOLDER cd "$SHELL_FOLDER"
libTransmsgCM.so.1: cannot open shared object file + "Log sink failed" export LD_LIBRARY_PATH=... 放在 source 之前 ,且使用 ${LD_LIBRARY_PATH} 未加 :- export 移到 source 之后 ,并改为 ${LD_LIBRARY_PATH:-}

这两个修改分别解决了路径切换失败和动态库加载失败的问题,程序得以正常启动。其他健壮性改进则让脚本在各种异常情况下都能给出明确提示,属于锦上添花。

相关推荐
ysa0510302 小时前
迷宫传送[最短路径]
c++·笔记·算法·深度优先
鄭郑2 小时前
Figma学习笔记--02
笔记·学习·figma
左左右右左右摇晃2 小时前
Java并发——锁的状态演变
java·开发语言·笔记
今儿敲了吗2 小时前
DS-1 传值与传引用
笔记·学习
ALINX技术博客2 小时前
【黑金云课堂笔记】第一~二期FPGA知识点总结
笔记·fpga开发
悠哉悠哉愿意2 小时前
【单片机学习笔记】第十一届省赛复盘
笔记·单片机·嵌入式硬件·学习
oi..3 小时前
Flag入门—修改数据包拿到答案
笔记·测试工具·安全·网络安全
马猴烧酒.3 小时前
【Java复习|Lambda表达式】Java Lambda 表达式、函数式接口与匿名内部类:从起源到原理
java·开发语言·ide·笔记·python·spring
風清掦3 小时前
【江科大STM32学习笔记-09】USART串口协议 - 9.2 USART串口数据包
笔记·stm32·单片机·嵌入式硬件·学习