【问题标题】:how to correctly check errorlevel如何正确检查错误级别
【发布时间】:2020-09-24 20:33:19
【问题描述】:

我有一个 Windows 批处理脚本,它以三种模式之一运行,具体取决于命令行参数的数量:

1 个命令行参数:播放命名的 .wav 文件

2 个命令行参数:运行第一个命令行参数指定的命令,然后播放第二个命令行参数指定的 .wav 文件

3 个命令行参数:运行第一个命令行参数指定的命令,然后播放通过第二个或第三个命令行参数指定的 .wav 文件,具体取决于命令是否成功

我的问题在于第三种模式:无论命令是否成功,脚本总是播放第一个声音。任何建议将不胜感激。

@ECHO OFF
Setlocal disableDelayedExpansion

:: OVERVIEW

:: This script optionally runs a command and then uses Eli Fulkerson's
:: `sounder.exe` to play the specified or default sound.

:: The Media environment variable must be defined and contain the path of a
:: folder containing one or more .wav files.


:: REFERENCE

:: https://www.elifulkerson.com/projects/commandline-wav-player.php


:: USAGE CASE 1: NO ARGUMENTS

:: If the script is invoked without arguments, it plays the default sound file
:: `beep-05.wav`.


:: USAGE CASE 2: ONE ARGUMENT

:: The single argument is the name of a sound file, minus the .wav extension.
:: sound.bat will play this sound file.  Example:

::    sound meow1


:: USAGE CASE 3: TWO ARGUMENTS

:: The first argument contains a command to be run; the second argument is the
:: name of a sound file, minus the .wav extension.  sound.bat will play the
:: sound after the command finishes running, regardless of exit code.  Example:

::    sound "dir C:\Phillip" meow1


:: USAGE CASE 4: THREE ARGUMENTS

:: The first argument contains a command to be run; the second and third
:: arguments name sound files, minus the .wav extension to be played if the
:: executes successfully or fails, respectively.

::    sound "dir C:\Phillip" meow1 meow2


:: NOTE

:: It is not currently possible to use this scripts to play sound files that are
:: located outside the Media folder.


:: AUTHOR

:: Phillip M. Feldman


:: REVISION HISTORY

:: June 5, 2020, Phillip M. Feldman: Initial version.


If not defined Media (
   msg "%username%" The Media environment variable is not defined!
   GOTO :EOF
)

If not EXIST %Media% (
   msg "%username%" The Media folder '%Media%' does not exist!
   GOTO :EOF
)


If '%1' == '' (

   :: No command-line arguments.
   sounder %Media%\beep-05.wav
   GOTO :EOF
)

If '%2' == '' (

   :: One command-line argument.
   sounder %Media%\%1%.wav
   GOTO :EOF
)

If '%3' == '' (

   :: Two command-line arguments.
   %~1
   sounder %Media%\%2%.wav
   GOTO :EOF
)

If '%4' == '' (

   :: Three command-line arguments.
   %~1

   If %ERRORLEVEL% == 0 (
      sounder %Media%\%2%.wav
   ) else (
      sounder %Media%\%3%.wav
   )
   GOTO :EOF
)

