Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

What could be causing %3$ to not work?

Jul
244
6
Pretty simple situation, just testing command line parameters to try to use some smarter methods.

But they aren't working for me.

Script:

Code:
@echo off
echo 3- is %3$
echo -3 is %-3$
echo # is %#
echo 0 is %1
echo 1 is %1
echo 2 is %2
echo 3 is %3
echo 4 is %4
echo 5 is %5
echo 6 is %6
echo * is %*
echo @ is %@

Output:

Code:
C:\bat>test-command-line-parameters 1 2 3 4 5 6 7 8 "9"
3- is 3$
-3 is 1$
# is 9
0 is 1
1 is 1
2 is 2
3 is 3
4 is 4
5 is 5
6 is 6
* is 1 2 3 4 5 6 7 8 "9"
@ is "1" "2" "3" "4" "5" "6" "7" "8" "9"

How the heck is %3$ not even working? Surely I must be doing something wrong....

1685370561237.png
 
Am I crazy? These are straight from the help file...
1685370758629.png
 
For reference:
1685370904292.png
 
What does SETDOS report? I'm interested in the "Parameters" and "Expansion" values in particular.
 
Thanks! It is:

1685371714953.png
 
You've changed the parameter char. (And the other two as well; to be 4DOS compatible?)

If you want to use that syntax, you should either use your customized parameter char:
Code:
echo 3- is %3&
echo -3 is %-3&

Or else change it back, maybe temporarily:
Code:
@echo off
setlocal
setdos /p36
echo 3- is %3$
echo -3 is %-3$
echo # is %#
echo 0 is %1
echo 1 is %1
echo 2 is %2
echo 3 is %3
echo 4 is %4
echo 5 is %5
echo 6 is %6
echo * is %*
echo @ is %@
endlocal
 
Dang! I'd always wondered how parameter char came into play, and I think it was just decades of avoiding learning this.

And yes, everything I do is legacy support of myself (ha), so if that's not the default values, it's the values i've carried with me since the 4DOS migration

thank you!!!
Maybe it's time I should change it back. I have no way of unit testing my 1000+ bat files though.
 
Maybe it's time I should change it back. I have no way of unit testing my 1000+ bat files though.

Aw jeez, don't do that to yourself! If you have hundreds of batch files using the 4DOS characters, then stick with that. Just remember that where Rex says %1$, to you it means %1&.
 
I'm not going to change separator back, that's or sure. Though it sure makes using grep with start-of-line regexes hard if i forget to enclose them in quotes.

Crap. That might be why I didn't want "$" as a parameter character as well.

I really would rather have the BAT files be "proper" and portable, though!
It sounds like an opportunity for self-challenge
 
This is very interesting!! Thank you!!

20 years ago, I did not realize you could enclose grep's regular expression in quotes. ‍

[EDIT: I put a woman-facepalm emoji here but the forum has a unicode bug and it ended up as. ♀️. As an experiment i'm going to put the man-facepalm emoji here and see what happens: ‍♂️ . Lol. Okay. Emojis get wiped, but facepalm emojis get reduced to their gender. Very strange]

Anyway, This erroneous conclusion lead me to 25 yrs of bad habits , That I'm only fixing today thanks to your excellent help

TCC would of course "attack" [:)] the character if it was not in quotes, so rather than learn how to grep correctly, I painted myself into a horrible corner.

SOLUTION: I reviewed ALL my grep calls. ALL of them. How? WITH GREP OF COURSE

Code:
for %ext in (bat btm pl py) editgrep "gr[e ]p*.*\$" *.%ext

^ Editgrep greps files and opens them in my text editor for me. So I grepped for instances of grep (which i sometime have aliased as gr) followed by a $. This opened about 50 files. It only took about 10 minute sof review. I had to enclose about 15 instances of grepped "$"s that weren't in quotes. I think there as at most 1 other $ that might have been a problem.




Thank you for your time!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Slowly moving out of the 4DOS age, lol.



