为何/bin/sh函数中管道内的return返回值未被上层正确识别
问题根因
这是POSIX标准规定的shell行为导致的:管道连接的所有命令默认都会运行在独立的子shell进程中。
你的代码里while read path_entry循环是管道的最后一段,运行在子shell环境中:
- 循环内匹配到目标路径后执行的
return 0,只会终止当前子shell,无法作用于外层的path_exists函数 - 子shell退出后,父函数的逻辑会继续向下执行,最终走到最后的
return 1,所以函数永远返回1
兼容/bin/sh的修复方案
方案1:使用here document喂给循环,避免子shell
让while循环运行在当前函数进程上下文,return可以直接退出函数:
path_exists() { path="$1" && shift while IFS= read -r path_entry ; do test "$path" = "$path_entry" && return 0 done << EOF $(echo "$PATH" | tr ':' '\n') EOF return 1 }
方案2:用字符串匹配直接判断,性能最优
不需要拆分PATH也不需要循环,是最简洁的POSIX兼容实现,符合PATH的规范设计:
path_exists() { case ":$PATH:" in *:"$1":*) return 0 ;; *) return 1 ;; esac }
原理是给PATH前后都加上冒号,只要目标路径被两个冒号包裹,就说明PATH中存在该路径。
内容的提问来源于stack exchange,提问作者Naftuli Kay
相关产品推荐
相关产品推荐

