Unix/Bash比较来自远程服务器的文件

t40tm48m  于 2022-11-23  发布在  Unix
关注(0)|答案(1)|浏览(321)

我更新了下面的代码,并创建了一个单独的变量用于时间比较。但是,即使在变量后面设置了循环,它仍然没有比较第二个文件。
我正在尝试远程比较多台服务器上的文件的最后更新时间

ssh -q -l user svr "ls -ltr /path/to/file/svr.log | tail -n1"

它返回这个输出,这就是我想要的。

-rwxr-xr-x 1 user user 1658367654 Jul 21 01:40 /path/to/file/svr.log

所以我对其余的服务器也做了同样的操作。我需要统计它们以获得最后修改的日期,并检查最后更新的时间阈值

#!/bin/bash
set -x
s11=$(ssh -q -l user svr1 "find /path/to/log/svr.log -printf '"%T+ %p"' | sort")
s12=$(ssh -q -l user svr2 "find /path/to/log/svr.log -printf '"%T+ %p"' | sort")
s11r=$(echo $s11 | awk '{print $2}')
s12r=$(echo $s12  | awk '{print $2}')

for myservers in $s11r $s12r;
do
OLDTIME=1200 #20 minutes file threshold
FILETIME=$(stat -c %Y "${myservers}")
CURTIME=$(perl -e 'print time')
TIMEDIFF=$(($CURTIME - $FILETIME))

if [[ $TIMEDIFF -gt $OLDTIME ]]; then
echo -e "$myservers: old time"
else
echo "$myservers: all good"
fi
done

输出如下

++ ssh -q -l user svr1 'find /path/to/log/svr.log -printf '\''%T+' '%p'\'' | sort'
+ s11='2022-07-21+03:09:19.3550802140 /path/to/log/svr.log'
++ ssh -q -l user svr2 'find /path/to/log/svr.log -printf '\''%T+' '%p'\'' | sort'
+ s12='2022-07-21+03:25:53.3758441030 /path/to/log/svr.log'
++ echo 2022-07-21+03:09:19.3550802140 /path/to/log/svr.log
++ awk '{print $2}'
+ s11r=/path/to/log/svr.log
++ echo 2022-07-21+03:25:53.3758441030 /path/to/log/svr.log
++ awk '{print $2}'
+ s12r=/path/to/log/svr.log
+ for myservers in '$s11r' '$s12r'
+ OLDTIME=1200
++ stat -c %Y /path/to/log/svr.log
+ FILETIME=1658381370
++ perl -e 'print time'
+ CURTIME=1658381855
+ TIMEDIFF=485
+ [[ 485 -gt 1200 ]]
+ echo '/path/to/log/svr.log: all good'
/path/to/log/svr.log: all good
+ for myservers in '$s11r' '$s12r'
+ OLDTIME=1200
++ stat -c %Y /path/to/log/svr.log
+ FILETIME=1658381370
++ perl -e 'print time'
+ CURTIME=1658381855
+ TIMEDIFF=485
+ [[ 485 -gt 1200 ]]
+ echo '/path/to/log/svr.log: all good'
/path/to/log/svr.log: all good

根据输出,它执行了该作业,但只处理服务器1的日志文件,而忽略服务器2。即使所有服务器都有更新的文件,但它们的大小并不相同。
需要以下方面的帮助
1.如何使其处理所有服务器
1.如果1个文件已更新,如何跳过服务器检查比较
谢谢你,谢谢你

6ioyuze2

6ioyuze21#

以下是此问题的解决方案:
我正在尝试远程比较多台服务器上的文件的最后更新时间

如何

  • 检查该文件的stat和**修改:**时间
  • 将时间转换为秒
  • 比较秒数

我将测试SSHing正在更新的/var/log/auth.log文件。

脚本

# host names
HOST_1=docker
HOST_2=irj

# SHH to host and stat a file
declare -ir HOST_1_TIME=$(ssh $HOST_1 "stat -c %Y /var/log/auth.log");
declare -ir HOST_2_TIME=$(ssh $HOST_2 "stat -c %Y /var/log/auth.log");

