美元的符号词文件读书和分配给变量

时间:2017-03-28 16:36:50

标签: linux shell

这是我的文字档案:

└─ $ ▶ cat myfile.txt
$FLD,abc
$FLD,xyz
$TRA,yyt

这是我的环境变量:

└─ $ ▶ echo $FLD
/Users
└─ $ ▶ echo $TRA
/opt

我想要做的是从文件中获取环境变量本身,然后将目录更改为该目录,并在文件的第2列中执行命令。

└─ $ ▶ cat myscript.sh
IFS=","
while read f1 f2
do
target_folder=`echo $f1`
target_path=$f2
echo "It is going to be executed $target_path file in $target_folder folder"
cd $target_folder
done < myfile.txt

由于美元符号自动转义,我无法更改文件夹并收到此错误:

└─ $ ▶ sh myscript.sh
It is going to be executed abc file in $FLD folder
myscript.sh: line 7: cd: $FLD: No such file or directory
It is going to be executed xyz file in $FLD folder
myscript.sh: line 7: cd: $FLD: No such file or directory
It is going to be executed yyt file in $TRA folder
myscript.sh: line 7: cd: $TRA: No such file or directory

这种情况类似:

└─ $ ▶ var1=$FLD
└─ $ ▶ var2=\$FLD
└─ $ ▶ cd $var1
└─ $ ▶ cd $var2
-bash: cd: $FLD: No such file or directory

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

虽然原则上使用 eval ,但出于安全原因,通常应避免使用 例如,您的文件的第1列可以包含任意命令 eval然后盲目执行。

根据您问题中的错误消息,我推断您使用bash ,这允许使用与运算符=~的扩展正则表达式匹配和间接变量扩展获得强大而安全的解决方案:

while IFS=',' read -r f1 f2
do
  target_folder=$f1
  # Only try to expand the value if it starts with '$' and is followed by
  # a legal variable name, and nothing else.
  if [[ $target_folder =~ ^\$([_a-zA-Z][a-zA-Z0-9]*)$ ]]; then
    # Use variable indirection to get the variable's value.
    vname=${BASH_REMATCH[1]}
    target_folder=${!vname}
  fi
  target_path=$f2
  echo "Executing file $target_path in folder $target_folder..."
  cd "$target_folder"
done < myfile.txt
  • 请注意,Bash的variable indirection仍为allows injection of arbitrary commands,通过数组索引,因此需要首先测试$target_folder的值。

  • 另请注意在IFS=','命令之前直接使用read,该命令将更改范围限定为该命令,而不会全局更改$IFS的值。

  • 此外,-r几乎总是与read一起使用的正确选项,以防止对\字符的意外解释。在输入中。

符合POSIX的解决方案也是可能的,但在这种情况下,它需要使用外部实用程序来测试有效的变量名称sed

while IFS=',' read -r f1 f2
do
  target_folder=$f1
  # Only try to expand the value if it is '$' followed by
  # a legal variable name, and nothing else.
  if [ -n "$(printf %s "$target_folder" | sed -n '/^\$[_a-zA-Z][a-zA-Z0-9]*$/p')" ]; then
    # Given that we've ensured that $target_folder contains a valid variable reference,
    # we can now use `eval` safely.
    target_folder=$(eval "printf %s \"$target_folder\"")
  fi
  target_path=$f2
  echo "Executing file $target_path in folder $target_folder..."
  cd "$target_folder"
done < < myfile.txt

请注意,即使使用eval(变量间接不是POSIX shell规范的一部分),在这种情况下它的使用是安全的,因为我们确保要评估的字符串是只是一个变量引用。

答案 1 :(得分:0)

试试这个:

IFS=","
while read f1 f2
do
    target_folder=$f1
    target_path=$f2
    eval "cd "$target_folder
done < myfile.txt