bash 中 eval 字符串内的美元符号

bash 中 eval 字符串内的美元符号

我有数百个子目录,$其名称中的第一个字符包含美元符号(即 ),每个子目录都需要访问。这些子目录不能重命名。 bash 脚本函数尝试访问每个 and (到目前为止)以回显其所在的路径。尝试通过构建的路径字符串来执行此操作,然后对其进行评估。

打印的行cmd=${cmd}确实cmd=cd /rbyoko/c/$Ono.RCB按预期显示 - 但是, eval 命令错误解释了$Ono.RCB(可能$Ono是空 var)并导致:-bash: cd: /rbyoko/c/.BIN/: No such file or directory 然后打印以下行 We are in /home/user(脚本运行的位置)。

我的问题:如何评估字符串(和/或使用 转义子目录$)才能真正成功访问所需的子目录?

这是我的功能:

visit_tree_recbin()
{
            strings="cdhlotpw"
            MACHINE=`uname -a`
            PWD=`pwd`
            for i in $(seq 1 ${#strings})
            do
                c="${strings:i-1:1}"
                echo "Letter $i: $c"
                #build eval string to do: cd "/rbyoko/${c}/\$Ono.RCB/"
                x1="cd /rbyoko/${c}/"
                x2="\$"
                x3="Ono.RCB/"
                cmd="${x1}${x2}${x3}"
                echo "cmd=${cmd}"
                eval "${x1}${x2}${x3}"
                echo "We are in " `pwd`
            done
}

答案1

不要尝试运行存储在变量中的命令(除非它只是一个简单的命令名称和/或路径)。除非您正确引用(这可能很繁琐并导致代码不太健壮),否则它肯定会以有趣的方式失败。

在你的情况下,这就足够了

cd "/rbyoko/$c/\$Ono.RCB"

即引用目录路径名(以允许$c有空格),然后转义$.

或者:

cd "/rbyoko/$c"/'$Ono.RCB'

即用美元符号单引号该位以保护它免受 shell 的影响。

您的函数已修改:

visit_tree_recbin () {
    for dir in c d h l o t p w; do
            cd "/rbyoko/$dir"/'$Ono.RCB'
            printf 'We are now in %s\n' "$PWD"
    done
}

或者,

visit_tree_recbin () {
    for dirpath in /rbyoko/[cdhlotpw]/'$Ono.RCB'/; do
            cd "$dirpath"
            printf 'We are now in %s\n' "$PWD"
    done
}

不同之处在于第一个变体将创建目录路径名并cd进入其中。如果目录不存在,这可能会失败。

第二种变体使用匹配的文件名通配模式现存的目录。如果模式与任何内容匹配,则cd将会成功(如果您有权cd进入该目录)。

请注意,bash维护一个PWD包含当前工作目录的路径名的变量,因此这里不需要使用pwd

相关内容