我有数百个子目录,$
其名称中的第一个字符包含美元符号(即 ),每个子目录都需要访问。这些子目录不能重命名。 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
。