Page 1 of 2

Is there a way to create a SUB without using a temp file ?

Posted: 30 Jan 2012 04:37
by Ed Dyreen
'

Code: Select all

>nul copy /A nul+nul "!$defines!.TMP"
:: (
   for /f "usebackq" %%? in (

      "!$defines!.TMP"

   ) do    set "!$defines!=%%?"
:: )
>nul del /f /q "!$defines!.TMP"

echo. This%$Sub%Works

Code: Select all

This→Works
Using XP :?:

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 11:57
by aGerman
Well the SUB character is created by the COPY command. There is no COPY without a resulting file :? Unfortunately I have no further idea.

Regards
aGerman

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 14:00
by Squashman
I know this may sound kind of hokey but why not just have that character as the last character in your batch file

Code: Select all

@echo off
:: (
   for /f "usebackq" %%? in (

      "%~nx0"

   ) do    set "sub=%%?"
:: )

echo. This%sub%Works

REM there is a hex 1A after this line. Doesn't paste into forum



output

Code: Select all

E:\batch files\SUB>getsub.bat
 This→Works

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 14:05
by Liviu
The (cmd) world would be a better more predictable place, had you never asked that question ;-)

Code: Select all

:: → @echo *** WHAT ???

@set /p "SUB=" <"%~f0"
@set "SUB=%SUB:~3,1%"

@echo this %SUB% works

Code: Select all

*** WHAT ???
this → works

Note that the "→" on the top line must be the single character ^Z code 0x1A.

Idea was to read the character with "set /p" off the first line of the batch file itself. Then I found out that "set /p" drops any trailing ^Z (and ^D) characters at the end of the line. So I added some text after ^Z. Then I found out that the batch attempted to execute the respective text. Apparently cmd doesn't play nicely with things it doesn't expect, like an EOF marker in the middle of a line, even if that's a comment line.

FWIW "set" and "set /p" have different tolerances to ^Z and ^D - "set" simply stops at the first ^Z, while "set /p" only drops both at the end of the line.

Code: Select all

C:\>set "eotsub=.^D.^Z.^D^Z"

C:\>set eotsub
eotsub=.♦.

C:\>set /p "eotsub="
.^D.^Z.^D^Z

C:\>set eotsub
eotsub=.♦.→.

Liviu

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 14:59
by aGerman
Good idea.
Based on your tests:

Code: Select all

^
::
@echo off
set /p "sub="<"%~f0"

echo. This%sub%Works

Regards
aGerman

Edit: No, sorry. This is not what it seems to be. The caret is part of the variable :(

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 16:34
by dbenham
aGerman wrote:Edit: No, sorry. This is not what it seems to be. The caret is part of the variable
That is easily solved with a substring operation.

Liviu wrote:The (cmd) world would be a better more predictable place, had you never asked that question ;-)
You can say that again :!:
within a batch file functions like a cross between white space and a command concatenation operator :shock:
But it doesn't play nicely with FOR /F

Code: Select all

@echo off
setlocal enableDelayedExpansion

set /p "sub="<"%~f0"
set "sub=%sub:~0,1%"
set sub

