远程检查linux中是否存在所有文件?

时间:2018-01-09 22:46:28

标签: linux bash unix ssh

我有一个下面的脚本,它迭代所有机器并远程检入每台机器:

  • 是否有特定目录?
  • 所有2000个文件都存在于该目录中。

以下是代码:

for machine in "${MACHINES[@]}"; do
   dircheck=($(ssh -o "StrictHostKeyChecking no" user@${machine} [[ ! -d "$dir3" ]] \&\& exit 1 \; ls -t1 "$dir3"))
   if [[ $? != 0 ]] ;then
       echo "Folder $dir3 doesn't exist on $machine" >&2
       exit 1
   fi

    # this is for checking all the 2000 files
    # this check is very slow when it checks all 2000 files
    for el in ${FILES[@]}
    do
        printf -v cmd '%q ' test -e "$dir3/process_${el}.log"
        ssh user@${machine} "$cmd" \
        || { echo "File number $el missing on $machine." >&2;
             exit 1; }
    done
done

现在的问题是检查所有2000个文件需要花费很多次,所以想看看我们是否有任何方法可以做同样的事情,但有点快?

更新

总的来说,我的脚本将是这样的:

readonly MACHINES=(machineA machineB machineC)
readonly dir3=/some_path
echo $dir3
FILES=({0..1999})

checkFunc() {
  test -d "$dir3" || echo "NODIR"

  local filename successCount=0
  while IFS= read -r filename; do
    test -e "$dir3/process_${filename}.log" && (( ++successCount ))
  done
  printf '%s\n' "$successCount"
}

for machine in "${MACHINES[@]}"; do
    actual=$(
      printf '%s\0' "${FILES[@]}" | \
        ssh "$machine" "$(declare -p dir3; declare -f checkFunc); checkFunc"
    ) || { echo "ERROR: Unable to retrieve remote file count" >&2; exit 1; }

    case $actual in
      (${#FILES[@]}) echo "SUCCESS: Expected, and found, $numberOfActuallyRemoteFiles files" ;;
      (NODIR)        echo "FAILURE: Directory $dir3 does not exist" ;;
      (*)            echo "FAILURE: Out of ${#FILES[@]} files, only $actual exist" ;;
    esac
done

1 个答案:

答案 0 :(得分:3)

不是创建2,000个单独的SSH连接,而是将整个循环推送到远程端:

# shell function which reads a NUL-delimited list of filenames on stdin
# and returns the number of them that actually exist on stdout, or "NODIR"
checkFunc() {
  test -d "$dir3" || { echo "NODIR"; return; }

  local filename successCount=0
  while IFS= read -r -d '' filename; do
    test -e "$dir3/process_${filename}.log" && (( ++successCount ))
  done
  printf '%s\n' "$successCount"
}

actual=$(
  printf '%s\0' "${FILES[@]}" | \
    ssh "$machine" "$(declare -p dir3; declare -f checkFunc); checkFunc"
) || { echo "ERROR: Unable to retrieve remote file count" >&2; exit 1; }

case $actual in
  (${#FILES[@]}) echo "SUCCESS: Expected, and found, $numberOfActuallyRemoteFiles files" ;;
  (NODIR)        echo "FAILURE: Directory $dir3 does not exist" ;;
  (*)            echo "FAILURE: Out of ${#FILES[@]} files, only $actual exist" ;;
esac

请注意,declare -p dir3declare -f checkFunc会发出字符串,当由bash执行时,它们将分别定义dir3变量或checkFunc函数。