批处理文件变量不会显示echo

时间:2016-09-18 18:26:13

标签: file variables batch-file echo

所以我厌倦了Spotify广告。所以我想创建自己的私人音乐播放器。

但我遇到了一个问题,你稍后会看到。

在这里您可以选择自动(基本上是播放列表)或手动(只播放一首歌曲)。

但我删除了这部分代码,因为它工作正常并且在这里不用了。

@echo off
:auto
echo Now pick a song to start it off.

我因版权原因删除了歌曲名称。

echo.
echo Type 1 for song number one
echo Type 2 for song number two
echo Type 3 for song number three
echo Type 4 for song number four
echo Type 5 for song number five
echo.
set /p songID=Enter songID: 
if %songID%==1 goto Auto1
if %songID%==2 goto Auto2
if %songID%==3 goto Auto3
if %songID%==4 goto Auto4
if %songID%==5 goto Auto5

这是我在下面放置变量的地方。

他们是麻烦制造者!

set song1=Song name 1
set song2=Song name 2
set song3=Song name 3
set song4=Song name 4
set song5=Song name 5

我保留了所有变量。我刚刚删除了代码的底部。

但它看起来只有:Auto2等等。

set /a x=x是歌曲的长度,用于创建计时器。

所以这首歌将在歌曲结束时结束。 ;)

:POSSA1:POSA1正在创建计时器:

:Auto1
cls
start  %user%\Downloads\Songs\"Song name 1.mp3"
set /a x=248

:POSSA1
if %x%==1 goto POSA1
if %x% gtr 0 (
    echo Now playing %song1%
    echo.
    echo %x% Seconds
    choice /n /c yn /t 1 /d y >nul
    set /a x-=1
    cls
    goto POSSA1
)

:POSA1
if %x% gtr 0 (
    echo Now playing %song1%
    echo.
    echo %x% Second
    choice /n /c yn /t 1 /d y >nul
    set /a x-=1
    cls
    goto POSSA1
)

:end
cls
taskkill /F /IM WMPlayer.exe
pause>nul

那么我做错了什么?

1 个答案:

答案 0 :(得分:1)

第一个错误是在线:

start  %user%\Downloads\Songs\"Song name 1.mp3"

通常,带路径的整个文件名应该用双引号括起来,而不仅仅是文件名的部分内容。在命令提示符窗口cmd /?中运行并仔细阅读所有输出帮助页面。

因为它可以通过在命令提示符窗口start /?中运行来读取,所以双引号中的第一个字符串由命令 START 解释为可选标题,这通常需要明确指定标题,即使它只是一个空标题,即只指定""。所以正确的命令行是:

start  "" "%user%\Downloads\Songs\Song name 1.mp3"

接下来,不要使用算术表达式为环境变量分配数字,这意味着不要使用set /a x=248。最好使用set "x=248"

环境变量总是字符串类型。无法创建整数类型的环境变量。对于行set /a x=248,Windows命令处理器首先使用C函数strtol将字符串248转换为整数,然后将该数字转换回字符串以将其分配给环境变量{{1 }}。将数字字符串直接作为字符串分配给环境变量当然更有效。

此外,建议将命令 SET 的参数括起来,x也始终用双引号括起来。有关解释,请参阅How to set environment variables with spaces?Why is no string output with 'echo %var%' after using 'set var = text' on command line?

上的答案

这意味着在您的批处理代码片段中:

variable=string

在命令提示符窗口set "song1=Song name 1" set "song2=Song name 2" set "song3=Song name 3" set "song4=Song name 4" set "song5=Song name 5" set /p "songID=Enter song ID: " 中运行并阅读所有输出帮助页面。您可以在那里阅读有关delayed expansion的内容。在以set /?开头并以匹配(结尾的命令块中定义或修改环境变量时,始终需要延迟环境变量扩展,并且在同一命令块中引用环境变量的值。 / p>

原因是在命令执行之前,所有带有)的{​​{1}}到匹配%VariableName%的环境变量引用都会被参考环境变量的当前字符串值立即替换,通常是命令 FOR IF 。此预处理命令块不会进一步更新。

可以通过

监视此变量扩展行为
  • 从批处理文件中删除所有(),使用 REM 命令对其进行评论,或将@echo off修改为echo off
  • 打开命令提示符窗口,
  • 从命令提示符窗口中运行批处理文件,该文件来自包含批处理文件的目录,或者输入带有完整路径的批处理文件的文件名,最好也用双引号括起来的文件扩展名。

现在,在启用了回显模式的命令提示符窗口中运行批处理文件,而不是在禁用回显模式的情况下双击它,可以看到Windows命令处理器在预处理后实际执行的操作 每个命令行分别是命令块。并且在出现错误时也可以看到错误消息,因为即使Windows命令处理器遇到语法错误,控制台窗口仍保持打开状态。

即使是高级批处理文件编码器在开发过程中用于调试批处理代码的方法也是如此。

