windows - 为什么我的 IF 比较运算失败?

标签 windows batch-file for-loop if-statement call

更新 已解决 - 问题不在我的代码中。命令处理器中存在设计限制(有些人可能会说“错误”)。 IF 比较运算符不适用于高于 2147483648 的值。现在我只需要弄清楚如何去除一些最低有效数字的解决方法。感谢大家的阅读。

=======

你好,在赛博世界,

我管理一家小公司的网络。我正在尝试使用在服务器上运行的批处理文件来设置自动归档过程,并且需要一些逻辑方面的帮助。我不是程序员,也没有时间学习 PowerShell 或 VBscript。我已经阅读并重新阅读了有关 IF、FOR 和 CALL 的 MS 命令引用,但无法弄清楚我做错了什么。

我们有一个带有两个磁盘驱动器和一个磁带驱动器的 Windows 2000 Server。一个磁盘有一个共享文件夹,称之为公共(public);另一个磁盘不共享,称之为暂存。

公共(public)驱动器将接受来自客户端桌面的传入备份。我需要将文件从公共(public)驱动器移动到暂存驱动器的过程,直到驱动器太满而无法再接受任何文件,于是磁带备份开始。磁带运行完成后,临时驱动器将被清空,该过程将恢复将文件从公共(public)文件移动到临时文件。

目标是自动和永久地将桌面备份文件存档到磁带,除了更换磁带外无需用户干预。

您可能会问,为什么涉及两个驱动器?两个原因:

1) 如果桌面直接备份到暂存驱动器,有时客户端桌面备份会因目标驱动器空间不足而失败。我无法预测这种情况何时会发生;我能想到的唯一可定义条件是可用磁盘空间的任意阈值,但由于要存档的备份文件大小不同,我可能会遇到目标驱动器可用空间高于阈值的情况,但下一个备份超过该空间。结果:客户端桌面备份失败,服务器磁带备份不启动。

2) 如果暂存驱动器已满并且磁带备份由于某种原因(磁带未更改或其他原因)失败,将桌面备份到公共(public)驱动器可以给我一些时间在桌面备份开始之前解决磁带问题失败。

这是我尝试编码的算法:

1)开始

2) 获取临时驱动器上的可用空间

3) 获取公共(public)驱动器上最小文件的大小(如果不存在文件,则退出)

4) 将文件大小与暂存驱动器上的可用空间进行比较

5) 如果文件适合,将其移动到暂存驱动器;否则,退出并开始磁带备份

6) 回到开始

这是我的批处理代码,它不起作用。在测试的这个阶段,我在公共(public)驱动器中有一个文件 (8 GB),它将适合暂存驱动器上的可用空间 (32 GB)。 set 命令确认变量正在按预期设置;该过程在语句 [ if %BKFsize% LSS %DiskFree%"] 处失败。不是移动文件,而是调用“else”指定的磁带例程:

@echo off
setlocal enableextensions enabledelayedexpansion
:Begin
REM   obtain and display free space on Staging drive.
D:
for /f "tokens=3 delims= " %%A in ('dir ^| find "bytes free"') do (
set Z=%%A
set Z=!Z:,=!
)
set DiskFree=!Z!
echo.
echo D: has %DiskFree% bytes free
echo.
REM   obtain sizes of files on Public drive to be moved.
E:
cd \backup.email
if not exist *.bkf exit
dir *.bkf /b /os > BKFlist.txt
for /f "tokens=*" %%G in (BKFlist.txt) do call :CheckBKF "%%G"
goto :eof
:CheckBKF
set BKFfile=%1
set BKFsize=%~z1
echo.
echo File %BKFfile% is %BKFsize% bytes
echo.
set
pause
REM   move file(s) to Staging drive, space permitting; or, 
REM   if not enough space for smallest file, start tape backup.
if %BKFsize% LSS %DiskFree% (
echo Moving file %BKFfile% to drive D
echo.
move E:\backup.email\%BKFfile% D:\backup.email
) else (
C:\WINNT\AutoBackup\TapeBKF.cmd
exit
)
goto Begin
:End

我知道这一定很简单,但就像我说的,我不是程序员,我对你的高超技能表示敬意。非常感谢任何建议,谢谢。

最佳答案

在批处理文件中,字符串和整数类型之间没有真正的区别,但这不是您的问题。

问题是整数只能在 32 位有符号范围内工作。
-2147483648 至 2147483647

但是您的文件更大,磁盘空间也更大。 要对此进行测试,您可以尝试添加一个。

Set /a myvar=BKFsize+1
Set /a myvar=DiskFree+1

我想你遇到了一个错误。

你可以解决这个问题,如果你尝试使用字符串比较,目前你在进行字符串比较,但你的数字长度不同,所以你会得到“不可预测”的结果。
但是如果你用零调整/填充字符串使它们具有相同的长度,它应该可以工作。

set "strBKSize=000000000000000000%bkSize%"
set "strBKSize=%strBKSize:~-15%"
set "strDisksize=000000000000000000%Disksize%"
set "strDisksize=%strDisksize:~-15%"

或者您尝试通过删除 6 或 9 个数字/字符而不是字节,而是以 MB 或 GB 为单位进行计算。

set BKFsizeGB=%BKFsize:~0,-9%

然后您可以将它们用作数字。

关于windows - 为什么我的 IF 比较运算失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5437185/

相关文章:

c++ - 将 Windows 上的文件共享用于数据库时,它的可靠性如何?

c++ - 我可以在低级 Hook 过程中区分触摸板和鼠标消息吗? (Win32)

windows - 列出cmd中的所有文件夹和子文件夹,但不包括文件

windows - 想要将 4 个用户输入传递给 Windows 批处理文件中的 4 个 SET 命令

regex - 从批处理文件中的字符串中提取数字

ruby - 如何通过 Ruby 在 Windows 上创建符号链接(symbolic link)?

string - “for” -statement上的批处理语法错误

java - 递归搜索错误

c# - 索引超出数组范围 - For 循环

linux - 如何使用fprintf在matlab中多次输出一个字符到一个文件