You might like this tall tale (or maybe it's not that tall after all), but I only regularly run one .cmd file!

My setpath.bat that sets my path does so generatively, and as such, my generated path is never actually stored or written down anywhere. Except the last line of setpath.bat is:
Code:
path >c:\bat\setpath.cmd

This let's me set my path from inferior^H^H^H^H^H^H^H^ anaconda command line when playing with python.




I was very much a dig-in-the-sand person, when I got things working I would try hard not to change them. ‍♀️ Recently I've had a change of heart and am hardening so many of my old scripts to be better, more resilient, and "alzheimer's proof" -- which is also "Widow proof" because I want my wife to be able to understand and fix my things after I'm gone.

Today i've mostly just been playing with errorlevel stuff and basic prints and learning how to use parenthesis in if statements. How much i've built with TCC over my life is probably top 1% of users, but there were huge glaring holes in my knowledge that I'd just been working around forever.

I'd been using GOTOs with my IF statements. I never used parenthesis until this week. I never used an "else" in a .BAT file until this week. I just avoided it all. Now that I'm doing it the right way, i'm definitely running into weird issues with closing parenthesis being errors after I have a "%+ REM" on the end of a line or after a call a bat file from within the parenthesis. I'm not sure what that's about, I just have to teach myself new best practices.


Thank you!



And if you're still reading, here's my setpath.bat for giggles:

Code:
@Echo OFF
:Echo ON

if "%DEBUG_DEPTH%" eq "1" echo * setpath.bat (batch=%_BATCH)

::::: DOCUMENTATION:
    :: WHAT THIS DOES:     set PATH for all computers!
    :: ASSUMES:         %MACHINENAME% and %OS% (95,98,ME,2K,XP,7,10) has already been set in the environment, and C:\BAT\ and C:\UTIL\ copied from another Clairevironment

::::: First, unset the old path:
    unset /q PATH

::::: THEN, we add the very basic path that we want ANYWHERE:
    :Base_Clairevironment_Related_1
        gosub AddFolderToPathEndOnlyIfItExists  c:\util\e
        gosub AddFolderToPathEndOnlyIfItExists  c:\util\aspell\bin
        gosub AddFolderToPathEndOnlyIfItExists  c:\cygwin\bin
        gosub AddFolderToPathEndOnlyIfItExists  c:\cygwin64\bin
        gosub AddFolderToPathEndOnlyIfItExists  c:\MinGW\bin
    :Work_Related_1
        :osub AddFolderToPathEndOnlyIfItExists  %DROPBOX%\work\bat\
        gosub AddFolderToPathEndOnlyIfItExists  C:\bat\work
    :Base_Clairevironment_Related_2
        gosub AddFolderToPathEndOnlyIfItExists  c:\perl\bin
        ::: Changed these 3 from AddToPathBeg to AddToPathEnd on 20230503:
            gosub AddFolderToPathBegOnlyIfItExists  C:\perl\c\bin
            :osub AddFolderToPathEndOnlyIfItExists  C:\perl\c\bin
            gosub AddFolderToPathBegOnlyIfItExists  c:\perl\perl\bin
            :osub AddFolderToPathEndOnlyIfItExists  c:\perl\perl\bin
            gosub AddFolderToPathBegOnlyIfItExists  c:\perl\perl\site\bin
            :osub AddFolderToPathEndOnlyIfItExists  c:\perl\perl\site\bin
        gosub AddFolderToPathEndOnlyIfItExists  c:\python23
        gosub AddFolderToPathEndOnlyIfItExists  c:\python
        gosub AddFolderToPathEndOnlyIfItExists  %UTIL2%\git\bin
        gosub AddFolderToPathEndOnlyIfItExists  %UTIL2%
        gosub AddFolderToPathEndOnlyIfItExists  %UTIL%\sysinternals
        gosub AddFolderToPathEndOnlyIfItExists "C:\util\xml"
    :Programs_That_May_Be_Installed_That_I_Script_With_Or_Use
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles%\FastPictureViewer"
        gosub AddFolderToPathBegOnlyIfItExists "%ProgramFiles%\ImageMagick"
        gosub AddFolderToPathBegOnlyIfItExists "%[ProgramFiles(x86)]\ImageMagick-6.3.3-Q16"
        gosub AddFolderToPathBegOnlyIfItExists "%ProgramFiles%\nodejs"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles%\PHP"
        gosub AddFolderToPathBegOnlyIfItExists "%ProgramFiles\SlikSvn\bin"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles\TortoiseSVN\bin"
                                                               SET C_RSYNCD_BIN=0
        gosub AddFolderToPathEndOnlyIfItExists "c:\rsyncd\bin"
                                      if isdir "c:\rsyncd\bin" set C_RSYNCD_BIN=1
    :Java_Versions
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles%\Java\jdk1.6.0_35\bin"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles%\Java\jdk1.7.0_25\bin"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles%\Java\jdk1.7.0_76\bin"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles(x86)%\Java\jre6\bin"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles(x86)%\Java\jdk1.7.0_25\bin"
        gosub AddFolderToPathEndOnlyIfItExists      "%ProgramFiles%\Common Files\Oracle\Java\javapath"
        gosub AddFolderToPathEndOnlyIfItExists "%ProgramFiles(x86)%\Common Files\Oracle\Java\javapath"
    :Oracle_Versions
        gosub AddFolderToPathEndOnlyIfItExists  C:\oraclexe\app\oracle\product\11.2.0\server\bin
    :Work_Inspired
        gosub AddFolderToPathEndOnlyIfItExists  "%ProgramFiles%\Common Files\Microsoft Shared\Microsoft Online Services"
        gosub AddFolderToPathEndOnlyIfItExists  "%ProgramFiles(x86)%\Common Files\Microsoft Shared\Microsoft Online Services"
        gosub AddFolderToPathEndOnlyIfItExists  "%ProgramFiles%\Intel\WiFi\bin\"
        gosub AddFolderToPathEndOnlyIfItExists  "%ProgramFiles%\Common Files\Intel\WirelessCommon\"
    :Work_Related_2
        :DEBUG: echo  @UPPER[%%MACHINENAME]  is %@UPPER["%MACHINENAME"]
        gosub AddFolderToPathEndOnlyIfItExists "C:\perl\instantclient"
    :Stuff_We_Want_At_The_Very_End
        gosub AddFolderToPathEndOnlyIfItExists "C:\Program Filnes\Git\bin"
    :2023
        :MiniConda/Anaconda/conda.exe stuff
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\anaconda3\condabin\
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\anaconda3\Scripts\
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\anaconda3\Library\bin\
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\miniconda3\condabin\
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\miniconda3\Scripts\
            gosub AddFolderToPathEndOnlyIfItExists  C:\ProgramData\miniconda3\Library\bin\
            gosub AddFolderToPathEndOnlyIfItExists "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\bin"
            gosub AddFolderToPathEndOnlyIfItExists "C:\Program Files\Graphviz\bin"
            :gosub AddFolderToPathEndOnlyIfItExists
        :SmartGPT, Chocolatey
            gosub  AddFolderToPathEndOnlyIfItExists %USERPROFILE%\.cargo\bin
            gosub  AddFolderToPathEndOnlyIfItExists %allusersprofile%\chocolatey\bin\
::::: MOST IMPORTANT STUFF: machinename-specific, then OS-specific BATs, then main/normal/non-specific -- for both BATs and UTILs:
    gosub AddFolderToPathBegOnlyIfItExists C:\UTIL\
    gosub AddFolderToPathBegOnlyIfItExists C:\UTIL\%OS%
    gosub AddFolderToPathBegOnlyIfItExists C:\UTIL\%MACHINENAME%
    gosub AddFolderToPathBegOnlyIfItExists C:\BAT\
    gosub AddFolderToPathBegOnlyIfItExists C:\BAT\%OS%
    gosub AddFolderToPathBegOnlyIfItExists C:\BAT\%MACHINENAME%
    gosub AddFolderToPathBegOnlyIfItExists C:\BAT\beta

::::: WORK-MACHINE STUFF THAT PRECEDES OUR NORMAL PATH:
    :if %@UPPER["%MACHINENAME"] eq "WORK" gosub AddFolderToPathBegOnlyIfItExists  %DROPBOX%\work\bat
    :if %@UPPER["%MACHINENAME"] eq "WORK" gosub AddFolderToPathBegOnlyIfItExists  %DROPBOX%\work\bat\eAdjudication

::::: Now include the OS'es binaries at the end of the path:
    :95/98/ME era:
        if "%OS%" == "95" .or. "%OS%" == "98" .or. "%OS%" == "ME" gosub AddFolderToPathEndOnlyIfItExists c:\windows\command
        if "%OS%" == "95" .or. "%OS%" == "98" .or. "%OS%" == "ME" gosub AddFolderToPathEndOnlyIfItExists c:\windows
        if "%OS%" == "95" .or. "%OS%" == "98" .or. "%OS%" == "ME" gosub AddFolderToPathEndOnlyIfItExists c:\windows\system
        if "%OS%" == "95" .or. "%OS%" == "98" .or. "%OS%" == "ME" gosub AddFolderToPathEndOnlyIfItExists c:\4DOS

    :NT/2K era:
        if "%OS%" == "NT" .or. "%OS%" == "2K"                     gosub AddFolderToPathEndOnlyIfItExists c:\winnt\system32
        if "%OS%" == "NT" .or. "%OS%" == "2K"                     gosub AddFolderToPathEndOnlyIfItExists c:\winnt
        if "%OS%" == "NT" .or. "%OS%" == "2K"                     gosub AddFolderToPathEndOnlyIfItExists c:\4NT

    :XP/VISTA/7 ERA - DEFAULT:
        :if "%OS%" == "7"  .or. "%OS%" ==  "XP" .or. "%OS%" == "10"
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\system32
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\Wbem
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\WindowsPowerShell\v1.0\
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\System32\WindowsPowerShell\v1.0\
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\System32\OpenSSH
        if "%OS%" ==  "XP" gosub AddFolderToPathEndOnlyIfItExists c:\4NT
        gosub AddFolderToPathEndOnlyIfItExists c:\TCMD
        gosub AddFolderToPathEndOnlyIfItExists c:\TCC

    :10/11 ERA - DEFAULT:
        gosub AddFolderToPathEndOnlyIfItExists %SystemRoot%\system32\Wbem


goto :END

    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
        :::::::::::::::::::::::::::::::::::::::::::::::::::
        :AddFolderToPathBegOnlyIfItExists [folder]
            if isdir %folder% PATH=%folder%;%PATH
        return
        :::::::::::::::::::::::::::::::::::::::::::::::::::
        :::::::::::::::::::::::::::::::::::::::::::::::::::
        :AddFolderToPathEndOnlyIfItExists [folder]
            :echo if isdir %folder% PATH=%PATH;%folder%
                  if isdir %folder% PATH=%PATH;%folder%
        return
        :::::::::::::::::::::::::::::::::::::::::::::::::::
    ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:END

REM * Save our dynamically-generated path as a .cmd file that can be run in other commandlines such as PowerShell & Anaconda
path >c:\bat\setpath.cmd


And now some quick emoji tests:
sunglasses=
eyeball=
red flag=
Strange. I wonder what is unique about the facepalm emojis. All other ones get wiped.
 
Last edited:
Back
Top