Batch file set command isn't working in if statement - batch-file

For the life of me, I can't figure out why the below set prompt won't work when it is in the if statement:
#echo off
REM :askdeletecsvs
if exist *.csv (
echo Warning! All files in the scripts folder that have the "CSV" extension will be deleted!
echo Answering "n" will continue the script without deleting the CSVs.
set /p ASKDELETE=Delete CSVs? (y/n):
REM
REM if ( /i %ASKDELETE% equ "y" goto :deletecsvs )
REM if ( /i %ASKDELETE% equ "n" goto :runscripts )
REM goto :askdeletecsvs
)
When I run the batch file as it is above the cmd window opens and then shuts quickly. If I move the set line outside of the if statement then the prompt shows as expected. (There are csvs in the folder the bat file is running from)
What am I missing?

To start with you had used a closing parenthesis which was prematurely ending your opening If parenthesis.
I'd suggest reversing the thinking:
If Not Exist *.csv GoTo runscripts
Echo Warning!
Echo All files in the scripts folder that have the "CSV" extension will be deleted!
Echo Answering "N" will continue the script without deleting the CSVs.
Choice /M "Delete CSVs"
If ErrorLevel 2 GoTo runscripts
:deletecsvs
Del /F /Q /A "PathTo\scripts\*.csv"
GoTo :EOF
:runscripts
You can change GoTo :EOF to a relevant valid label as necessary or remove it if you want to continue on to :runscripts. You can also replace PathTo\scripts\ with %~dp0 if the batch file is running from the scripts directory, or remove PathTo\scripts\ if the current directory holds those files. (note that the current directory and batch file path may not necessarily be the same)

Related

How to print only number of files copied as a variable, while logging all the actions?

