cmdmacroscommand-line-interfacealiasdoskey

The doskey command separator produces blank lines


The doskey command separator ($T) generates a blank line when the command produces no output.

C:\> set "a="                                                    

C:\> set "b="                                                    

C:\> doskey test=set "a=foo" $T set "b=bar" $T echo ^%a^% ^%b^%

C:\> test                                                      

C:\>                                                           
C:\> foo bar                                                   

Note the blank line after issuing test, which affects readability.

There is a well-known ^? alternative to $T, which does not add blanks, but the new command does not inherits environment variables.

C:\> set "a="                                                    

C:\> set "b="                                                    

C:\> doskey test=set "a=foo" ^& set "b=bar" ^& echo ^%a^% ^%b^%

C:\> test                                                      
%a% %b%     

There are no blanks here, anyway set is ineffective after starting a new command.

How can I remove the blank lines?

Update: Removed "creates a separate process" line as it was wrong.


Solution

  • The difference between $T and ^& is who handles the execution of the different commands.

    When $T is used, doskey knows there is more than one command and it is itself who serially executes the commands in the current cmd instance, with the blank lines and prompt lines as a side effect.

    When ^& is used, doskey (who is checking the $ prefixed characters) only sees a character without any special meaning. When the macro is invoked, doskey only executes one command (the full line) and is the cmd parser who now sees the concatenated commands and handles the serial execution, this time without additional lines.

    The indicated "... it creates a separate process not inheriting environment variables." is not correct. There is no additional process. What you see is the usual variable expansion "problem". Variable read operations are removed from the line at parse time to generate the final command to execute. You can not change a variable in a line and retrieve the changed value from the same line in a later command because the read operation was replaced while parsing, before starting the execution that will change the variable. (Read here)

    So, now, instead of one, we have two problems to solve. The variable expansion in the ^& case and the additional lines in the $T case.

    If delayed expansion is not enabled, we can not enable it from the current cmd instance while in command line context (only inside batch files), so, to solve the problem we need to force an additional parse of the line to force retrieval of the changed value. We can use the call command before the echo

    doskey test=set "a=foo" ^& set "b=bar" ^& call echo ^%a^% ^%b^%
    

    But it is easier to solve the other problem. The empty and prompt lines are a simply echo problem

    doskey test=echo off $t set "a=foo" $t set "b=bar" $t echo ^%a^% ^%b^% $t echo on
    

    Just turn echo off at the start and on at the end.