Shell Cd&x27;通过读取';cd&x27;从文件中

Shell Cd&x27;通过读取';cd&x27;从文件中,shell,unix,cd,Shell,Unix,Cd,我编写了一个脚本,通过从文件中读取cd的值来更改目录(cd)。但是当我运行这个脚本时,我遇到了“没有这样的文件或目录”错误 这是我写的剧本: #!/bin/bash while read line do IN=$line set -- "$IN" IFS=":"; declare -a Array=($*) echo "File location : ${Array[1]}" location=${Array[1]} echo "Location : $location" cd "$loca

我编写了一个脚本,通过从文件中读取cd的值来更改目录(cd)。但是当我运行这个脚本时,我遇到了“没有这样的文件或目录”错误

这是我写的剧本:

#!/bin/bash
while read line  
do
IN=$line
set -- "$IN"
IFS=":"; declare -a Array=($*)
echo "File location : ${Array[1]}"
location=${Array[1]}
echo "Location : $location"
cd "$location"
echo "Pwd :"
pwd
done < location.properties
输出:

File location : ~/Downloads  
Location : ~/Downloads  
./script.sh: line 10: cd: ~/Downloads: No such file or directory  
Pwd :  
/home/path/to/current/dir
两条echo语句都正确打印了位置,但cd到位置失败。
感谢您的帮助!提前谢谢

~
不会用引号展开。我通常建议将其视为一种交互式功能,并且在脚本中不可用,因为脚本中未引用的扩展带来的副作用不值得这样做

要自己执行此扩展步骤,请执行以下操作:

if [[ $location = "~/"* || $location = "~" ]]; then
  location=$HOME/${location#"~"}
elif [[ $location = "~"?* ]]; then
  user=${location%%/*}
  user=${user#"~"}
  read _ _ _ _ _ home _ < <(getent passwd "$user")
  location="$home/${location#*/}"
fi
if[[$location=“~/”*||$location=“~”];然后
位置=$HOME/${location#“~”}
elif[$location=“~”?*];然后
用户=${location%%/*}
user=${user#“~”}

阅读<删除$location周围的引号(正如其他注释所建议的那样),或者,如果出于某种原因需要引号,请在命令前面加上“eval”,如: 评估cd“$位置”
我刚刚尝试了eval方法(在~~周围加上引号),它很有效。

“只有在~'未加引号时才应用波浪展开。”顺便说一句--
Array=($*)
非常糟糕。如果您想保留带有引号/转义空格、通配符等的参数,您可能需要
Array=(“$@”)
。如果您有任何理由将内容复制到单独的数组中,我在这里没有看到。顺便问一下,您的shell是什么?我一直在假设一个兼容POSIX的ksh派生,但是如果它是非POSIX的东西,比如zsh,这可能会改变一些事情。如果你想在冒号上将行分割成一个数组,正确的方法是:
IFS=:read-r-a array+1,用于扩展~user,并用于注释overkill!我使用了这个,但仍然得到相同的错误。错误:script.sh:line 21:cd:$HOME/Downloads:没有此类文件或directory@Malick所以这意味着,
$HOME
未展开时发出。我在这里给出的确切代码并不能做到这一点。您是否在“$HOME”
周围使用了单引号?事实上,它必须是无引号的(这是安全的,因为它是赋值的一部分)或双引号的。@Malick,……此外,如果它是通过cron守护程序、at守护程序运行的,或者其他没有得到环境变量完全补充的东西运行的,请确保它有一个HOME。也就是说,这个bug不会导致您在这里描述的问题,因为它只会导致值扩展为零(并且是
/Downloads
)。@Malick:我已经在本地测试了这个问题,完全按照给定的方式,我正确地获得了
/home/myusername//Downloads
。有点过度:删除斜杠,但完全可行。eval方法将以相同的方式在相同的位置中断,就像删除引号一样。尝试使用包含空格的文件名执行此操作……另外,请参阅BashFAQ#48有关
eval
的风险:
if [[ $location = "~/"* || $location = "~" ]]; then
  location=$HOME/${location#"~"}
elif [[ $location = "~"?* ]]; then
  user=${location%%/*}
  user=${user#"~"}
  read _ _ _ _ _ home _ < <(getent passwd "$user")
  location="$home/${location#*/}"
fi