I'm writing a script on a BAT file to use when necessary, to backup a folder of an application on several computers.
This script works on Windows 7: will it also work on Windows 10?
:: Backup script with logging
#echo off
net use \\SERVER\Shared_Folder userPassword /USER:userName
set PATH=c:\WINDOWS\system32;
set SRC="C:\Program Files (x86)\ApplicationName\TargetFolder"
set DST=\\SERVER\Shared_Folder\Backups
set LOG=%DST%\Backup_LogFile.log
echo:>>%LOG%
echo Backup from computer %COMPUTERNAME% >>%LOG%
echo Starts -- %DATE% %TIME% >>%LOG%
echo Wait please: backup is running...
xcopy %SRC% %DST%\%COMPUTERNAME%\ /A /D /E /J /Y /Z>>%LOG%
echo Ends -- %DATE% %TIME% >>%LOG%
echo:>>%LOG%
My script works fine but I want a better response on terminal for the user than execute it.
The script adds correctly the actions on a log file, but I want the user can see only the number of file copied not the list of all files copied.
Here is one way to accomplish what you ask. There are other ways too. The secret here is using "for /F" and sending each result to another function. The other function will log each line to a file. It will then look for xcopy's "File(s) copied" line and pipe that to the user if it sees it.
Also... note the "goto :EOF" statements. These tell the batch interpreter to return to the caller much like any other programming language.
I hope this does what you are asking. :)
:: Backup script with logging
#echo off
net use \\SERVER\Shared_Folder userPassword /USER:userName
set SRC="C:\Program Files (x86)\ApplicationName\TargetFolder"
set DST=\\SERVER\Shared_Folder\Backups
set LOG=%DST%\Backup_LogFile.log
echo:>>%LOG%
echo Backup from computer %COMPUTERNAME% >>%LOG%
echo Starts -- %DATE% %TIME% >>%LOG%
echo Wait please: backup is running...
for /f "delims=" %%f in ('xcopy %SRC% %DST%\%COMPUTERNAME%\ /A /D /E /J /Y /Z') do call :log_items "%%f"
echo Ends -- %DATE% %TIME% >>%LOG%
echo:>>%LOG%
goto :EOF
:log_items
Set InputLine=%~1
:: Log everything
echo %InputLine%>>%LOG%
:: Check if the line coming in contains "File(s) copied" if it doesn't, return
if "%InputLine:File(s) copied=%"=="%InputLine%" goto :EOF
:: If it does, show it to the user and return
echo %InputLine%
goto :EOF
The comparison done for the files copied looks like this:
For a line with your file name: (here they match so it returns)
C:\git\ps>if "test\targetver.h" == "test\targetver.h" goto :EOF
For a line with your number of files: (here they dont match do it doesn't return)
C:\git\ps>if "205 " == "205 File(s) copied" goto :EOF

If statement in batch script isn't working?

I have a batch script which when given the input "edit", should then echo "hello" as a sort of debug and open the batch scripts file in notepad. However for some inexplicable reason the script will not respond to the if statement no matter what. How do I get it to respond to the "edit" input?
REM #ECHO OFF
cd/
cd projects\py_test
ECHO Use this batch script to lauch Python modules living in "C:\Projects\py_test\" ONLY.
ECHO.
SET /P name="Type file name with file extension .py to start or type EDIT to edit this .bat: "
REM #ECHO OFF
cmd /k IF %name%==edit GOTO EDIT
REM IF EXIST %name% py %name%
REM IF NOT EXIST %name% echo [101mERROR: The requested file could not be found. Make sure the file exists in "C:\Projects\py_test\" and that the filename includes the ".py" extension.[0m
#ECHO OFF
:EDIT
ECHO HELLO
notepad projects-py_test-dot_start.bat`
Firstly, why all the REM #ECHO OFFs? It looks ugly, especially when they are all caps.
Then, you want to run cmd /k for an if statement for no real reason? With the variable name you need to preferbly enclose the if statement variables in double quotes to eliminate possible whitespace:
#echo off
cd /d "C:\projects\py_test"
echo Use this batch script to lauch Python modules living in "C:\Projects\py_test\" ONLY.
echo/
set /p name="Type file name with file extension .py to start or type EDIT to edit this .bat: "
if defined name set "name=%name:"=%"
if /i "%name%"=="edit" goto edit
goto :EOF
:edit
echo hello
notepad echo "%~f0"
but by guessing that you simply want to launch a python script if it exists, else edit itself, then I would instead do this version without the labels. It simply checks if the name typed exists (hoping the user typed the full script with extension) else, we add the extension test in case the user typed only the name and not extension.:
#echo off
cd /d "C:\projects\py_test"
echo Use this batch script to lauch Python modules living in "C:\Projects\py_test\" ONLY.
echo/
set /p name="Type file name with file extension .py to start or type EDIT to edit this .bat: "
if defined name set "name=%name:"=%"
if /i "%name%"=="edit" notepad "%~f0"
if exist "%name%" (
python "%name%"
) else (
if exist "%name%.py" (
python "%name%.py"
) else (
echo "%name%" does not exist
)
)

uTorrent Batch Script

I wrote myself a script based off another one that I found and I'm having trouble figuring out why it's not working.
How it is supposed to work is once a torrent has finished downloading, it runs the script and grabs the Label on the torrent. For testing, I was downloading a song with the label of Music.
When it gets to the point at :copyfile, it won't move it into the correct directory. Instead of moving into F:\Completed Torrents\Music, it just moves into F:\Completed Torrents.
Can someone please point out what I'm missing because I've looked through it thrice already and it's driving me crazy. The script is below.
#echo off
title Liam's torrent-file script
rem Parameter usage: fromdir torrent-name label kind [filename]
rem corresponds to uTorrents flags: %D %N %L %K %F
echo *********************************************
echo Run on %date% at %time%
set fromdir=%1
set name=%2
set label=%3
set kind=%4
set filename=%5
set savepartition="F:\Completed Torrents"
set winrar="C:\Program Files (x86)\WinRAR\WinRAR.exe"
set torrentlog="F:\Torrent Scripts\logs\torrentlog.txt"
set handledlog="F:\Torrent Scripts\logs\handled_torrents.txt"
set errorlog="F:\Torrent Scripts\logs\ErrorLog.txt"
set label_prefix=""
echo Input: %fromdir% %name% %label% %kind% %filename%
rem Check if the label has a sub label by searching for \
if x%label:\=%==x%label% goto skipsublabel
rem Has a sub label so split into prefix and suffix so we can process properly later
echo sub label
for /f "tokens=1,2 delims=\ " %%a in ("%label%") do set label_prefix=%%a&set label_suffix=%%b
rem add the removed quote mark
set label_prefix=%label_prefix%"
set label_suffix="%label_suffix%
echo.prefix : %label_prefix%
echo.suffix : %label_suffix%
goto:startprocess
:skipsublabel
echo Skipped Sub Label
goto:startprocess
:startprocess
echo %date% at %time%: Handling %label% torrent %name% >> %handledlog%
rem Process the label
if %label%=="Movies" goto known
if %label%=="Music" goto known
if %label_prefix%=="TV" goto TV
rem Last resort
rem Double underscores so the folders are easier to spot (listed on top in explorer)
echo Last Resort
set todir=%savepartition%\Unsorted\__%name%
if %kind%=="single" goto copyfile
if %kind%=="multi" goto copyall
GOTO:EOF
:known
echo **Known Download Type - %label%
set todir=%savepartition%\%label%\%name%
echo todir = %todir%
GOTO:process
:TV
echo **Known Download Type - %label%
set todir=%savepartition%\%label_prefix%\%label_suffix%
echo todir = %todir%
GOTO:process
:process
rem If there are rar files in the folder, extract them.
rem If there are mkvs, copy them. Check for rars first in case there is a sample.mkv, then we want the rars
if %kind%=="single" goto copyfile
if exist %fromdir%\*.rar goto extractrar
if exist %fromdir%\*.mkv goto copymkvs
if %kind%=="multi" goto copyall
echo Guess we didnt find anything
GOTO:EOF
:copyall
echo **Type unidentified so copying all
echo Copy all contents of %fromdir% to %todir%
xcopy %fromdir%\*.* %todir% /S /I /Y
GOTO:EOF
:copyfile
rem Copies single file from fromdir to todir
echo Single file so just copying
echo Copy %filename% from %fromdir% to %todir%
xcopy %fromdir%\%filename% %todir%\ /S /Y
GOTO:EOF
:copymkvs
echo Copy all mkvs from %fromdir% and subdirs to %todir%
xcopy %fromdir%\*.mkv %todir% /S /I /Y
GOTO:EOF
:extractrar
echo Extracts all rars in %fromdir% to %todir%.
rem Requires WinRar installed to c:\Program files
if not exist %todir% mkdir %todir%
IF EXIST %fromdir%\subs xcopy %fromdir%\subs %todir% /S /I /Y
IF EXIST %fromdir%\subtitles xcopy %fromdir%\subtitles %todir% /S /I /Y
call %winrar% x %fromdir%\*.rar *.* %todir% -IBCK -ilog"%todir%\RarErrors.log"
IF EXIST %fromdir%\*.nfo xcopy %fromdir%\*.nfo %todir% /S /I /Y
GOTO:EOF
EDIT
Also, for some reason, on line 39 nothing prints to the log. For those who wish to see the code with line numbers: http://hastebin.com/juqokefoxa.dos
A couple of bits for ya:
1) Likely, your script isn't moving the files. Preferences / Directories has an option to move downloads when completed. verify that these settings aren't doing the file moving.
2) uTorrent locks the files on completion so that seeding can continue. To change this behavior, go to Preferences / Advanced and set bt.read_only_on_complete to false
3) you will still be foiled because "Run this program when a torrent finishes" doesn't really do what it says. It runs the program as downloading reaches 100%, but while uTorrent is still either moving the file or seeding. See my bug report here.
A quick summary of the post, just in case that post gets deleted: you have to set the command in "Run this program when a torrent changes state:", add a %S parameter and check that %S == 11
4) Just a tip from my attempt at doing something very similar: when you set the variables from the arguments, add a tilde (%~1 instead of %1). This will strip the quotes off and let us more easily build command lines with the variables later.
You say that the log is not being written to. Try this as a test and see if it writes to the log.
If it doesn't there there is some other fundamental problem.
#echo off
title Liam's torrent-file script
rem Parameter usage: fromdir torrent-name label kind [filename]
rem corresponds to uTorrents flags: %D %N %L %K %F
echo *********************************************
echo Run on %date% at %time%
set "fromdir=%~1"
set "name=%~2"
set "label=%~3"
set "kind=%~4"
set "filename=%~5"
set "savepartition=F:\Completed Torrents"
set "winrar=C:\Program Files (x86)\WinRAR\WinRAR.exe"
set "torrentlog=F:\Torrent Scripts\logs\torrentlog.txt"
set "handledlog=F:\Torrent Scripts\logs\handled_torrents.txt"
set "errorlog=F:\Torrent Scripts\logs\ErrorLog.txt"
set "label_prefix="
set "handledlog=%userprofile%\desktop\handled_torrents.txt"
>> "%handledlog%" echo Input: "%fromdir%" "%name%" "%label%" "%kind%" "%filename%"
>> "%handledlog%" echo %date% at %time%: Handling "%label%" torrent "%name%"

Delete a specific file if this one is empty

I would like to delete a specific file if this one is empty by the use of a windows .bat file. Here is my non-working script:
if %~z1 == 0
echo %~z1===================
del "%1"
goto :eof
if %~z1==0 (
echo %~z1===================
del "%1"
)
goto :eof
The goto should be placed inside the parentheses if you want to go to end-of-file having deleted the file. As I've placed it, in the absence of further information, the batch would terminate regardless.

How can you create a batch script which runs the user-specified software?

So basically I want to create a batch script that can run any notepad file which the user specifies. I tried this...
#Echo Off
SET /P ANSWER=What is the name of the file to open?
IF /i (%ANSWER%)==('FIND /i "*.txt" %ANSWER%) (goto :Filename)
goto :exit
:Filename
Start *.txt
EXIT
:exit
ECHO FAILLLLLLLL
PAUSE
EXIT
The issue here is the first IF statement. I know its wrong. But, I don't know how to specify the entry of any filename. A different way to do this task is also appreciated.
Thanks for help :)
If your goal is simply to open a file that the user specifies in Notepad, the following works for me in Windows 7:
#echo off
set /P answer=What is the file name?
if exist %answer% (
start notepad.exe %answer%
) else (
echo Unable to locate %answer%
)

Resources