Shell脚本循环从另一个文件调用函数,找不到命令。语法错误?

时间:2014-06-11 06:57:59

标签: linux bash shell

我有这个文件正在执行其他文件中的函数:

#!/bin/sh

for ABC in dir.d/*; do

   . $ABC

   echo -n "Checking for $ABC..."

   if ${ABC}_find; then
      echo "yes"
      ${ABC}_download
      ${ABC}_cleanup
      break
   else
      echo "no"
      ${ABC}_cleanup
   fi
done

和dir.d目录中的文件是 文件名:一个

#!/bin/sh

one_find() {
echo "one found"
}

one_download() {
echo "one downloaded"
}

one_cleanup() {
echo "one removed"
}
对于文件名为2的文件,

相同

#!/bin/sh

two_find() {
echo "two found"
}

two_download() {
echo "two downloaded"
}

two_cleanup() {
echo "two removed"
}

我得到以下输出:

检查dir.d / one .... / myfile.sh:13:./myfile.sh:dir.d/one_find:not found 没有 ./myfile.sh:20:./myfile.sh:dir.d/one_cleanup:not found

我试图谷歌,但没有解决我的问题。我是shell的新手,这是我在SO中的第一个问题。更多细节:

1.我无法重命名文件,文件名必须与函数名称匹配(在_之前)

2.我需要在循环中导入,因为dir.d中可能有数百个文件就像一个和两个

编辑: 这些文件是项目的一部分。我正在使用git,我使用notepad ++在Windows中部分编码,部分在Linux(Ubuntu 12.04)中使用nano / gedit进行编码。我正在从Windows和Linux上复制一些代码(我的Ubuntu是在VMware的另一个窗口中运行的虚拟机)。它无论如何会影响代码吗?

2 个答案:

答案 0 :(得分:1)

您的问题是您添加dir.d两次。

一定是

for ABC in dir.d/*; do
   . $ABC
done

你写的

for ABC in dir.d/*; do
   . dir.d/$ABC
done

这显然是错误的。

<强>更新

另外,做

是错误的
if ${ABC}_find; then

因为dir.d/one中有ABC。 您必须关闭dir.d

另一种选择:首先cd$ABC,然后迭代其内容。 在这种情况下,$ ABC将保留文件的唯一名称。

cd dir.d
for ABC in *
do
  if ${ABC}_find
  then
  ...
  fi
done

更新2

只是为了100%确定我刚刚用我的建议检查了你的脚本:

for abc in dir.d/*; do
 . $abc
 ABC=${abc#*/}

 echo -n "Checking for $ABC..."

 if ${ABC%*/}_find; then
  echo "yes"
  ${ABC}_download
  ${ABC}_cleanup
  break
 else
  echo "no"
  ${ABC}_cleanup
 fi
done

执行结果:

$ sh 1.sh 
Checking for one...one found
yes
one downloaded
one removed

答案 1 :(得分:0)

我以这种方式修复它:

#!/bin/sh

for FILE in dir.d/*; do
   . "$FILE"

   ABC=${FILE##*/}

   echo -n "Checking for $ABC..."

   if "${ABC}_find"; then
      echo "yes"
      "${ABC}_download"
      "${ABC}_cleanup"
      break
   else
      echo "no"
      "${ABC}_cleanup"
   fi
done

此外,最好为您的下标提供.sh扩展名:

for FILE in dir.d/*.sh; do
   . "$FILE"

   ABC=${FILE##*/}; ABC=${ABC%.sh}

当您进入更大的模块化项目时,您也可以考虑像Shell Script Loader这样的框架解决方案。还要检查Bash 4.0 + here的保守概念脚本。