脚本在FreeBSD失效:Linux正常但if判断未生效,求排查
问题:FreeBSD下脚本检查wget存在却仍报错未找到的原因及修复
我正在为自己的编程语言编写可移植的编译器构建安装脚本,脚本逻辑如下:
mkdir ArithmeticExpressionCompiler cd ArithmeticExpressionCompiler if command -v wget &> /dev/null then wget https://flatassembler.github.io/Duktape.zip else curl -o Duktape.zip https://flatassembler.github.io/Duktape.zip fi unzip Duktape.zip if command -v gcc &> /dev/null then gcc -o aec aec.c duktape.c -lm # The linker that comes with recent versions of Debian Linux insists that "-lm" is put AFTER the source files, or else it outputs some confusing error message. else clang -o aec aec.c duktape.c -lm fi ./aec analogClock.aec if command -v gcc &> /dev/null then gcc -o analogClock analogClock.s -m32 else clang -o analogClock analogClock.s -m32 fi ./analogClock
但在FreeBSD上运行该脚本时,系统报错wget未找到,尽管脚本在调用wget前已检查其是否存在。该脚本在Linux系统上可正常运行,FreeBSD使用sh而非bash,怀疑脚本不符合POSIX标准。
问题根源
&> /dev/null是Bash的扩展语法,并非POSIX标准写法。FreeBSD默认的sh是严格遵循POSIX规范的shell,它会将&> /dev/null解析为两个独立的操作:
- 把
command -v wget放到后台执行(&的作用) - 将空输出重定向到
/dev/null(> /dev/null的作用)
这导致if条件判断的是后台进程的启动状态(永远为真),而不是wget是否存在的实际结果。即使系统中没有wget,条件也会成立,进而执行wget命令引发错误。
修复方案
将所有&> /dev/null替换为POSIX标准的> /dev/null 2>&1,这是同时重定向标准输出(stdout)和标准错误(stderr)到/dev/null的合规写法。
修复后的脚本:
mkdir ArithmeticExpressionCompiler cd ArithmeticExpressionCompiler if command -v wget > /dev/null 2>&1 then wget https://flatassembler.github.io/Duktape.zip else curl -o Duktape.zip https://flatassembler.github.io/Duktape.zip fi unzip Duktape.zip if command -v gcc > /dev/null 2>&1 then gcc -o aec aec.c duktape.c -lm # The linker that comes with recent versions of Debian Linux insists that "-lm" is put AFTER the source files, or else it outputs some confusing error message. else clang -o aec aec.c duktape.c -lm fi ./aec analogClock.aec if command -v gcc > /dev/null 2>&1 then gcc -o analogClock analogClock.s -m32 else clang -o analogClock analogClock.s -m32 fi ./analogClock
内容的提问来源于stack exchange,提问作者FlatAssembler
相关产品推荐
相关产品推荐

