pushd popd depend on batch filenames with which they run... why?

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

pushd popd depend on batch filenames with which they run... why?

#1 Post by nnnmmm » 30 Apr 2024 01:55

Code: Select all

"AAA BBB.bat" and "AAABBB.BAT" have the same batch as below
@ECHO OFF
CLS

SET "A1=%~dp0"
PUSHD "%A1%"

CD ..
SET "B1=%~dp0"

POPD
SET "C1=%~dp0"

ECHO %A1%
ECHO %B1%
ECHO %C1%
pause

Code: Select all

AAA BBB.bat produces
W:\Crysis 2\bin32\
W:\Crysis 2\
W:\Crysis 2\bin32\

but
AAABBB.bat produces
W:\Crysis 2\bin32\
W:\Crysis 2\bin32\
W:\Crysis 2\bin32\

the answers depend on the finenames whether they have spaces or not in their filenames, how could this be?
i also used CD .. or CD ..\

i need this as an answer to find a parent dir
W:\Crysis 2\bin32\
W:\Crysis 2\
W:\Crysis 2\bin32\

i almost always execute batch files from Ztree console, but when i ran the desktop shortcuts of AAABBB.bat and AAA BBB.bat
W:\Crysis 2\bin32\
W:\Crysis 2\bin32\
W:\Crysis 2\bin32\
was an answer

shodan
Posts: 89
Joined: 01 May 2023 01:49

Re: pushd popd depend on batch filenames with which they run... why?

#2 Post by shodan » 30 Apr 2024 02:51

Hi,

Just tried a simpler version

Code for AAABBB.bat

Code: Select all

@ECHO OFF
CLS
echo this is AAABBB.bat
echo 1 %~dp0
PUSHD %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
popd 
echo 3 %~dp0
Code for AAA BBB.bat

Code: Select all

@ECHO OFF
CLS
echo this is AAA BBB.bat
echo 1 %~dp0
PUSHD %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
popd 
echo 3 %~dp0

Code: Select all

this is AAABBB.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\

Code: Select all

this is AAA BBB.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
Next I tried without involving pushd/popd at all

Code for FFFFFF.bat

Code: Select all

@ECHO OFF
CLS

echo this is FFFFFF.bat
echo 1 %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
cd experimental
echo 3 %~dp0
Code for FFF FFF.bat

Code: Select all

@ECHO OFF
CLS

echo this is FFF FFF.bat
echo 1 %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
cd experimental
echo 3 %~dp0
Result

Code: Select all

this is FFFFFF.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\

Code: Select all

this is FFF FFF.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
I tried quoting %~dp0, this had no effect
experimental.zip
(1.33 KiB) Downloaded 806 times

shodan
Posts: 89
Joined: 01 May 2023 01:49

Re: pushd popd depend on batch filenames with which they run... why?

#3 Post by shodan » 30 Apr 2024 03:00

Tried adding filename to the tests

The code

Code: Select all

AAA BBB.bat


@ECHO OFF

echo this is AAA BBB.bat
echo 1 %~dp0
PUSHD %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
popd
echo 4 %~dp0

echo this is AAA BBB.bat part2
echo 1 %~dpn0
PUSHD %~dp0
echo 2 %~dpn0
cd ..
echo 3 %~dpn0
popd
echo 4 %~dpn0
AAABBB.bat


@ECHO OFF

echo this is AAABBB.bat
echo 1 %~dp0
PUSHD %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
popd
echo 4 %~dp0

echo this is AAABBB.bat part2
echo 1 %~dpn0
PUSHD %~dp0
echo 2 %~dpn0
cd ..
echo 3 %~dpn0
popd
echo 4 %~dpn0
FFF FFF.bat


@ECHO OFF

echo this is FFF FFF.bat
echo 1 %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
cd experimental
echo 3 %~dp0

echo this is FFF FFF.bat part2
echo 1 %~dpn0
PUSHD %~dp0
echo 2 %~dpn0
cd ..
echo 3 %~dpn0
popd
echo 4 %~dpn0
FFFFFF.bat


@ECHO OFF

echo this is FFFFFF.bat
echo 1 %~dp0
echo 2 %~dp0
cd ..
echo 3 %~dp0
cd experimental
echo 3 %~dp0

