How to go to label in called batch file - batch-file

My code is like this in one.bat:
#echo off
echo hi
call example.bat
:label
echo hello
pause
My code is like this in example.bat:
#echo off
echo hi!
call one.bat
I want it to goto the label once one.bat is called. How do I do this?

If you want to return to the line below where you called example.bat (place where you currently have the label) , you don't need the label. Use exit /b at end of example.bat.
#echo off
echo hi!
exit /b
:: Takes you back to the batch file at the spot you left it
If you really do want to go to a label in one.bat, put goto %1 at the top of one.bat (right under #echo off) and pass a variable with the name of the label when you do the call. Like this:
#echo off
echo hi!
set gotoPlace=label
call one.bat %gotoPlace%
Calling One.bat starts it over again, but the variable you are passing to One.bat (%gotoplace%) replaces the %1 that you put at the top of the file, so "goto %1" now equals "goto label".
Edit: %1 used this way does what you want in your very simple batch file, but typically you wouldn't want goto %1 at the top of a bat. The beginning of this page tells more about passing items from one batch file to another.

The trouble with contrived code is that the answer to the question may not be what you are looking for :)
#echo off
echo hi
echo hi!
start "" "%comspec%" /c one.bat
echo hello
pause

Related

How I can set a temporary title on batch script?

Is there a way to set a title in a batch script that will desappear when the program exits?
In my case, I want to set 'JCC' as a title, but using title JCC, the title will remain when the program exits.
Thanks for your help.
I was searching and I found a solution:
#echo off
if "%~1" equ ":SET-TITLE" goto %1
cmd /c "%~f0" :SET-TITLE %*
pause
exit /b
:SET-TITLE
shift /1
title JCC
This will work. It's recommended to delete the fourth line to make it usable and leave the SET-TITLE paragraph at the bottom of the file. Also remember that you must put an exit /b before the SET-TITLE paragraph.

How to get a batch file only processed if it's called from another batch file?

I am coding a batch file and it needs some more files. But they files should only be able to run using the call function from another batch file. My code looks like this:
call compileData.bat
pause
I want the compilerData.bat just starts when it's called from this one, not if its just started from Explorer or something other.
Can you please help me?
I have tried to find a solution on this problem in a whole hour!
You can use a parameter.
compileData.bat:
if "%1" neq "somestring" exit /b
REM rest of your code
Another.bat:
call compileData.bat somestring
pause
I cannot think of any way that would prevent the bare "run" of the called script. Possibly that might only be done using NTFS permissions.
What you can do quickly is something like this:
MOTHERBATCH.bat
call compileData.bat SomePASSPHRASE
compileData.bat
#echo off
if not "%1"=="SomePASSPHRASE" (
echo "You can not run this script directly, please run MOTHERSCRIPT.bat."
exit /B 1
)
echo "Passphrase is correct, code is executed..."
Set an environment variable in the parent script, then if that variable is not set or doesn't have the correct value in the children, they just exit with an error message explaining they aren't intended for standalone use. You really can't prevent someone from reverse engineering the code and forcing it to run.
You could put the children in a password protected zip file and have the parent unpack it just before calling them. Then when the parent is done, it deletes the unpacked scripts.
Do all of the above.
You can use a not so well known system variable named cmdcmdline.
I will explain a brief usage for you.
For brevity's sake we will have two very simple batch files.
Parent.bat
#echo off
call compiledata.bat
And compiledata.bat
#echo off
echo %cmdcmdline%
pause
When compiledata.bat is executed on its own this variable's value is the batch file itself.
C:\WINDOWS\system32\cmd.exe /c ""C:\Batch\CALL\compiledata.bat" "
But when compiledata.bat is called from parent.bat the variable's value is that of the calling parent.bat.
C:\WINDOWS\system32\cmd.exe /c ""C:\Batch\CALL\parent.bat" "
My suggestion is putting all your batch code into a single batch file and use subroutines. Open a command prompt window and run call /? for help on how to use subroutines which is nothing else than calling a batch file being embedded in current batch file.
A simple example:
#echo off
echo Running %~f0 %*
call :compileData %*
call :WaitForUser
rem The next line results in exiting processing of this batch file
goto :EOF
:compileData
echo/
echo Running subroutine compileData with the arguments: %*
rem Exit processing subroutine compileData and continue above
rem after the command line calling the subroutine compileData.
goto :EOF
:WaitForUser
echo/
pause
rem Exit processing subroutine WaitForUser and continue above
rem after the command line calling the subroutine WaitForUser.
goto :EOF
See also Where does GOTO :EOF return to? And take a look on DosTips forum topic ECHO. FAILS to give text or blank line - Instead use ECHO/ for the explanation on using echo/ to output an empty line.
Here's my solution:
when launched from the command line, %cmdcmdline% inherits the name from the base calling program, so it wouldn't be the name of the "middle man" calling your batch file
this is what I came up with. I had to use the "subroutine" method to get the variables properly expanded
Note: Edge Case: if you use complex paths with the batch files having the same name in different folders, you could run into an "Edge Case". If that is important to you, then you might have to further parse the file names. I'm not totally sure, it wasn't my use case so I didn't go further.
#echo OFF
setlocal EnableDelayedExpansion
call :myGetFileName "%CmdCmdLine%"
if /I "%sRet%"=="%~nx0" (
echo ************** Pause
) else (
echo ************** NO Pause
)
echo finished test
pause
exit
:myGetFileName
set "sRet=%~nx1"
exit /b

