【发布时间】:2018-06-19 01:15:33
【问题描述】:
我有一个下面的脚本,它迭代所有机器并远程检查每台机器:
- 特定目录是否存在?
- 该目录中是否存在所有 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
【问题讨论】:
-
顺便说一句,
array=( $(...) )通常来说是一种代码气味——除非你小心,否则它很容易在本地扩展看起来像 glob 的东西,和/或在文件名包含空格时将它们拆分为多个元素.几乎总是更适合做类似while IFS= read -r line; do array+=( "$line" ); done < <(...)的事情; 尤其是如果您可以用 NUL 分隔您的流并因此使用IFS= read -r -d '' line。 -
SFTP 协议比普通 ssh 更适合访问远程文件。不幸的是,OpenSSH
sftp命令行实用程序不太适合自动化。如果您知道 python、perl 等,那么您应该考虑使用其中一种语言实现它,使用 SFTP 库。