什么是jhove?
Oleg Nekhayenko,你问在最后的日子几个jhove
相关的问题,但你总是忘了解释什么jhove
是要知道你的所有问题是非常重要的。
所以我搜索万维网为jhove
,发现很快主页
JHOVE | JSTOR/Harvard Object Validation Environment,快速阅读其documentation和command-line interface描述,最后下载也jhove-1_11.zip从JHOVE SourceForge项目页面。
这一切都被我做找出jhove
是使用shell脚本jhove
在Linux上执行,或许也可以在Mac和Windows上的批处理文件jhove.bat
为了更容易被用户使用Java应用程序。
你可以救自己和您的问题所有的读者很多的时间,如果你会在你的代码片段已经写jhove.bat
,而不是只jhove
或者任何地方至少提到jhove
是一个批处理文件。
分配值/字符串变量
我建议先读这两行上
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
的答案,接下来看看环境:
set "input=C:\Users\NekhayenkoO\test\"**
set "output=C:\Users\NekhayenkoO\outputxml\"**
我不知道为什么两个星号在这两条命令行的末尾。但是,这并不重要,因为在将两个路径分配给两个环境变量时,两个星号都会被忽略。
这可以在批处理文件的发布输出被视为有上线没有星号输出:
for /F %a in ('dir /b /a-d /s "C:\Users\NekhayenkoO\test\"') do (
CALL jhove -m PDF-hul -h xml -o "C:\Users\NekhayenkoO\outputxml\\757419577.xml" "C:\Users\NekhayenkoO\test\757419577.pdf"
没有星号的任何地方。所以环境变量input
和output
显然没有星号,最终在这里甚至是好的。
在双引号封闭目录和文件名
在命令提示符窗口中运行cmd /?
帮助输出解释了最后帮助页面上的最后一段上的目录或文件名双引号字符周围必须使用完整的目录/文件名称。
空格字符是命令行上的字符串分隔字符,因此带空格的目录或文件名必须始终用双引号括起来。在Windows
预定义的环境变量打开命令提示窗口并运行set
结果在用于当前用户帐户中定义的所有的环境变量的输出,包括PATH
和PATHEXT
为还USERNAME
和USERPROFILE
。
维基百科有关Windows Environment Variables的文章解释了Windows预定义的环境变量。建议在批处理文件中使用它们。
在Windows
的应用程序和脚本执行如果在命令提示符窗口或在批处理文件中指定的只是一个应用程序或脚本没有文件扩展名,没有路径的文件名,在Windows命令解释器搜索首先在当前目录中,然后在环境变量PATH
的所有目录中对于具有在环境变量PATHEXT
中列出的文件扩展名的指定名称的文件。在这种情况下,Windows命令解释程序正在搜索jhove.*
。
环境变量PATH
和PATHEXT
的值可以看到打开命令提示窗口和运行在该窗口set path
这导致开始与不区分大小写的解释字符串PATH
与它们的当前值的所有的环境变量的输出。
要知道的是,当Windows命令解释程序搜索jhove.*
时,NTFS文件系统返回匹配此搜索模式的文件名称按字母顺序排序。因此,如果当前目录或PATH
中列出的任何目录都有例如jhove.bat
和jhove.exe
,则NTFS文件系统首先返回jhove.bat
。此批处理文件由Windows命令解释程序使用,因为文件扩展名BAT
默认在PATHEXT
中列出。
但是,如果具有jhove.*
文件的驱动器的文件系统是FAT,FAT32或ExFat,则文件系统按照存储在文件分配表中的顺序返回与搜索模式匹配的文件名,因此未排序。因此,如果某个目录包含jhove.bat
和jhove.exe
在具有任何FAT文件系统的驱动器上,则无法预知哪个文件由Windows命令解释程序在批处理文件中指定jhove
执行。
因此,总是建议使用文件名称指定应用程序或脚本,并至少使用文件扩展名。如果可能的话,还应指定要运行的应用程序的整个路径或要调用的脚本。
Windows命令解释程序不需要通过指定具有文件扩展名和完整路径的应用程序或脚本文件的名称进行搜索。
参见回答Where is "START" searching for executables?
调用一个批处理文件与由线运行由Windows命令解释行解释应用
批处理文件是一个脚本(文本文件),从而命令块开始(
并以与匹配)
结尾的方式解释为像在一行上定义的子例程。
应用程序是一个可执行文件(二进制文件),用于针对特定处理器或处理器系列的编译器进行编译,因此在执行时不需要再解释。它包含处理器指令(机器码)。
为什么命令呼叫必须用于运行从一个批处理文件中另一个批处理文件进行详细的答案上
解释了这个原因知道什么是jhove
是非常重要的。这是一个批处理文件,因此必须调用命令呼叫,回答了问题How to process 2 for loops after each other in batch?
有关命令呼叫帮助打开命令提示符窗口,然后运行call /?
。输出帮助还解释了哪些占位符存在以引用批处理文件的参数,其中参数0是批处理文件的名称。
哪些命令行包含jhove.bat?
对于从另一个批处理文件调用批处理文件时发生的意外行为,重要的是要知道调用的批处理文件的代码,因为错误可能在调用批处理文件的代码中。
的jhove.bat
代码存储在jhove-1_11.zip
没有指令评论:
@ECHO OFF
SET JHOVE_HOME=%~dp0
SET EXTRA_JARS=
REM NOTE: Nothing below this line should be edited
REM #########################################################################
SET CP=%JHOVE_HOME%\bin\JhoveApp.jar
IF "%EXTRA_JARS%"=="" GOTO FI
SET CP=%CP%:%EXTRA_JARS
:FI
REM Retrieve a copy of all command line arguments to pass to the application
SET ARGS=
:WHILE
IF %1x==x GOTO LOOP
SET ARGS=%ARGS% %1
SHIFT
GOTO WHILE
:LOOP
REM Set the CLASSPATH and invoke the Java loader
java -classpath %CP% Jhove %ARGS%
好了,这是以下原因不好写批处理代码:
命令SETLOCAL和endlocal不在批处理文件中用于控制此批处理文件使用的变量的生存时间。有关更多详细信息,请参见change directory command cd ..not working in batch file after npm install的答案。 npm.bat
也是一个不好的编码批处理文件,如jhove.bat
,因为它结果。
命令行SET JHOVE_HOME=%~dp0
定义环境变量JHOVE_HOME
,驱动器和存储位置的路径为jhove.bat
。由%~dp0
返回的路径始终以反斜杠结尾。如果jhove*.zip
被提取到一个具有一个或多个完整路径空间的目录中,则必须注意最后使用JHOVE_HOME
将最后一个字符串括在双引号中。
命令行SET CP=%JHOVE_HOME%\bin\JhoveApp.jar
通过将批处理文件jhove.bat
的路径连接到Java程序包的固定路径和名称来定义环境变量CP
。这已经是一个小错误,因为%~dp0
是一个始终以一个反斜杠和一个以反斜杠开始的串联结尾的路径。所以最终在Java包文件的路径中有两个反斜杠。但是Windows内核在路径中处理这个错误,因此它并不重要。
环境变量CP
未经修改而引用,没有EXTRA_JARS
,最终由用户在命令行java -classpath %CP% Jhove %ARGS%
上定义。如果jhove*.zip
确实被用户提取到具有一个或多个完整路径空间的目录中,则错误指定为%CP%
,而不包含在导致意外行为的双引号中。
在命令行SET CP=%CP%:%EXTRA_JARS
末尾缺少百分号。
的jhove.bat
笔者不知道%*
显然任何事情上最后一个命令行而不是%ARGS%
的使用使得WHILE
以上循环完全无用。
为jhove.bat
好多是:
@echo off
setlocal EnableExtensions
set "JHOVE_HOME=%~dp0"
set "EXTRA_JARS="
REM NOTE: Nothing below this line should be edited
REM #########################################################################
set "CP=%JHOVE_HOME%bin\JhoveApp.jar"
if not "%EXTRA_JARS%"=="" set "CP=%CP%:%EXTRA_JARS%"
rem Set the CLASSPATH and invoke the Java loader
java.exe -classpath "%CP%" Jhove %*
endlocal
可执行java.exe
必须通过由Windows命令解释器环境变量PATH
被发现。
用于使用
最终批次码
我建议使用以下代码中的jhove.bat
情况下,这任务不应该被修饰以上述工作的代码:
@echo off
setlocal EnableExtensions
set "InputFolder=%USERPROFILE%\test"
set "OutputFolder=%USERPROFILE%\outputxml"
echo Searching for bin\JhoveApp.jar in:
echo.
set "SearchPath=%CD%;%PATH%"
set "SearchPath=%SearchPath:)=^)%"
for /F "delims=" %%I in ('echo %SearchPath:;=^&ECHO %') do (
echo %%I
if exist "%%~I\bin\JhoveApp.jar" (
set "JHOVE_HOME=%%~I"
goto RunJHOVE
)
)
echo.
echo Error reported by %~f0:
echo.
echo Could not find bin\JhoveApp.jar in current directory and folders of PATH.
echo.
endlocal
pause
goto :EOF
:RunJHOVE
if "%JHOVE_HOME:~-1%" == "\" (
set "CP=%JHOVE_HOME%bin\JhoveApp.jar"
) else (
set "CP=%JHOVE_HOME%\bin\JhoveApp.jar"
)
echo.
echo Using %CP%
md "%OutputFolder%" 2>nul
rem for /F %%I in ('dir /A-D /B /S "%InputFolder%\*" 2^>nul') do (
rem java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I"
rem)
for /R "%InputFolder%" %%I in (*) do (
java.exe -classpath "%CP%" Jhove -m PDF-hul -h xml -o "%OutputFolder%\%%~nI.xml" "%%I"
)
endlocal
输入和输出文件夹路径是使用预定义的环境变量USERPROFILE
在末尾没有反斜线定义,没有星号。
通过Magoo在他的Find the path used by the command line when calling an executable答案写一个稍微修改后的代码被用于查找的JHOVE Java包。批处理文件将打印正在搜索的文件夹,以防文件无法找到,从而导致出现错误消息并暂停批量处理,直到用户按下任何键。
创建类路径变量CP
是考虑到文件夹路径是否以反斜杠结尾。 PATH
中的文件夹路径应该在末尾没有反斜线定义,但总是有安装程序将文件夹路径添加到PATH
不是100%正确。但是,Windows内核处理这种情况时,路径中的任何位置的结果是否为\\
都无关紧要。这就是为什么if exist "%%~I\bin\JhoveApp.jar"
也始终工作的原因,虽然此文件存在测试也可以通过路径中的两个反斜杠完成,具体取决于PATH
中的文件夹路径。
接下来,输出文件夹在没有先检查文件夹是否已存在的情况下创建,也不检查文件夹创建是否成功。
批处理代码包含两个解决方案,用于在输入文件夹路径中递归找到的每个文件上运行jhove
。第一个被注释掉。这对于隐藏和系统文件也有好处。第二种解决方案不适用于隐藏文件和系统文件,但这在这里很可能不是必需的。第二种解决方案因此是首选。
为了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
pause /?
set /?
setlocal /?
而且也可以参考微软的文章:
当有路径或文件名空格,使用引号周围:'... in('dir/b/a -d/s“%input%”')do ...'和'CALL jhove -m PDF-hul -h xml -o“%output%\ %%〜na.xml”“%% a”' – Stephan
@斯蒂芬我已经尝试过了,但结果相同 –
@OlegNekhayenko,我觉得很难相信。我很想看到脚本的执行情况。保持回应,并用该信息更新您的问题。 – Squashman