【问题讨论】:

  • If '%3' == '' 是错误的语法。单引号不提供双引号提供的保护,并且如果文件路径参数包含空格并且已通过双引号传递给脚本,则应使用~ 修饰符If "%~3" == "" 此外,您正在错误地扩展参数变量。 sounder %Media%\%3%.wav 应该是:sounder "%Media%\%~3.wav"
  • 请删除所有格式错误的标签::  并用正确的评论命令Rem  替换它们。 或者更好的是,将它们全部删除,因为我们只需要 minimal reproducible example,我们不需要所有这些。此外,If not EXIST %Media% ( 无法确定 folder 是否名为 ExpandedValueOfMediaVariable exists。
  • 您需要延迟扩展errorlevel 变量或使用if not errorlevel 1

标签: windows batch-file command-line-arguments


【解决方案1】:

这是一个使用我在您自己的答案下通过评论提出的方法的示例,并包括一些额外的验证:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Rem OVERVIEW
Rem This script optionally runs a command and then uses Eli Fulkerson's
Rem `sounder.exe` to play the specified or default sound.
Rem The Media environment variable must be defined and contain the path of a
Rem folder containing one or more .wav files.

Rem REFERENCE
Rem https://www.elifulkerson.com/projects/commandline-wav-player.php

Rem USAGE CASE 1: NO ARGUMENTS
Rem If the script is invoked without arguments, it plays the default sound file
Rem `beep-05.wav`.  Example:
Rem    sound

Rem USAGE CASE 2: ONE ARGUMENT
Rem The single argument is the name of a sound file, minus the .wav extension.
Rem sound.bat will play this sound file.  Example:
Rem    sound meow1

Rem USAGE CASE 3: TWO ARGUMENTS
Rem The first argument contains a command to be run; the second argument is the
Rem name of a sound file, minus the .wav extension. The sound will play upon
Rem completion of the command, regardless of its returned exit code.  Example:
Rem    sound "dir C:\Phillip" meow1

Rem USAGE CASE 4: THREE ARGUMENTS
Rem The first argument contains a command to be run; the second and third
Rem arguments name sound files, minus their .wav extensions, the first to be
Rem played if the command executes successfully and the second if it fails.
Rem Example:
Rem    sound "dir C:\Phillip" meow1 meow2

Rem NOTE
Rem It is not currently possible to use this script to play sound files which
Rem are located outside the Media folder.

Rem AUTHORS
Rem Phillip M. Feldman, Compo

Rem REVISION HISTORY
Rem June 8 2020, Compo: Improved version.
Rem June 5 2020, Phillip M. Feldman: Initial version.

Rem Validates the environment and input of no more than three arguments.
Set "$=0"
%__AppDir__%where.exe /Q sounder.exe && (If Not Defined Media (Set "$=16"
        %__AppDir__%msg.exe "%UserName%" The Media environment variable is not defined.
    ) Else For %%G In ("%Media%") Do If "%%~aG" Lss "d" (Set "$=8"
        %__AppDir__%msg.exe "%UserName%" The Media folder '%Media%' does not exist!
    ) Else %__AppDir__%where.exe /Q "%Media%":"*.wav" && (If Not "%~4"=="" (Set "$=2"
            %__AppDir__%msg.exe "%UserName%" Unexpected number of arguments.)) || (Set "$=4"
        %__AppDir__%msg.exe "%UserName%" There are no WAV files in '%Media%'.)) || (Set "$=32"
    %__AppDir__%msg.exe "%UserName%" Eli Fulkerson's sounder.exe was not found.)

If %$% NEq 0 Exit /B %$%

Rem Validates that the input .wav file names exist in the Media directory.
If Not "%~3"=="" (%__AppDir__%where.exe /Q "%Media%":"%~2.wav" || (Set "$=1"
        %__AppDir__%msg.exe "%UserName%" Sound file '%Media%\%~2' does not exist.)
    %__AppDir__%where.exe /Q "%Media%":"%~3.wav" || (Set "$=1"
        %__AppDir__%msg.exe "%UserName%" Sound file '%Media%\%~3' does not exist.)
) Else If Not "%~2"=="" (%__AppDir__%where.exe /Q "%Media%":"%~2.wav" || (Set "$=1"
        %__AppDir__%msg.exe "%UserName%" Sound file '%Media%\%~2' does not exist.)
) Else If Not "%~1"=="" (%__AppDir__%where.exe /Q "%Media%":"%~1.wav" || (Set "$=1"
        %__AppDir__%msg.exe "%UserName%" Sound file '%Media%\%~1' does not exist.)
) Else %__AppDir__%where.exe /Q "%Media%":"beep-05.wav" || (Set "$=1"
    %__AppDir__%msg.exe "%UserName%" Sound file '%Media%\beep-05.wav' does not exist.)

If %$% NEq 0 Exit /B %$%
Set "$="

Rem The commands to run if validation is successful.
If Not "%~3"=="" (%~1 2>NUL && (sounder.exe "%Media%\%~2.wav") || sounder.exe "%Media%\%~3.wav"
) Else If Not "%~2"=="" (%~1 2>NUL
    sounder.exe "%Media%\%~2.wav") Else If Not "%~1"=="" (sounder.exe "%Media%\%~1.wav"
) Else sounder.exe "%Media%\beep-05.wav"

GoTo :EOF

【讨论】:

    【解决方案2】:

    通过两个小改动,脚本(见下文)现在可以工作了。我要感谢所有帮助或试图提供帮助的人。

    @ECHO OFF
    Setlocal enableDelayedExpansion
    
    :: OVERVIEW
    
    :: This script optionally runs a command and then uses Eli Fulkerson's
    :: `sounder.exe` to play the specified or default sound.
    
    :: The Media environment variable must be defined and contain the path of a
    :: folder containing one or more .wav files.
    
    
    :: REFERENCE
    
    :: https://www.elifulkerson.com/projects/commandline-wav-player.php
    
    
    :: USAGE CASE 1: NO ARGUMENTS
    
    :: If the script is invoked without arguments, it plays the default sound file
    :: `beep-05.wav`.
    
    
    :: USAGE CASE 2: ONE ARGUMENT
    
    :: The single argument is the name of a sound file, minus the .wav extension.
    :: sound.bat will play this sound file.  Example:
    
    ::    sound meow1
    
    
    :: USAGE CASE 3: TWO ARGUMENTS
    
    :: The first argument contains a command to be run; the second argument is the
    :: name of a sound file, minus the .wav extension.  sound.bat will play the
    :: sound after the command finishes running, regardless of exit code.  Example:
    
    ::    sound "dir C:\Phillip" meow1
    
    
    :: USAGE CASE 4: THREE ARGUMENTS
    
    :: The first argument contains a command to be run; the second and third
    :: arguments name sound files, minus the .wav extension to be played if the
    :: executes successfully or fails, respectively.
    
    ::    sound "dir C:\Phillip" meow1 meow2
    
    
    :: NOTE
    
    :: It is not currently possible to use this scripts to play sound files that are
    :: located outside the Media folder.
    
    
    :: AUTHOR
    
    :: Phillip M. Feldman
    
    
    :: REVISION HISTORY
    
    :: June 5, 2020, Phillip M. Feldman: Initial version.
    
    
    If not defined Media (
       msg "%username%" The Media environment variable is not defined!
       GOTO :EOF
    )
    
    If not EXIST %Media% (
       msg "%username%" The Media folder '%Media%' does not exist!
       GOTO :EOF
    )
    
    
    If '%1' == '' (
    
       :: No command-line arguments.
       sounder %Media%\beep-05.wav
       GOTO :EOF
    )
    
    If '%2' == '' (
    
       :: One command-line argument.
       sounder %Media%\%1%.wav
       GOTO :EOF
    )
    
    If '%3' == '' (
    
       :: Two command-line arguments.
       %~1
       sounder %Media%\%2%.wav
       GOTO :EOF
    )
    
    If '%4' == '' (
    
       :: Three command-line arguments.
       %~1
    
       If ERRORLEVEL 1 (
          sounder %Media%\%3%.wav
       ) else (
          sounder %Media%\%2%.wav
       )
       GOTO :EOF
    )
    

    【讨论】:

    • 看起来你正在寻找这样的东西:If Not "%~3"=="" (%~1 2>NUL && (sounder "%Media%\%~2.wav") || sounder "%Media%\%~3.wav") Else If Not "%~2"=="" (%~1 2>NUL & sounder "%Media%\%~2.wav") Else If Not "%~1"=="" (sounder "%Media%\%~1.wav") Else sounder "%Media%\beep-05.wav"。但是,要使您的脚本在实际场景中几乎有用,您应该首先对输入进行一些验证,以验证输入的声音文件是否存在,在尝试播放任何声音或运行之前通知最终用户错误任何输入的命令。
    • 验证命令听起来不错,但我不知道该怎么做。
    • 我没有考虑验证命令,只是作为参数输入的任何 wav 文件的存在。要验证一个命令,即检查它是否真的是一个命令,唯一可靠的方法是运行它,看看会发生什么。如果您将它作为验证的一部分运行,那么您最终将不得不运行每个命令两次,这似乎非常浪费。是否有允许的命令列表,或者您是否打算能够使用任何内部命令或外部可执行文件? (有清单你有机会,有任何你没有机会).
    【解决方案3】:

    替代方案:

    If "%~4" == "" (
    
       :: Three command-line arguments.
       %~1
    
       If "%ERRORLEVEL%" == "0" (
          sounder "%Media%\%~2.wav"
       ) else (
          sounder "%Media%\%~3.wav"
       )
       GOTO :EOF
    )
    

    是使用&&(成功时)和|| (失败时)条件运算符:

    (If Not "%~3" == "" %~1) && sounder "%Media%\%~2.wav" || sounder "%Media%\%~3.wav"
    

    【讨论】:

    • 你不能在代码块中使用::,因为它在技术上是一个标签。
    • ``` (如果不是 "%~3" == "" %~1) && sounder "%Media%\%~2.wav" || sounder "%Media%\%~3.wav" ``` 很紧凑,但是当命令执行成功时,两个声音都在播放。
    • 回复。单引号 vs. 双引号:如果命令包含空格,则必须双引号,如果代码使用双引号,这种情况下解析失败。
    • 好吧,@PhillipM.Feldman,它不会总是失败,但在某些情况下你需要this
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2013-03-06
    • 2021-08-27
    • 2018-02-04
    • 1970-01-01
    相关资源
    最近更新 更多