# print
echo HOST_1_TIME: $HOST_1_TIME
echo HOST_2_TIME: $HOST_2_TIME
echo diff: $(( $HOST_1_TIME - $HOST_2_TIME ));

# check which was access first
if (( $HOST_1_TIME < $HOST_2_TIME )); then
    echo "HOST_1: $HOST_1 logged in first"
else
    echo "HOST_2: $HOST_2 logged in first"
fi

示例输出

HOST_1_TIME: 1658414665
HOST_2_TIME: 1658414666
diff: -1
HOST_1: docker logged in first

如果我们交换主机

declare -ir HOST_2_TIME=$(ssh $HOST_2 "stat -c %Y /var/log/auth.log");
declare -ir HOST_1_TIME=$(ssh $HOST_1 "stat -c %Y /var/log/auth.log");

示例输出

HOST_1_TIME: 1658414653
HOST_2_TIME: 1658414651
diff: 2
HOST_2: irj logged in first

注记

  • find不用于对文件进行查询:find /path/to/log/svr.log
  • 如果您输出超过一行,请将其保存在数组中--您可以使用mapfile -t array_name < <(your-cmd)
  • 您可能希望以如下方式使用find -printf-printf '%T+ %p\n'-缺少\n换行符

更干净的方式

#!/bin/bash

declare -a servers=(docker irj);
declare -A stat_time;

for server in ${servers[*]}; do
    stat_time[$server]=$(ssh $server "stat -c %Y /var/log/auth.log");
done

for server in ${servers[*]}; do
    printf "%-20s %s\n" stat_time[$server]: ${stat_time[$server]};
done

示例输出

stat_time[docker]:   1658415177
stat_time[irj]:      1658415179

如果有多个单个文件(多个文件)

#!/bin/bash

declare -r server=docker

# save list of files and their time in an array
mapfile -t files < <(ssh $server "find -maxdepth 1 -type f -printf '%T+@%p\n'");

OLDIFS=$IFS
IFS='@'
for file in "${files[@]}"; do
    # extra time and filename
    read _time _filename <<< "$file";

    printf "time: %s and filename: %s\n" $_time "$_filename";
done

echo

for file in "${files[@]}"; do
    # extra time and filename
    read _time _filename <<< "$file";

    # extract valid format for date --date
    _time=$(sed 's/+/ /' <<< $_time);

    # cover time to seconds
    _time=$(date --date $_time +%s);
    printf "time(seconds): %s and filename: %s\n" $_time "$_filename";
done
IFS=$OLDIFS

示例输出

time: 2022-07-21+05:35:28.1242915540 and filename: ./.viminfo
time: 2022-05-17+08:59:32.3547403750 and filename: ./.cloud-locale-test.skip
time: 2022-07-10+10:06:06.3498292130 and filename: ./.lesshst
time: 2022-07-21+15:09:39.1537378410 and filename: ./.bash_history
time: 2022-07-19+14:12:51.0595533570 and filename: ./.bashrc
time: 2022-07-21+08:54:02.6645262280 and filename: ./.gitconfig
time: 2022-07-19+05:45:24.5526313330 and filename: ./.vimrc
time: 2019-12-05+14:39:21.0000000000 and filename: ./.profile
time: 2022-07-19+13:33:53.2693524620 and filename: ./.wget-hsts

time(seconds): 1658365528 and filename: ./.viminfo
time(seconds): 1652761772 and filename: ./.cloud-locale-test.skip
time(seconds): 1657431366 and filename: ./.lesshst
time(seconds): 1658399979 and filename: ./.bash_history
time(seconds): 1658223771 and filename: ./.bashrc
time(seconds): 1658377442 and filename: ./.gitconfig
time(seconds): 1658193324 and filename: ./.vimrc
time(seconds): 1575544161 and filename: ./.profile
time(seconds): 1658221433 and filename: ./.wget-hsts

相关问题