echo(
echo embeddedecho works
echo(
echo multiplesecho are ok
echo(
echo expanded%sub%echo fails
echo(
echo escaped^Echo is stripped
echo(
for %%A in (hellogoodbye) do @echo %%A
echo(
if 1==1 (echo true 1echo true 2) else (echo false 1echo false 2)
echo(
if 1==0 (echo true 1echo true 2) else (echo false 1echo false 2)
echo(
for /f %%A in ('echo 1echo 2') do echo for /f direct: %%A
for /f %%A in ('echo 1%sub%echo 2') do echo for /f immediate expansion: echo %%A
for /f %%A in ('echo 1!sub!echo 2') do echo for /f delayed expansion: echo %%A


result

Code: Select all

sub=→

embedded
works

multiples
are ok

expanded→echo fails

escapedEcho is stripped

hello
goodbye

true 1
true 2

false 1
false 2

for /f direct: 1
for /f immediate expansion: echo 1→echo
for /f delayed expansion: echo 1→echo


Dave Benham

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 17:58
by Liviu
dbenham wrote:

Code: Select all

echo(
echo expanded%sub%echo fails
echo(

Code: Select all

expanded→echo fails

Think you meant "expanded%sub%echo works".

And, thanks for the rest of the test cases. About the "doesn't play nicely with FOR /F" don't know that I have strong enough expectations about what "nicely" is in this context. If you replace the "for /f" lines with "for /f "tokens=1,2*"" and echo "%%B %%C" as well, then there will be some more output.

Liviu

P.S. If you save your or aGerman's code as say ctrlz.cmd, then the added bonus is that "type ctrlz.cmd" will output nothing at all. That must be the grandfather of all copy protections ;-)

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 18:26
by aGerman
dbenham wrote:
aGerman wrote:Edit: No, sorry. This is not what it seems to be. The caret is part of the variable
That is easily solved with a substring operation.

Of course. I was looking for a solution to read only the SUB character from the first line :wink: For a brief moment I wasn't aware that SET /P is reading the caret as well.

However, it causes crazy effects in a batch code :lol: I wonder if it could be useful ...

Liviu wrote:P.S. If you save your or aGerman's code as say ctrlz.cmd, then the added bonus is that "type ctrlz.cmd" will output nothing at all. That must be the grandfather of all copy protections ;-)

:shock: Interesting side effect :lol:

Regards
aGerman

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 18:53
by dbenham
Liviu wrote:
dbenham wrote:

Code: Select all

echo(
echo expanded%sub%echo fails
echo(

Code: Select all

expanded→echo fails

Think you meant "expanded%sub%echo works".
Actually no. I was referring to the ability of Ctrl-Z to function like the & operator. It no longer separates commands if it is the result of a variable expansion.

It totally blew my mind when I first saw your code with the :: remark hack followed by Ctrl-Z followed by @echo, and the echo still executed.

Upon further reflection, CMD.EXE must be treating Ctrl-Z as some kind of line terminator, because normally it is impossible to get anything to execute if a line starts with ::

Dave Benham

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 19:40
by Ed Dyreen
'
Didn't think I'd get a response at all ( I clearly underestimate you guys ).
This is more than my brain cell can absorb.

The thing is, I create many special chars using temp files in the current directory.
This is a problem when a batch is executed from a read only drive,
Of course I could use the temp dir, I thought it would be even better not to use any tempfile at all.
Squashman wrote:I know this may sound kind of hokey but why not just have that character as the last character in your batch file
That would be possible were it not for the fact, the last/first line I already use to embed jscript :(

Code: Select all

@set @a=0 /* Enable Jscript comment, must be first line in batch !
...
rem :: Disables Jscript comment, must be last line in batch ! */


Thanks, I'm impressed :P
(Don't be surprised I'll be asking about other chars in future.)

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 20:35
by dbenham
aGerman wrote:However, it causes crazy effects in a batch code :lol: I wonder if it could be useful ...
Very useful indeed :!:

:idea: Now we can embed VBScript in a batch file without resorting to a temporary file. Note - this code has embedded Ctrl-Z (ascii 26 decimal) characters that are visible in IE, but are not visible in Chrome. But when I copy and paste from Chrome into a text editor, the Ctrl-Z is there.

Code: Select all

::'@cscript //nologo //e:vbscript "%~f0" & exit /b
WScript.Echo "Example of a hybrid VBS / batch file"


We can even make the batch portion complex if we are willing to put up with the nasty ::' prefix. Batch labels need to be written as :'Label

Code: Select all

::'This is the batch portion
::' @echo off
::'
::'Test if GOTO works
::' goto :'TestGoto
::' echo goto failed & exit /b
::'
:'TestGoto
::' echo goto succeeded
::'
::'Now test if CALL works
::' call :'TestCall
::' exit /b
::'
:'TestCall
::' echo call worked
::' cscript //nologo /e:vbscript "%~f0"
::' exit /b

' The remainder is VBScript
WScript.Echo "Another more complicated example of a hybrid VBS / batch file"


Dave Benham

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 21:23
by Liviu
dbenham wrote:
aGerman wrote:However, it causes crazy effects in a batch code :lol: I wonder if it could be useful ...
Very useful indeed :!:

:idea: Now we can embed VBScript in a batch file without resorting to a temporary file.
...
We can even make the batch portion complex if we are willing to put up with the nasty ::' prefix. Batch labels need to be written as :'Label

Indeed... VERY nicely done!

Now, this is all too fresh, still. Hope there'll be more confirmations that it's working the same under various windows versions and 32b/64b.

Liviu

Re: Is there a way to create a SUB without using a temp file

Posted: 30 Jan 2012 22:20
by dbenham
You are using XP sp3 yes?

I can confirm XP Home Edition sp3, as well as Vista Home Premium sp2 64bit, and Vista 32 bit (not sure about specifics)

How about you aGerman? (or anyone else) Anyone have Windows 7 covered?


Dave Benham

Re: Is there a way to create a SUB without using a temp file

Posted: 31 Jan 2012 02:36
by alan_b
I always thought you could only create a SUB in a naval shipbuilders yard.
Never realized you could get a SUB without a periscope :roll:

Ctrl'Z or 0x1A would have been understood.

Alan

Re: Is there a way to create a SUB without using a temp file

Posted: 31 Jan 2012 02:51
by Ed Dyreen
'
No Submarine, Substitute :lol: You wanna be my english teacher alan ?

I use XP pro 32 nosp, sp1, sp2, sp3, I haven't seen CMD behave differently in any of these versions.
If there are, they're surely not obvious. I do unattended installs mostly.