echo this is FFFFFF.bat part2
echo 1 %~dpn0
PUSHD %~dp0
echo 2 %~dpn0
cd ..
echo 3 %~dpn0
popd
echo 4 %~dpn0
GGG GGG.bat


@ECHO OFF

echo this is GGG GGG.bat
echo 1 "%~dp0"
echo 2 "%~dp0"
cd ..
echo 3 "%~dp0"
cd experimental
echo 3 "%~dp0"

echo this is GGG GGG.bat part2
echo 1 "%~dpn0"
echo 2 "%~dpn0"
cd ..
echo 3 "%~dpn0"
cd experimental
echo 4 "%~dpn0"
GGGGGG.bat


@ECHO OFF

echo this is GGGGGG.bat
echo 1 "%~dp0"
echo 2 "%~dp0"
cd ..
echo 3 "%~dp0"
cd experimental
echo 4 "%~dp0"

echo this is GGGGGG.bat part2
echo 1 "%~dpn0"
echo 2 "%~dpn0"
cd ..
echo 3 "%~dpn0"
cd experimental
echo 4 "%~dpn0"
The result

Code: Select all

C:\Users\user\BatchfileFrameWork\lib\experimental>AAABBB.bat
this is AAABBB.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
4 C:\Users\user\BatchfileFrameWork\lib\experimental\
this is AAABBB.bat part2
1 C:\Users\user\BatchfileFrameWork\lib\experimental\AAABBB
2 C:\Users\user\BatchfileFrameWork\lib\experimental\AAABBB
3 C:\Users\user\BatchfileFrameWork\lib\experimental\AAABBB
4 C:\Users\user\BatchfileFrameWork\lib\experimental\AAABBB

C:\Users\user\BatchfileFrameWork\lib\experimental>"AAA BBB.bat"
this is AAA BBB.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\
4 C:\Users\user\BatchfileFrameWork\lib\experimental\
this is AAA BBB.bat part2
1 C:\Users\user\BatchfileFrameWork\lib\experimental\AAA BBB
2 C:\Users\user\BatchfileFrameWork\lib\experimental\AAA BBB
3 C:\Users\user\BatchfileFrameWork\lib\AAA BBB
4 C:\Users\user\BatchfileFrameWork\lib\experimental\AAA BBB

C:\Users\user\BatchfileFrameWork\lib\experimental>FFFFFF.bat
this is FFFFFF.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
this is FFFFFF.bat part2
1 C:\Users\user\BatchfileFrameWork\lib\experimental\FFFFFF
2 C:\Users\user\BatchfileFrameWork\lib\experimental\FFFFFF
3 C:\Users\user\BatchfileFrameWork\lib\experimental\FFFFFF
4 C:\Users\user\BatchfileFrameWork\lib\experimental\FFFFFF

C:\Users\user\BatchfileFrameWork\lib\experimental>"FFF FFF.bat"
this is FFF FFF.bat
1 C:\Users\user\BatchfileFrameWork\lib\experimental\
2 C:\Users\user\BatchfileFrameWork\lib\experimental\
3 C:\Users\user\BatchfileFrameWork\lib\
3 C:\Users\user\BatchfileFrameWork\lib\experimental\
this is FFF FFF.bat part2
1 C:\Users\user\BatchfileFrameWork\lib\experimental\FFF FFF
2 C:\Users\user\BatchfileFrameWork\lib\experimental\FFF FFF
3 C:\Users\user\BatchfileFrameWork\lib\FFF FFF
4 C:\Users\user\BatchfileFrameWork\lib\experimental\FFF FFF

C:\Users\user\BatchfileFrameWork\lib\experimental>GGGGGG.bat
this is GGGGGG.bat
1 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
2 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
3 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
4 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
this is GGGGGG.bat part2
1 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGGGGG"
2 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGGGGG"
3 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGGGGG"
4 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGGGGG"

C:\Users\user\BatchfileFrameWork\lib\experimental>"GGG GGG.bat"
this is GGG GGG.bat
1 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
2 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
3 "C:\Users\user\BatchfileFrameWork\lib\"
3 "C:\Users\user\BatchfileFrameWork\lib\experimental\"
this is GGG GGG.bat part2
1 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGG GGG"
2 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGG GGG"
3 "C:\Users\user\BatchfileFrameWork\lib\GGG GGG"
4 "C:\Users\user\BatchfileFrameWork\lib\experimental\GGG GGG"
experimental.zip
(1.45 KiB) Downloaded 788 times

nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

Re: pushd popd depend on batch filenames with which they run... why?

#4 Post by nnnmmm » 30 Apr 2024 04:19

you got the same results as i did, is it possible to explain why?

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: pushd popd depend on batch filenames with which they run... why?

#5 Post by penpen » 01 May 2024 08:29

Though the output indeed depends on the filename used when calling the batch, the examples you have used shouldn't produce different results if being called in the same way.

If you call the file with a filename only (encapsulated in doublequotes), then you should get this output:

Code: Select all

D:\Crysis 2\bin32\
D:\Crysis 2\
D:\Crysis 2\bin32\
.

If you call the file with an absolute path as part of the filename (encapsulated in doublequotes), then you should get that output:

Code: Select all

D:\Crysis 2\bin32\
D:\Crysis 2\bin32\
D:\Crysis 2\bin32\
Any filename inbetween (such as example "bin32\filename.bat"), might produce different results on different directory levels.
The reason for that behaviour is that you demand a volume and path, which in case it isn't contained in the parameter %0 is added by using the actual directory.

At least under my Win10 it behaves exactly as expected.


penpen

nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

Re: pushd popd depend on batch filenames with which they run... why?

#6 Post by nnnmmm » 01 May 2024 10:41

If you call the file with a filename only (encapsulated in doublequotes), then you should get this output:

Code: Select all

"W:\Crysis 2\bin32\AAA BBB.bat" produces a "wrong" result as below
w:\Crysis 2\bin32\
w:\Crysis 2\bin32\
w:\Crysis 2\bin32\
-----------------------------------------------------------------------------
W:\Crysis 2\bin32>"AAA BBB.bat" produces a "correct" result
w:\Crysis 2\bin32\
w:\Crysis 2\
w:\Crysis 2\bin32\
-----------------------------------------------------------------------------
W:\Crysis 2\bin32>AAA BBB.bat is interpreted as AAA.EXE %1 as being BBB.bat so this is not even a consideration
-----------------------------------------------------------------------------

W:\Crysis 2\bin32>AAABBB.bat
W:\Crysis 2\bin32>"AAABBB.bat"
"W:\Crysis 2\bin32\AAABBB.bat"
these 3 produce all the same "wrong" results
w:\Crysis 2\bin32\
w:\Crysis 2\bin32\
w:\Crysis 2\bin32\
i ran out of all options here how i can run it correctly... so i like to claim this as an OS bug even if there is a "reason" for that behavior......  because i  cant run it any other way. 
>The reason for that behaviour is that you demand a volume and path, which in case it isn't contained in the parameter %0 is added by using the actual directory.
is volume a drive letter with : ?
"it isn't contained in the parameter %0 is added by using the actual directory." i will probably never understand this with my ability. if i were to make a rocket with this kind of behavior. it would crash into the planet mars upon arrival
i am not dead certain as this moment on what all my pushd popd used in my 1000 other batches will do when they are there to guide to delete things
but most of the time i used these 2 lines every step of the way to make sure to see if there was an anomaly

ECHO %A1%
pause

thanks for the help
i will find a detour to find a parent dir name

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: pushd popd depend on batch filenames with which they run... why?

#7 Post by penpen » 01 May 2024 18:47

What exactly are you looking for, when you write "i will find a detour to find a parent dir name"?

Are you looking for the parent name of the current directory, or the name of your currently running batch file's directory, or sth else?

I suspect you might look for sth like the following:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion
set "initial.dir=%cd%"

pushd "%~0\.."
set "batch.dir=%cd%"
cd..
set "batch.dir.parent=%cd%"
if "\" == "%batch.dir:~-1%" (
	echo(Warning: This batch file's current directory has no parent directory.
	set "batch.dir.parent="
)

popd

