WAD Multiple TEE causese weird variable scoping?

Dec 13, 2011
3
0
Usually when I find something weird in TCC/4NT, it's some kind of CMD compatibility. But, I can't see how this could be intentional! I have repro'd in both TCC LE 13.00. 09 and 11.00.40. We are long-time 4NT users here at our shop.

I have made a very simple repro case for this. The assignment to EXAMPLE_VAR inside the block seems to have no effect when multiple TEEs are used on the echo statement.

As you might imagine, this code originally was meaningful and wasn't TEEing to the NUL device!

------------------------------------------------------
Batch file:

@echo off
set EXAMPLE_VAR=0
(
echo This line uses TEE | tee /a nul | tee nul
set EXAMPLE_VAR=1
)
echo After block: EXAMPLE_VAR = %EXAMPLE_VAR

---------------------------------------------------------
Output:

This line uses TEE
After block: EXAMPLE_VAR = 0
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
4,491
90
Albuquerque, NM
prospero.unm.edu
I think what's happening is that your second SET is being executed in one or the other of the right-hand shells. You can use more parentheses to clarify your intentions for the parser:

Code:
@echo off
set EXAMPLE_VAR=0
(
   ( echo This line uses TEE | tee /a nul | tee nul )
set EXAMPLE_VAR=1
)
echo After block: EXAMPLE_VAR = %EXAMPLE_VAR

Or, if you don't actually need the command group, get rid of all the parentheses.
 

samintz

Scott Mintz
May 20, 2008
1,511
18
Solon, OH, USA
The issue is the command group as near as I can tell.
(
command1
command2
)

is essentially: command1 & command2

So, looking at your example, it would appear that the group is causing the set to execute inside one of the piped processes. That keeps the original value intact.

-Scott
 
Dec 13, 2011
3
0
Thank you for your very quick replies on this one, gentlemen. This test case is very contrived; originally this was an IF group inside a FOR group.

Scott, I like the direction you're going with this. But, why does this new version work properly? The only change is to remove the second TEE. I would expect this version to exhibit the same behavior.

@echo off
set EXAMPLE_VAR=0
(
echo This line uses TEE | tee /a nul
set EXAMPLE_VAR=1
)
echo After block: EXAMPLE_VAR = %EXAMPLE_VAR
 

Charles Dye

Super Moderator
Staff member
May 20, 2008
4,491
90
Albuquerque, NM
prospero.unm.edu
I was able to replicate your issue with two FINDs instead of two TEEs. With just one FIND, the SET executes in the main shell as expected. I'm pretty sure, therefore, that it isn't multiple TEEs; it's multiple pipes.
 

rconn

Administrator
Staff member
May 14, 2008
12,404
152
Scott, I like the direction you're going with this. But, why does this new version work properly? The only change is to remove the second TEE. I would expect this version to exhibit the same behavior.

TCC goes through some gymnastics to move the compound argument following a pipe to execute in the parent shell instead of the child pipe shell. (Strictly speaking this isn't the technically correct way to parse the line, but 99.999% of the time the user doesn't realize that piped processes execute in a different shell and can't modify the parent environment.)

That is impossible to do when you're nesting pipes -- TCC has no idea whether you want to execute the SET in the parent, the child pipe process, or the child of the child pipe process. (The latter is actually what you asked it to do.) You'll have to use command grouping to force the SET to the proper shell.
 
Dec 13, 2011
3
0
Thanks Rex, and everyone. This has been very educational. I really had no idea that so much magic was going on behind the scenes with multiple pipes, or groups! I certainly have learned something today.

Sometimes, the very easy syntax of groups can lead to surprising results. Groups are not just "inline gosubs". It is easy to think of them that way because they are both EOL-delimited. But that is a very sloppy way of thinking about groups, as Scott illustrated by rephrasing my group as a single-liner with command-separators. *That* is how we should be thinking when we use multiline groups!

Let me add one final example so that we can all see how surprising this can be. Though, this is really not very surprising considering what we've learned today.
--------------------------------------------------
@echo off
set EXAMPLE_VAR=0
(
echo This line uses multiple pipes | tee /a nul | tee nul
set EXAMPLE_VAR=1
echo Inside block: EXAMPLE_VAR = %EXAMPLE_VAR
)
echo After block: EXAMPLE_VAR = %EXAMPLE_VAR

---------------------------------------------------

This line uses multiple pipes
Inside block: EXAMPLE_VAR = 1
After block: EXAMPLE_VAR = 0
----------------------------------------------------
Not only does the SET occur in a different shell, but also the subsequent echo! After the use of multiple pipes, the rest of this group has been relocated to a subprocess. That is pretty neato.

Thank you all so much! I am going to take much greater care with my groups.
 
Similar threads
Thread starter Title Forum Replies Date
MickeyF TCC crashing when copying multiple files (now resolved) Support 6
N Unable to bind multiple keys to the same key mapping directive Support 9
vefatica Console not redrawn in BTM or with multiple commands Support 4
C duplicate files in multiple plugin sites Support 9
kb6ojs ALIAS with multiple commands? Support 9
vefatica How do I do this with a multiple-line DO? Support 7
Joe Caverly Multiple Text Searches at once using FFIND or TPIPE Support 4
R How to? Append files in multiple subfolders using copy? Support 8
N multiple command alias and redirection Support 0
B Can copy command concatenate multiple mp3 files Support 2
C INSTALLED returnes same program multiple times Support 14
M Delete multiple Alternate Datastreams Support 5
D What are the rules for detecting multiple versions of TC on a machine? Support 7
C FOLDERMONITOR inactive with multiple /I Support 1
C WAD VIEW print multiple files - switches fail Support 10
vefatica Multiple instances of help file Support 3
J How to? Array sort according to multiple keys Support 3
Alexander WAD The number of files and dirs are multiplied when using multiple wildcards Support 6
Jay Sage Version 17 Installer Leaves Multiple Copies of ShrAlias Support 48
R Fixed Internal ZIP command fails to process multiple files Support 3
M How to? PDir on multiple wildcard patterns... Support 2
A WAD Dir daterange + multiple path wildcards crashes tcc Support 2
T How to? Using FOLDERMONITOR 1 event causes multiple trigger(ing)s Support 8
samintz How to? Pull out multiple matching lines Support 5
L "for" in multiple lines Support 2
S TAR with multiple files and /G Support 2
Frank VIEWing multiple files possible? Support 4
J syntax problems multiple commands (command & command) Support 4
J How do I - ffind - with multiple items Support 10
R multiple monitor 'help' Support 7
H Another multiple FTP password prompt issue Support 2
J tcmd height with multiple monitors Support 2
T Open & Configure multiple TCC windows on STARTUP Support 4
old coot tee command cancels colors Support 33
A How to? TEE - duplicate output to STDERR Support 3
Peter Murschall TEE cannot handle Unicode output Support 2
C TEE command appending null characters to output Support 6
vefatica TEE /A adds newline? Support 2
D Why is the TEE command 120 times slower? Support 10
vefatica Debug messages from TEE? Support 3
Joe Caverly Problem with TEE in v22 Support 2
David McClelland TEE command puts it's output file in c:\ Support 4
Roedy problem with tee Support 2
krischik WAD Tee printing Chinese characters Support 7
J TEE Problem Support 11
vefatica WAD TEE adds newlines Support 4
A How to? Use TEE with .NET output Support 6
S Tee? Support 9

Similar threads