虽然有问题的代码片段对重现问题没有帮助,但我认为off没有输出任何内容,因为行on位于{{1}以上任何地方的同一个命令块中并且在echo Now playing %song1%以下的任何地方结束,因此需要延迟扩展。

在命令提示符窗口set song1=Song name 1(中运行,以获取有关使用延迟扩展所需的这两个命令的帮助。

在阅读本答案时可以看到,要获得批处理文件中使用的命令的帮助,只需在命令提示符窗口中运行带参数)的命令即可。建议在开发批处理文件时使用内置帮助。

最后我建议将文件名放入文本文件(播放列表文件)并使用命令 FOR 来处理它们(输出,选择一个播放等)。通过在命令提示符窗口setlocal /?中运行,了解有关命令 FOR 的更多信息。

使用歌曲列表文件对播放器进行编码的演示代码。

endlocal /?

阅读以 REM 命令开头的注释,尤其是

/?

此行必须替换为播放歌曲文件for /?的代码。

歌曲列表文件@echo off setlocal EnableExtensions EnableDelayedExpansion set "SongsListFile=C:\Temp\Song List.txt" set "SongFileMissing=0" if not exist "%SongsListFile%" goto ListFileError cls echo Pick a song to start it off. echo. echo 0 ... play all songs rem Output all songs from song list without path and file extension. rem The song number is right aligned with 3 characters width which rem means working for song numbers 1 to 999. set "SongNumber=0" for /F "usebackq delims=" %%I in ("%SongsListFile%") do ( set /A SongNumber+=1 set "SongOption= !SongNumber!" set "SongOption=!SongOption:~-3!" echo !SongOption! ... %%~nI ) echo. rem Define as default value 0 for playing all songs in case of rem user just hits key RETURN or ENTER and prompt user for number. set "SongSelected=0" set /P "SongSelected=Enter song number (default: %SongSelected%): " echo. rem Play all songs if a string was entered by the user not consisting rem of only digits, i.e. the entered string is not a number. for /F "delims=0123456789" %%I in ("!SongSelected!") do goto PlayAll rem Numbers with leading 0s could be interpreted as octal numbers by rem Windows command processor and therefore better make sure that the rem number string does not have leading zeros. On a number like 0, 00, rem 000, ... play all songs. :RemoveLeadingZeros if not "%SongSelected:~0,1%" == "0" goto CheckMaxNumber set "SongSelected=%SongSelected:~1%" if not "%SongSelected%" == "" goto RemoveLeadingZeros goto PlayAll rem Windows command processor interprets numbers as signed 32-bit integers rem which limits the range from -2147483648 to 2147483647 whereby only the rem positive range is of interest here at all. The entered number string rem could be longer than what Windows command processor supports. Every rem number with more than 9 digits is interpreted as invalid which reduces rem the valid number range here from 1 to 999999999 which should be always rem enough. And of course the entered number should not be greater than rem the number of song file names in songs list. :CheckMaxNumber if not "%SongSelected:~9,1%" == "" goto PlayAll if %SongSelected% GTR %SongNumber% goto PlayAll rem For playing a single song skip all lines above the line with the rem song file name to play, play the selected song file and then exit rem the loop without processing the other lines in songs list file. rem skip=0 results in a syntax error and therefore it is necessary to rem define the entire skip option as an environment variable if needed rem because any other than first song in songs list file should be played. set "SkipOption=" set /A SongSelected-=1 if not "%SongSelected%" == "0" set "SkipOption= skip=%SongSelected%" if not exist "%SongsListFile%" goto ListFileError for /F "usebackq%SkipOption% delims=" %%I in ("%SongsListFile%") do ( call :PlaySong "%%~fI" goto EndPlayer ) rem Output error message if songs list file does not exist rem checked every time before reading the lines from this file. :ListFileError echo Error: The songs list file "%SongsListFile%" does not exist. set "SongFileMissing=1" goto EndPlayer rem This is a subroutine embedded in the player's batch file used rem to play the song passed to the subroutine with first argument. :PlaySong if not exist "%~1" ( echo Error: Song file "%~1" does not exist. set "SongFileMissing=1" goto :EOF ) echo Playing now song %~n1 ... rem Insert here the code used to play the song. rem This command results in exiting subroutine and processing of batch rem file continues on the line below the line calling PlaySong. goto :EOF :PlayAll if not exist "%SongsListFile%" goto ListFileError for /F "usebackq delims=" %%I in ("%SongsListFile%") do call :PlaySong "%%~fI" :EndPlayer echo. if not "%SongFileMissing%" == "0" ( endlocal pause ) else endlocal 可以包含带或不带路径的歌曲文件的名称。例如:

rem Insert here the code used to play the song.

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • "%~1"
  • C:\Temp\Song List.txt
  • First song.mp3 C:\Temp\Another song.mp3 Album 1 - Last song .mp3
  • call /?
  • cls /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • pause /?
相关问题