Zsh环境下Source .sh文件出现addvar:1: bad substitution错误的求助
解决Zsh中Source含Bash语法脚本时的"bad substitution"错误及变量导出问题
这个问题我很熟悉——你遇到的bad substitution错误根源在于Zsh和Bash的语法差异,而直接执行脚本没效果则是Shell环境的特性导致的,我来一步步帮你解决:
1. 为什么会报"bad substitution"?
你的addvar函数里的local tmp="${!1}"是Bash专属的间接参数扩展语法,用来通过变量名的字符串间接获取变量值。但Zsh不支持这种写法,它用${(P)1}来实现同样的间接引用功能,所以Zsh解析到${!1}时就会报错。
2. 修复脚本让它能在Zsh中Source
只需要把函数里的间接引用部分改成Zsh兼容的写法即可,修改后的函数如下:
function addvar () { local tmp="${(P)1}" tmp="${tmp//:${2}:/:}" tmp="${tmp/#${2}:/}" tmp="${tmp/%:${2}/}" export $1="${2}:${tmp}" }
修改后再执行source file.sh,就不会再出现错误了,脚本里的export语句也会在当前Shell环境中生效。
3. 为什么直接执行./file.sh没效果?
哪怕你加了#!/bin/bash,直接执行脚本是在一个子Shell进程里运行的。子Shell中导出的变量只在自身进程有效,不会传递到父Shell(也就是你的终端会话)。只有通过source(或者简写为.)命令让脚本在当前Shell环境中执行,变量才会被导出到你的终端会话里。
4. 可选:让脚本同时兼容Bash和Zsh
如果需要脚本既能在Bash中运行,也能在Zsh中Source,可以加个Shell版本判断,自动适配语法:
function addvar () { # 判断当前是Zsh还是Bash,选择对应的间接引用语法 if [[ -n "$ZSH_VERSION" ]]; then local tmp="${(P)1}" else local tmp="${!1}" fi tmp="${tmp//:${2}:/:}" tmp="${tmp/#${2}:/}" tmp="${tmp/%:${2}/}" export $1="${2}:${tmp}" }
内容的提问来源于stack exchange,提问作者user1773603
相关产品推荐
相关产品推荐