echo(initial.dir      = "%initial.dir%"
echo(batch.dir        = "%batch.dir%"
echo(batch.dir.parent = "%batch.dir.parent%"

goto :eof
penpen

nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

Re: pushd popd depend on batch filenames with which they run... why?

#8 Post by nnnmmm » 01 May 2024 23:32

>What exactly are you looking for, when you write "i will find a detour to find a parent dir name"?

it may be my boring story, but goes something like this
i am nornamlly expecting this way W:\Crysis 2>Crysis2.exe
but this program runs this way W:\Crysis 2\Bin32>Crysis2.exe from its sub
no matter what, i always create Crysis2.bat to support Crysis2.exe
Crysis2.bat contains like
delete cache, log, some savedfiles, may overwrite some settings, and screenshot
and SET /P VAR=INPUT: to select mods and etc
-----------------------------------------------------------
Crysis2.bat will be called by another bacth like !!!!2 Crysis2.bat
!!!!2 Crysis2.bat's file name contains the INFO as to if it is
a dosbox needed, win game or scummVM or other emulators or win programs

i have ~1000 files like Crysis2.bat form and have ~1000 files like !!!!1 Crysis2.bat form
throughout the pc HDDs

what !!!!2 Crysis2.bat should have had only
@ECHO OFF
SET "A1=%~dp0Bin32"
PUSHD "%A1%"
IF EXIST "!emulator - setup.bat" CALL "!emulator - setup.bat"
CALL "%A1%\Crysis2.bat"

but not this way, this was a temp detour, it violates the format, before the number of this kind of ill and mixed format starts to increase, i must correct it
@ECHO OFF
IF /I EXIST "%~dp0LogBackups" RMDIR /s /q "%~dp0LogBackups"

@ECHO OFF
SET "A1=%~dp0Bin32"
PUSHD "%A1%"
IF EXIST "!emulator - setup.bat" CALL "!emulator - setup.bat"
CALL "%A1%\Crysis2.bat"
--------------------------------------------------
since this following one doesnt work in Crysis2.bat and tries to delete other directory, i must do a string manipulation to find the parent dir name, i am capable of doing it but it takes a lot of energy out of me unlike CD ..
SET "AA1=%~dp0"
PUSHD "%AA1%"
CD ..
SET "AA2=%~dp0"
POPD
SET "AA3=%~dp0"
PUSHD "%AA1%"
ECHO %AA1%
ECHO %AA2%
ECHO %AA3%
PAUSE
CLS
IF /I EXIST "%AA2%LogBackups" RMDIR /s /q "%AA2%LogBackups"
----------------------------------------------------
then
!!!!2 Crysis1.bat will be executed by a batch file "central.bat"
central.bat is built with some batch intelligence, it can be run anywhere and finds the 1st parent dir and the 2nd and 3rd layer of the path for IT to make a decision among 10s and 100s and 1000s sub directories(not layers) within it, which will save my clicking and scrolling time and labor otherwise.

and best of all, batch is OS independent, upgrade independent, or it would take 6 months for me in the past to get the ALL settings right, now only takes 10 minutes after installing windows. because nothing is linked or integrated through the explorer in my windows. i used xtree for DOS and now using ztree for windows.
making drive letter, directory name and registry independent with programs is my goal in batch

nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

Re: pushd popd depend on batch filenames with which they run... why?

#9 Post by nnnmmm » 02 May 2024 01:01

pushd "%~0\.."
set "batch.dir=%cd%"
cd..

%0 gives you crysis2.bat
%~0 gives you without quotes
what is \.. for?
what does crysis2.bat\.. stand for?
what does it mean by cd.. and not by CD .. ?

i got it the simplest form after staring at your code for long, now i am like ....what couldnt i think of this before?
I need to stare at %~dp0 more as to what 0 actually means, why not understanding it instead of staring it, cause it wouldnt make a difference for me at this time

SET "AA1=%CD%"
PUSHD "%AA1%"
CD ..
SET "AA2=%CD%"
POPD
IF /I EXIST "%AA2%\LogBackups" RMDIR /s /q "%AA2%\LogBackups"
PAUSE

i went back and started to change %~dp0 to %CD% for few trials, it didnt work
%CD% didnt work it seemed to be executed from where the command prompt was located and not where the batch file was located, this was probably why i used %~dp0 long long ago
%CD% gives two formats W:\ and W:\ABC which gives an extra difficulty
%~dp0 gives one format W:\ and W:\ABC\

just prior to the usage of these two lines, other batch already used PUSHD "%~dp0"
SET "AA1=%CD%"
PUSHD "%AA1%"

it would be like this, that was why %CD% worked
PUSHD "%~dp0"
SET "AA1=%CD%"
PUSHD "%AA1%"

my interconnected batches are calling each other like 5 ~ 6 times
A1.bat is called by A2.bat
A2.bat is called by central.bat

central.bat also controls other batches like C1.bat
C1.bat is called by C2.bat
C2.bat is called by C3.bat
A1.bat finally gets to be used by C3.BAT

so with vague memory, it was probably impossible for me to trace where the command prompts are located for every situation
it was maybe better for me to pivot the location where that each specific batch is... or something like that

"%~0\.." seems telling me the location batch....

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: pushd popd depend on batch filenames with which they run... why?

#10 Post by penpen » 04 May 2024 15:35

The reason why 'pushd "%~0\.."' works is pretty simple:
Your batch file was successfully started from an initial location with the content of %0, so it must contain a path from the initial location to the batch file location.
The 'pushd' command expects a path to a directory and doesn't expect any name in it to be a filename.
So 'pushd' interprets the filename as if it were a subdirectory of that directory in which the batch file is located.
Because the name ".." is the default name for the current parent directory, appending it to the path (seperated by the '\'-character) results in a path string to the location of the batch file.
That no such directory exists doesn't matter, because (for performance reasons) 'pushd' normalized the path string before changing the current directory (so "Z:\subdir2\subdir1\foo.bat\.." is normalized to "Z:\subdir2\subdir1").

However, because %0 might be a location relative to the initial location from which you started the batch file, that string might not contain a valid path for any other location.
So "%~0\.." doesn't neccessarily tell you the location of your batch from whereever you are.
Therefore you should change to that directory and store the fully qualified path of the current directory ("%cd%") in an environment variable, because that string is valid no matter your location.
In case you want the current directory to consistently end on a backslash character ('\'), you might use "%__cd__%" instead.

I'm not sure i understand all your requirements (sorry), so I'm not quite sure, whether or not it's the best approach to use pushd here. There is a limit of how many instance of batch files/setlocal/pushd can be nested (~= run at the same time), which is sytstem dependent but should be around 300.
But as long as you get no error message that informs you of a stack recursion counter that has exceeded its limit of n instances or similar, you are probably fine (hopefully i misunderstand the part with "~1000 files like" and you only start two/three batch instances at the same time instead).
In case you get such error messages, it might be an option to initially change to the batch file location before executing that batch and ensure that your batch file ends in the same location it started from. Also in case you don't need a batch to take back control you might just refer control to a batch, instead of calling it (= instead of 'call "subdir\foo.bat"' just use '"subdir\foo.bat"').


Finally i wanted to say that i wouldn't fully agree with your statement "batch is OS independent, upgrade independent ...".
I would agree if you limit the OSes to for example to Windows versions from XP onwards.
I doubt your solution will work for OSes like MS-DOS 6.22, Solaris, Zeta, ... .


penpen

nnnmmm
Posts: 141
Joined: 26 Aug 2017 06:11

Re: pushd popd depend on batch filenames with which they run... why?

#11 Post by nnnmmm » 06 May 2024 20:46

%~0\..
if crysis2.bat\.. = crysis2.bat\c:\ABC
i will take crysis2.bat\c:\ABC as c:\ABC\crysis2.bat

>However, because %0 might be a location relative to the initial location from which you started the batch file, that string might not contain a valid path for any other location.
i run batches from ztree or under its environment, sometimes ztree takes the %0 and %1 internally. this was why i developed a habit of echoing as below
echo %~dp0
echo %~dp1
echo %~dp2
echo %~dp3
pause

>"~1000 files like"
1000 batch files are not interconnected, there are 300 different sets of batch files that use 2~3 interconnected batch files. c1.bat c2.bat c3.bat d1.bat and d2.bat are common interconnected shared batch files, only 5 files exist. central.bat connects them with batch intelligence, because i dont use LNK files that are OS SETUP dependent and need massive manual labors to individually correct or edit.
so if there was a problem of my understanding %~dp0, it would take 900 batch file editing, this topic was such a case, things happened, caused a problem and i didnt know why... but limited to the batch that didnt have a SPACE in its filename and next time i will slowly correct them

>i wouldn't fully agree with your statement "batch is OS independent,
i should have said with more precision, or independent "enough"
for me at the moment, examples
windows OS doesnt have what nircmd has
Wait 1400 millisecond
BEEP frequency and duration in millisecond
XP doesnt have timeout.. and etc
even 1980s TRUE basic and maybe gwbasic has these functions

thanks again for your big help

PS
instead of 'call "subdir\foo.bat"' just use '"subdir\foo.bat"'
i am not sure exactly what call does, but without it, it used to cause an error not finding a batch or give me a wrong path info or something.
and now i am editing
@exit /B
@exit
@setlocal
before ending a batch file. i think basic calls it intensive parameters (didnt use the word local there) in which the usage was limited in that file only

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: pushd popd depend on batch filenames with which they run... why?

#12 Post by penpen » 10 May 2024 10:14

You got sth wrong with "%~0\..", so let's consider starting the batch file "crysis2.bat" from the current directory "c:\ABC\Bin32".
Here the string "%~0\.." is expanded to "crysis2.bat\..".
The string neither starts with a "\\", nor with a vomue designator (like for example "X:").
Therefore it is a path relative to the current directory, so here it refers to "c:\ABC\Bin32\crysis2.bat\..".
Then the path is simplified by removing all local references to the parent directory ".." and the local path element before that reference,
resulting in the path string "c:\ABC\Bin32", which is the path of the folder in which "crysis2.bat" is located.


With "However, because %0 might be a location relative to the initial location from which you started the batch file, that string might not contain a valid path for any other location." i meant,
that calling a relative path like "crysis2.bat" in the above example only works if your current directory is equal to the location fromn where you started the batch file.
So if you change the current directory to somewhere else, then "%~dp0", as well as "%~0\.." is expanded to a wrong path.
That's the reason, why i used pushd, to change to the path of the batch file and stored the fully qualified path of the current directory in an environment variable and 'poped' back to the initial path.


Luckily i misunderstood the "~1000 files like" part; if you only call 2 or 3 batch files, then you don't need to avoid using the "call"-command.

Regarding the 'call'-command:
If you execute a batch file B without using the 'call' command, then A is terminated and then B is started.
If you execute a batch file B using the 'call' command, then A is (kinda) paused until B is terminated.


penpen

shodan
Posts: 89
Joined: 01 May 2023 01:49

Re: pushd popd depend on batch filenames with which they run... why?

#13 Post by shodan » 13 May 2024 19:20

Just for fun, I have asked chatgpt about this

here is chatgpt classic

https://chat.openai.com/share/1591e9b7- ... e6f5d2f968

here is chatgpt 4o, today's newest model

https://chat.openai.com/share/ee8e7ba3- ... 6bef333484

The best it got, is to use %CD% if you pushd a file with space

It doesn't seem to understand there's a bug of somekind with the %~dp0 expansion after a pushd

Code: Select all

@ECHO OFF
CLS
SET "A1=%~dp0"
PUSHD "%A1%"
CD ..
SET "B1=%CD%"
POPD
SET "C1=%~dp0"
ECHO %A1%
ECHO %B1%
ECHO %C1%
pause
Also suggests testing if the bug also exists with the subsequent argument set to a file with or without spaces in the name ?

Code: Select all

@ECHO OFF
CLS

SET "A1=%~dp0"
SET "A2=%~dp1"
ECHO A2 Initial: %A2%

PUSHD "%A1%"
CD ..
SET "B1=%~dp0"
SET "B2=%~dp1"

POPD
SET "C1=%~dp0"
SET "C2=%~dp1"

ECHO A1: %A1%
ECHO B1: %B1%
ECHO C1: %C1%
ECHO A2: %A2%
ECHO B2: %B2%
ECHO C2: %C2%
pause

penpen
Expert
Posts: 2009
Joined: 23 Jun 2013 06:15
Location: Germany

Re: pushd popd depend on batch filenames with which they run... why?

#14 Post by penpen » 14 May 2024 05:36

To be clear: There is no bug, only wrong expectations.

Post Reply