如何编写bash/ksh通用脚本,实现输出同时记录日志并显示?
兼容bash与ksh的日志输出实现方案
你原本的代码依赖bash专属的进程替换语法>(...),ksh不支持该语法因此抛出语法错误。以下两种方案可实现脚本输出同时显示在终端并写入日志文件,且兼容bash和ksh:
方案一:通用命名管道法(适配所有POSIX兼容shell)
这是兼容性最强的方案,几乎所有主流shell都支持:
# 定义日志目录和文件路径 SDIR="/path/to/your/log/directory" LOG_FILE="${SDIR}/script.log" # 确保日志目录存在 mkdir -p "${SDIR}" # 创建命名管道 mkfifo -p log_pipe # 后台启动tee,从管道读取内容,同时输出到终端和日志文件 tee -ia "${LOG_FILE}" < log_pipe & # 将脚本标准输出重定向到管道 exec 1> log_pipe # 脚本退出时自动删除管道 trap 'rm -f log_pipe' EXIT # -------------------------- # 此处编写你的脚本核心逻辑 echo "测试内容:同时输出到屏幕和日志" # --------------------------
方案二:分shell适配优化
如果希望针对不同shell使用更贴合的语法,可以通过判断当前shell类型分别处理:
SDIR="/path/to/your/log/directory" LOG_FILE="${SDIR}/script.log" mkdir -p "${SDIR}" # 获取当前运行的shell名称 CURRENT_SHELL=$(ps -p $$ -o comm=) if [ "${CURRENT_SHELL}" = "bash" ]; then # bash使用进程替换 exec 1> >(tee -ia "${LOG_FILE}") elif [ "${CURRENT_SHELL}" = "ksh" ]; then # ksh使用协程(coproc,ksh93及以上版本支持) coproc TEERUNNER { tee -ia "${LOG_FILE}"; } exec 1>&${TEERUNNER[1]} else # 其他shell fallback到通用重定向 exec > >(tee -ia "${LOG_FILE}") 2>&1 fi # 测试代码 echo "兼容bash/ksh的日志输出测试"
关键说明
tee的-i选项用于忽略中断信号,避免脚本中途被中断时日志记录异常- 若使用老版本ksh(不支持
coproc),建议优先选择方案一的命名管道法 - 务必确保
SDIR目录存在,否则日志文件无法创建
内容的提问来源于stack exchange,提问作者Bharat Goyal
相关产品推荐
相关产品推荐

