如何声明变量名等于目录中的文件名和变量值等于文件的内容?

时间:2017-02-04 00:55:57

标签: bash shell

我在文件夹中有一些文件,每个文件中的内容为4位数字。如何在bash中使用循环导出变量name=filename及其value=filecontent

1 个答案:

答案 0 :(得分:4)

这很简单。

#!/bin/bash
dir="."
for file in "$dir"/*
do
  [[ -f "$file" ]] || continue
  var="${file##*/}"
  if
    printf -v "$var" "$(<"$file")" 2>/dev/null
  then
    export "$var"
  else
    echo "Invalid filename: $file"
  fi
done

并非所有文件名都是有效的变量名。您需要100%确保您使用脚本的所有文件都具有有效变量名称,或者(最好)执行某种测试或错误处理。上面的脚本会检测到失败的作业,但除了抱怨之外不会做任何巧妙的事情。

一些解释......

如果文件不是常规文件(即目录,则跳过特殊文件),则跳过循环体。

代码使用-v的{​​{1}}选项,这会导致printf分配一个提供名称的值,而不是打印到stdout。这比不正确地使用printf更安全,这会打开代码注入的可能性,特别是考虑到你使用的是脚本无法控制的文件名。

eval语句是一个输出文件内容的命令替换,就像生成字符串而不是流的重定向一样。

最后,请注意,如果您想要"$(<"$file")"变量来准备您的脚本将要执行的其他操作,那么您没问题。但是,如果要将这些变量导出到调用脚本的shell,则需要使用export(或.)执行脚本,因为子进程永远不能导出(或进行任何操作)对其父变量的赋值)。 Sourcing使shell在不启动子进程的情况下从所述文件中读取命令。