通过不使用 SSH 的 SFTP 删除子目录中超过一周的文件
Delete files in subdirectories via SFTP without SSH which are older than a week
上下文
目前我正在将数据推送到 SFTP 服务器,其他进程和系统将用于进一步的东西。所有文件共享一个根文件夹,但它们根据特定类别细分为子文件夹。此文件夹结构不得更改,也不能更改。一段时间后(目前是 7 天)我需要自动删除这些文件。
不幸的是,服务器有严格的访问权限,我只能通过SFTP访问特定目录; SSH等是禁止的。这种自动化过程的挑战在于这些限制:
- 仅SFTP-协议
- 不允许更改任何文件夹逻辑;新旧文件需要共享相同的目录
- SFTP-命令必须从 CRON-作业发出。因此,SFTP-命令需要作为一行处理。
- SFTP 服务器
上不能installed/changed
到目前为止,我知道我可以通过这种方式一次性删除文件:
echo "rm $_file_name" | sftp $username@$sftp_server
然而,我最纠结的问题是在一行中读取 SFTP 服务器上的文件并按日期标准过滤此输出。
问题
如何实现 CRON 作业,仅通过 SFTP 删除目录中超过一周的文件?
注意:我知道像 here and 这样的问题;无论如何,这些都没有我的局限性。
一段时间后,我在逐步学习过程中找到了解决方案:
第 1 步:检索所有子目录
首先我需要获取存储文件的所有目录。
假设所有相关目录都是 \IN
的子目录,我的解决方案是获取该信息的 String
-return 并遍历拆分的 `String.
# Get the string the sftp-command returns for listing all directories in /IN.
sftp_dirs=$(echo $(echo ls | sftp $username@$sftp_server:/IN))
# Then erase the log-information from that string sftp appends to it.
# This leaves a string which can be split in order to iterate over it.
process_dirs="${sftp_dirs/'Changing to: /IN sftp> ls '/}"
# Now iterate over each directory and retrieve the files.
for _dir in $(echo $process_dirs | tr " " "\n")
do
# Fill in Step2
done
第 2 步:检索所有文件及其创建日期
SFTP 服务器上的文件创建时间戳是我将文件推送到服务器的日期。因此,获取在服务器上存储超过7天的文件可以通过创建时间来识别。
这里的挑战是从 SFTP 的回显输出中检索此信息。由于我拥有在服务器 运行 CRON 作业上安装我需要的所有必要权限,因此我使用了 LFTP
的帮助,因为我无法使用纯 SFTP 来完成。
最后,解决方案是从 LFTPs 输出中读取一个数组。
# Returns an array with all files stored in $_dir with their respective timestamps.
# $_dir is the loop-variable from Step 1
readarray -t _files <<< "$(lftp -u $username, sftp://$sftp_server:/IN/$_dir -e "cls -B --date --time-style long-iso; exit")"
请注意,我将时间戳配置为 long-iso
以便进一步处理。
因此,现在遍历所有文件以识别超过 7 天的文件,例如:
for _file in "${_files[@]}"
do
# Fill in Step3
done
第 3 步:检索并删除旧文件
这里直截了当的代码:
# Get the files date in the desired date format
# (remember that long-iso was chosen in Step 2)
# _file is the loop-variable from Step 2
_file_date=$(date -d "${_file:0:10}" +%s)
_file_name="/IN/"$_dir"/"${_file:17}
# Compare the date-difference
deletion_date=$(date -d 'now - 7 days' +%s)
_datediff=$(( (_file_date - deletion_date) / 86400 ))
最后,如果datediffs结果显示文件早于7天,删除它
if [ $_datediff -lt 0 ]
then
# Pass the file to sftp and issue the delete command.
echo "rm $_file_name" | sftp $username@$sftp_server
fi
上下文
目前我正在将数据推送到 SFTP 服务器,其他进程和系统将用于进一步的东西。所有文件共享一个根文件夹,但它们根据特定类别细分为子文件夹。此文件夹结构不得更改,也不能更改。一段时间后(目前是 7 天)我需要自动删除这些文件。
不幸的是,服务器有严格的访问权限,我只能通过SFTP访问特定目录; SSH等是禁止的。这种自动化过程的挑战在于这些限制:
- 仅SFTP-协议
- 不允许更改任何文件夹逻辑;新旧文件需要共享相同的目录
- SFTP-命令必须从 CRON-作业发出。因此,SFTP-命令需要作为一行处理。
- SFTP 服务器 上不能installed/changed
到目前为止,我知道我可以通过这种方式一次性删除文件:
echo "rm $_file_name" | sftp $username@$sftp_server
然而,我最纠结的问题是在一行中读取 SFTP 服务器上的文件并按日期标准过滤此输出。
问题
如何实现 CRON 作业,仅通过 SFTP 删除目录中超过一周的文件?
注意:我知道像 here and
一段时间后,我在逐步学习过程中找到了解决方案:
第 1 步:检索所有子目录
首先我需要获取存储文件的所有目录。
假设所有相关目录都是 \IN
的子目录,我的解决方案是获取该信息的 String
-return 并遍历拆分的 `String.
# Get the string the sftp-command returns for listing all directories in /IN.
sftp_dirs=$(echo $(echo ls | sftp $username@$sftp_server:/IN))
# Then erase the log-information from that string sftp appends to it.
# This leaves a string which can be split in order to iterate over it.
process_dirs="${sftp_dirs/'Changing to: /IN sftp> ls '/}"
# Now iterate over each directory and retrieve the files.
for _dir in $(echo $process_dirs | tr " " "\n")
do
# Fill in Step2
done
第 2 步:检索所有文件及其创建日期
SFTP 服务器上的文件创建时间戳是我将文件推送到服务器的日期。因此,获取在服务器上存储超过7天的文件可以通过创建时间来识别。
这里的挑战是从 SFTP 的回显输出中检索此信息。由于我拥有在服务器 运行 CRON 作业上安装我需要的所有必要权限,因此我使用了 LFTP
的帮助,因为我无法使用纯 SFTP 来完成。
最后,解决方案是从 LFTPs 输出中读取一个数组。
# Returns an array with all files stored in $_dir with their respective timestamps.
# $_dir is the loop-variable from Step 1
readarray -t _files <<< "$(lftp -u $username, sftp://$sftp_server:/IN/$_dir -e "cls -B --date --time-style long-iso; exit")"
请注意,我将时间戳配置为 long-iso
以便进一步处理。
因此,现在遍历所有文件以识别超过 7 天的文件,例如:
for _file in "${_files[@]}"
do
# Fill in Step3
done
第 3 步:检索并删除旧文件
这里直截了当的代码:
# Get the files date in the desired date format
# (remember that long-iso was chosen in Step 2)
# _file is the loop-variable from Step 2
_file_date=$(date -d "${_file:0:10}" +%s)
_file_name="/IN/"$_dir"/"${_file:17}
# Compare the date-difference
deletion_date=$(date -d 'now - 7 days' +%s)
_datediff=$(( (_file_date - deletion_date) / 86400 ))
最后,如果datediffs结果显示文件早于7天,删除它
if [ $_datediff -lt 0 ]
then
# Pass the file to sftp and issue the delete command.
echo "rm $_file_name" | sftp $username@$sftp_server
fi