Batch script to move to another section of the script if there is no input from user

I am trying to get this script to jump to another section of the script if there is no input from the user.
Down at the if %input%== area.
What I'm trying to do is skip to the section where the script checks for .mp4 files and moves them if they are there. Am I supposed to set a variable or loop for that section? Thanks for any replies
#echo off
echo Checking for youtube-dl updates.
pause
youtube-dl -U
rem Enter the url or urls that you want to download from
set /p input="Enter the url(s) you want to download:"
rem Uses the youtube-dl continue (-c) option to download multiple files if not in a playlist
youtube-dl -c "%input%"
rem pause
if %input%=="" GOTO:EOF
cls
echo Download complete, please wait while files are transfered to appropiate folder
pause
for %%o in (.mp4) do move "*%%o" "E:\Documents\scripts\videos\"
if not exist do echo .mp4 files are no longer in this directory
pause
How about following script? This script waits for 3 seconds while "file.mp4" doesn't exist. It keeps to wait until the file exists. About "filename", you can change for your script.
#echo off
set waittime=3
set filename=file.mp4
:loop
if not exist %filename% (
Timeout /t %waittime% /nobreak > nul
goto loop
)
echo Find %filename%
When doing string comparison in batch you have to make sure, that both parts are equal, which in your case will never happen! In most languages strings have double quotes around them. In batch they usually do not.
To solve your problem enclose %input% in double quotes as well.
Note that it can be useful to do something like "x%input%"=="x" to prevent certain characters like <>|to be at the beginning of the comparison string.
You can check this on your own with these few lines:
#echo off
set /p input="Input something or nothing here "
echo %input%
echo "%input%"
pause
If you are hitting Return without any input you will see that only the bottom one will output "" which is the string you are comparing to.

Accessing Batch Functions in another batch file

Alright, so lets say we have a file called "lib.cmd" it contains
#echo off
GOTO:EXIT
:FUNCTION
echo something
GOTO:EOF
:EXIT
exit /b
Then we have a file called "init.cmd" it contains
#echo off
call lib.cmd
Is there anyway to access :FUNCTION inside of init.cmd? Like how bash uses "source" too run another bash file into the same process.
Change your lib.cmd to look like this;
#echo off
call:%~1
goto exit
:function
echo something
goto:eof
:exit
exit /b
Then the first argument passed to the batch file (%~1) will identify as the function you want to call, so it will be called with call:%~1, and now you can call it in init.cmd in this way:
call lib.cmd function
#echo off
(
rem Switch the context to the library file
ren init.cmd main.cmd
ren lib.cmd init.cmd
rem From this line on, you may call any function in lib.cmd,
rem but NOT in original init.cmd:
call :FUNCTION
rem Switch the context back to original file
ren init.cmd lib.cmd
ren main.cmd init.cmd
)
For further details, see How to package all my functions in a batch file as a seperate file?
The following takes #npocmaka solution and add support for calling functions in with arguments. Thanks #jeb for improvements. Let's save the following as lib.cmd:
#echo off
shift & goto :%~1
:foo
set arg1=%~1
set arg2=%~2
echo|set /p=%arg1%
echo %arg2%
exit /b 0
You can test it with:
call lib.cmd foo "Hello World" !
And it will print Hello World!.

Starting batch with a particular goto command

I want to know if it is possible to start a batch thin in a particular goto function from another batch?
thus not just starting another batch file but also have the "mother" batch select a particular goto option with in the "child"batch?
1.bat
call 2.bat /c goto :this
call 2.bat /c call :that
.
2.bat
if "%1"=="/c" shift & shift & %2 %3
goto :eof
:this
echo This!
goto :eof
:that
echo That!
goto :eof
EDIT: My original post was closest to correct. But I've corrected my mistake(s).
I double shift to remove %1 and %2 to the left, bringing any other variables passed to the %1 and %2 positions. I then execute %2 and %3 because the effect of the shifts won't take effect until the line is finished being executed / interpreted.
Just have the parent/mother batch file and pass a parameter to the child batch file.
mom.bat
#ECHO OFF
ECHO Here we go
CALL child.bat 3
PAUSE
child.bat
#ECHO OFF
IF "%1"=="1" Goto 1
IF "%1"=="2" Goto 2
IF "%1"=="3" Goto 3
EXIT
:1
ECHO 1!
PAUSE
EXIT
:2
ECHO 2!
PAUSE
EXIT
:3
ECHO 3!
PAUSE
EXIT
This example should echo 3! as the mother batch file passes the parameter 3 to the child batch file.
Yes, but it's a hack.
Normally you would do this with a bit of help from the called batch file.
main.bat
call second.bat :theFunction
*second.bat
goto %1
...
:theFunction
The hack uses a feature-bug, you only need the same label as in the second.bat.
And it only works if you start the second.bat without call
main.bat
call :theFunction
echo back in main
exit /b
:theFunction
second.bat
echo back in the func in main, this line will never reached
exit /b This line will also never reached
When the second.bat returns , it will return to the line after the call in main.bat
In the batch file that you are calling put this at the top
if not %1=="" goto :%1
In the batch file you are using to call it put
call b.bat labelname
Obviously this is limited depending on what you are trying to do but the basic functionality works.

Resources