Saturday, 1 March 2014

Useless tips in DOS !!!

Useless tips?

This page shows some, er, let's call it "unexpected" behaviour of various DOS commands.
Many will be of no practical use -- hence this page's title -- but it may be fun to experiment with them.

DOSKEY and SET /P

A tip by Padmanabha Holla:
If you have a doskey macro defined and if you input that macro string as input for any SET /P varname= command, later on varname contains the alias of your input, not your input!
C:\>DOSKEY fit=dir
C:\>DOSKEY xla=cls
C:\>SET /P Test=Macro1?
Macro1?xla
C:\>ECHO %Test%
cls
C:\>SET /P Test=Macro2?
Macro2?fit
C:\>ECHO %Test%
dir
C:\>SET /P Test=Macro3?
Macro3?DoesNotExist
C:\>ECHO %Test%
DoesNotExist
C:\>
Thanks Padmanabha

+ Prefix

Adding a plus sign before a command does some pretty weird things in DOS.
Try this for example, and watch the path in your prompt:
C:\>+MD

C:\>+CD

C:\D>CD..

C:\>+RD

C:\>+CD
Directory not found

C:\>
It seems that, for example, +COPY C: is interpreted as COPY Y C:
+DIR will be interpreted as DIR R
The effect of the + before a DOS command is that the last character of the DOS command is inserted as the first command line argument.
This works for COMMAND.COM's "internal commands" only.
As I said, pretty weird and pretty useless.
Unless, of course, you are looking for a way to make your batch files hard to understand.
(Thanks for Günther Brunthaler for helping me work out a proper description of the effect).

ATTRIB

ATTRIB,
Note the comma.
Removes all attributes from all files in the current directory, like
ATTRIB *.* -S -H -R -A
Should work in MS-DOS 5 and 6.* and IBM DOS 5 through 7.

Escape Characters

Both NT and OS/2 offer the ˆ (caret) as an escape character for command lines. Both will display:
Usage: ABC.BAT <drive:>
when you issue the command:
ECHO Usage: ABC.BAT ˆ<drive:ˆ>
Both NT and OS/2 show some unexpected behavior when the escape character is used as the last character of the command line.
The first time I heard about this strange behavior was in a post from Mark Stang in the alt.msdos.batch news group.
Let's take this simple batch file, for example:
SET DATE=ˆ
12/12/99
ECHO Date=%DATE%
In NT, the resulting output would look like this:
Date=12/12/99
That makes this trick really useful in NT. The second line, containing the date, could come from the DATE/T command in another batch file, for example.
In OS/2, however, the output from that same batch file looks like this:
Date=
However, the command SET DATE will display:
Date=
     12/12/99
The only way to make OS/2 display the value of the DATE variable is:
SET DATE| FIND /V "DATE="
(No space between DATE and | allowed)
In NT, the caret at the end of the line is interpreted as "skip the following linefeed".
In OS/2, the SET command interprets the caret as an escape character for the following linefeed, so the variable will contain a linefeed. A pity it cannot be displayed using %variable%, that would have allowed multiple lines of text in a single variable.
Right now, in OS/2, the only use I could think of is for hiding variables.
If you did  find any other way to use this "hidden feature", please send it to my e-mail address.

SET Quirk

Besides the "long list of known problems" with NT's SET /A switch, it has some "unknown" features too.
I haven't found a useful application of the following features yet, maybe you can think of some.
These features were mailed to me by Ken Gould. Thanks.
The common way to use the /A switch is like this:
SET /A variable = mathematical expression
If, however, all you need to do is display the result of the expression on screen, you can use SET like this:
SET /A mathematical expression
For example:
SET /A 75 / 5
will display 15 on screen.
An extra "bonus" feature is the way the result of the expression is displayed: without a carrige return/line feed!
Try this:
(SET /A 75 / 5) > TEST.TXT
The file TEST.TXT will contain one line with nothing but the number 15 and no carriage return/line feed. Check the file size, it will be only 2 bytes.
Ken Gould also mailed me a trick to use when you do want a carriage return/line feed at the end:
(SET /A 75 / 5) | MORE > TEST.TXT
TEST.TXT's size will now be 4 bytes, due to the carriage return/line feed pair added by MORE.
If you prefer internal commands, use this instead:
(SET /A 75 / 5) > TEST.TXT
ECHO.>> TEST.TXT
This SET /A feature can be used as a command line calculator.
Don't, however, expect it to work in the following batch file:
SET /A %1 %2 %3 %4 %5 %6 %7 %8 %9
nor in:
SET /A %*
Calling this batch file with the arguments 12 + 3 will return nothing.
This behaviour seems rather inconsitent.
What does work is this:
SET /A Result = %*
SET Result
Both Windows 2000 and XP show the same results.
This tip was shown to me by Chris Moore. Thanks.

ECHO

Robert Van Etta reported some very odd behaviour of the ECHO command in Windows 2000/XP/Server 2003. Type:
ECHO ˆ
at the command line (doesn't work in batch files) and you will be prompted for "More?".
Type in any text, followed by the Enter key, and it will be echoed again.
To store this text into a file, type:
> MYINPUT.TXT ECHO ˆ
Too bad it won't work in a batch file...

Create Empty Files

to create an empty (zero bytes) file I always used:
TYPE NUL > new_empty_file_name
Robert Van Etta showed me an even shorter command:
CD.> new_empty_file_name

IF ERRORLEVEL

Benny Pedersen has listed some pretty weird but definitely very useful behavior of the IF ERRORLEVEL command on his DOS/batch page.

FTP in batch programming

                            FTP in batch programming


On this page I will show some examples of unattended FTP download (or upload, the difference in script commands is small) scripts.

Command Line Syntax

    FTP [-v] [-d] [-i] [-n] [-g] [-s:filename] [-a] [-w:windowsize] [host]

where:

-v Suppresses display of remote server responses.

-n Suppresses auto-login upon initial connection.

-i Turns off interactive prompting during multiple file transfers.

-d Enables debugging.

-g Disables filename globbing (see GLOB command).

-s:filename Specifies a text file containing FTP commands; the commands will automatically run after FTP starts.

-a Use any local interface when binding data connection.

-A Login as anonymous.

-w:buffersize Overrides the default transfer buffer size of 4096.

host Specifies the host name or IP address of the remote host to connect to.

Notes: (1) mget and mput commands take y/n/q for yes/no/quit.
  (2) Use Control-C to abort commands.

The -s switch is the most valuable switch for batch files that take care of unattended downloads and uploads:
FTP -s:ftpscript.txt
On some operating systems redirection may do the same:
FTP < ftpscript.txt
However, unlike the -s switch its proper functioning cannot be guaranteed.

FTP's Interactive Commands

The following table shows the FTP commands available in Windows NT 4. The difference with other operating systems is marginal.
The actual commands available can be found by starting an FTP session and then typing a question mark at the FTP> prompt.
To get a short description af a particular command, type a question mark followed by that command: (user input shown in bold italics):
C:\>ftp
ftp> ? get
get             receive file
ftp> ? mget
mget            get multiple files
ftp> bye

C:\>







FTP commands
Command Description
!   escape to the shell
?   print local help information
append   append to a file
ascii   set ascii transfer type
bell   beep when command completed
binary   set binary transfer type
bye   terminate ftp session and exit
cd   change remote working directory
close   terminate ftp session
debug   toggle debugging mode
delete   delete remote file
dir   list contents of remote directory
disconnect   terminate ftp session
get   receive file
glob   toggle metacharacter expansion of local file names
hash   toggle printing `#' for each buffer transferred
help   print local help information
lcd   change local working directory
literal   send arbitrary ftp command
ls   nlist contents of remote directory
mdelete   delete multiple files
mdir   list contents of multiple remote directories
mget   get multiple files
mkdir   make directory on the remote machine
mls   nlist contents of multiple remote directories
mput   send multiple files
open   connect to remote tftp
prompt   force interactive prompting on multiple commands
put   send one file
pwd   print working directory on remote machine
quit   terminate ftp session and exit
quote   send arbitrary ftp command
recv   receive file
remotehelp   get help from remote server
rename   rename file
rmdir   remove directory on the remote machine
send   send one file
status   show current status
trace   toggle packet tracing
type   set file transfer type
user   send new user information
verbose   toggle verbose mode


Creating Unattended FTP Scripts

Suppose an interactive FTP session looks like this (user input shown in bold italics):
C:\>ftp ftp.myhost.net
Connected to ftp.myhost.net.
220 *** FTP SERVER IS READY ***
User (ftp.myhost.net:(none)): MyUserId
331 Password required for MyUserId.
Password: ****
230- Welcome to the FTP site
230- Available space: 8 MB
230 User MyUserId logged in.
ftp> cd files/pictures
250 CWD command successful. "files/pictures" is current directory.
ftp> binary
200 Type set to B.
ftp> prompt n
Interactive mode Off.
ftp> mget *.*
200 Type set to B.
200 Port command successful.
150 Opening data connection for firstfile.jpg.
226 File sent ok
649 bytes received in 0.00 seconds (649000.00 Kbytes/sec)
200 Port command successful.
150 Opening data connection for secondfile.gif.
226 File sent ok
467 bytes received in 0.00 seconds (467000.00 Kbytes/sec)
ftp> bye
221 Goodbye.

C:\>


An FTP script for unattended file transfer would then look like this:
USER MyUserId
MyPassword
cd files/pictures
binary
prompt n
mget *.*
Note that I left out the BYE (or QUIT) command, it isn't necessary to specify this command in unattended FTP scripts (though it doesn't do any harm either).
As you can see, using a script like this is a potential security risk: the password is stored in the script in a readable form.
As Tom Lavedas once pointed out in the alt.msdos.batch newsgroup, it is safer to create the script "on the fly" and delete it afterwards:
@ECHO OFF
:: Check if the password was given
IF "%1"=="" GOTO Syntax
:: Create the temporary script file
> script.ftp ECHO USER MyUserId
>>script.ftp ECHO %1
>>script.ftp ECHO cd files/pictures
>>script.ftp ECHO binary
>>script.ftp ECHO prompt n
>>script.ftp ECHO mget *.*
:: Use the temporary script for unattended FTP
:: Note: depending on your OS version you may have to add a '-n' switch
FTP -v -s:script.ftp ftp.myhost.net
:: For the paranoid: overwrite the temporary file before deleting it
TYPE NUL >script.ftp
DEL script.ftp
GOTO End

:Syntax
ECHO Usage: %0 password

:End
Sometimes it may be necessary to make the script completely unattended, without the user having to know the password, or even the user ID, but with the possibility to check for errors during transfer.
There are several ways to do this.
One is to redirect FTP's output to a log file and either display it to the user or use FIND to search the log file for any error messages.
Another way to do this, on the fly, is by displaying FTP's output on screen, in the mean time using FIND /V to hide the output you do not want the user to see (like the password and maybe even the USER command):
FTP -s:script.ftp ftp.myhost.net | FIND /V "USER" | FIND /V "%1"
It is important not to use FTP's -v switch in either case.

Summary

To create a semi interactive FTP script, you may need to split it into several smaller parts, like an unattended FTP script to read a list of remote files, the output of which is redirected to a temporary file, which in turn is used by a batch file to create a new unattended FTP script on the fly to download and/or delete some of these files.
Create these files by writing down every command and all screen output in an interactive FTP session, analyze this "log" thoroughly, and test, test, and test again!
And don't forget to log the results by redirecting the script's output to a log file. You may need it later for debugging purposes...

Alternatives

Instead of Windows' own native FTP command, you can choose from a multitude of "third party" alternatives.
I'll discuss three of those alternatives here: a command-line tool, a GUI-tool and VBScript with a third party ActiveX component.
Note: The alternatives discussed here, GNU WGET, Fileaze, and VBScript (with WinHTTP), handle HTTP downloads just as easily.

WGET

WGET is a port of the UNIX wget command.
WGET is perfect for anonymous FTP or HTTP downloads (sorry, no uploads), but it can be used for downloads requiring authentication too.
GNU WGET comes with help both in the (text mode) console and in Windows Help format.
The basic syntax for an FTP download doesn't get any simpler than this:
WGET ftp://ftp.mydomain.com/path/file.ext
for anonymous downloads, or:
WGET ftp://user:password@ftp.mydomain.com/path/file.ext
when authentication is required.
Note: This is not secure, as you would need to store your user ID and password in unencrypted format in the batch file.
Besides that, the user ID and password will be logged together with the rest of the URL on all servers associated with the file transfer.
Read the GNU WGET help file for more information on securing user IDs and passwords.

WinSCP

WinSCP is a free open-source SFTP and FTP client with a command line/scripting interface as well as a GUI.
WinSCP can be used for uploads and downloads.

Fileaze

Prefer a GUI to create interactive as well as unattended jobs?
To be honest, I hardly ever use the text mode native FTP command myself.
For these web pages, my photographs, or any other FTP job, I have always used Coffeecup FreeFTP (no longer available, unfortunately).
Recently, I automated my own web page uploads using Fileaze.
Fileaze is a great GUI program to automate file related tasks like rename, copy, upload and download, send by e-mail, etcetera, in batch (no, not in batch files but in batch mode, i.e. in groups of files, and unattended).
Have a look at the tutorial I wrote, based on my own "efforts" to generate an automated FTP upload job.
And did I mention the uploads are fast?
You can download the free Fileaze trial version or buy it here.
You can also download the free Fileaze LITE version from the Fileaze website. The LITE version may be used indefinitely, without limitations, but it has limited functionality (i.e. no FTP and no e-mail).
Make sure you read the tutorials included in the help file.
The program may not be that hard to learn without help, but speaking from experience: reading them will save you a lot of time.
And once you created one or more jobs, make sure you make a backup.
Fileaze stores the data (jobs, encrypted account settings, etcetera) in the registry key "HKEY_CURRENT_USER\Software\Resolware".
The registry as a whole is included in Windows's SystemState backups, but it doesn't support selectively restoring registry keys.
So (of course) I made myself a batch file which I scheduled, to make unattended backups. View this batch file's source, or download the ZIPped batch file (for Windows NT 4 and later).

VBScript

In my VBScript Scripting Techniques section, sample scripts are available for FTP and HTTP file transfers.
The FTP scripts require one of these free ActiveX components:

Send e-mails by batch programming

                   Send e-mails by batch programming


The January 2000 issue of Blaise, the Dutch HCC Pascal User Group's magazine, contained an article about sending e-mail with Delphi. The article contained more information on the command strings used to send e-mail.
The general format is:
mailto:to?subject=subject&cc=cc_address&bcc=bcc_address&body=message_body
to_address The (escaped) e-mail address of the recipient; allowed formats:
• someone@somedomain.com
• Full%20Name&lt;someone@somedomain.com&gt;
subject The (escaped) subject field of the message
cc_address The (escaped) "carbon copy" e-mail address; allowed formats:
• someone@somedomain.com
• Full%20Name&lt;someone@somedomain.com&gt;
bcc_address The (escaped) "blind carbon copy" e-mail address; allowed formats:
• someone@somedomain.com
• Full%20Name&lt;someone@somedomain.com&gt;
message_body The actual message body (escaped too)

Notes: (1) All parameters mentioned need to be "escaped", i.e. spaces should be replaced by %20, carriage return/line feeds by %0D%0A, double quotes by %22, single quotes by %27, backslashes by %5C, less than by &lt;, greater than by &gt;, and ampersands by &amp;.
For batch files and command line use, unless the entire string is enclosed in doublequotes, the percent signs in the "escape sequences" themselves must also be replaced by double percent signs: so in the end spaces should be replaced by %%20, carriage return/line feeds by %%0D%%0A, etcetera.
  (2) The commands shown here only create a message.
To send it you still need to press the Send button yourself.
Check out the links to third party command line e-mail utilities at the bottom of this page if you need to send e-mail unattended.

To use this type of command in batch files we need to:
  • precede the string with the START command
  • replace every single percent sign ( % ) by double percent signs ( %% )
  • "escape" ampersands ( & ) with carets ( ˆ )
  • limit the length of the mailto string to the maximum allowable command line length minus 6 (leaving a maximum of 121 characters for MS-DOS, or 249 characters for Windows NT 4/Windows 2000, or 2035 for Windows XP)

Examples:


START mailto:dummy@nuldevice.com?subject=Test%%20messageˆ&cc=info@nuldevice.comˆ&body=Hi,%%0D%%0A%%0D%%0AThis%%20is%%20an%%20automatically%%20created%%20message.%%0D%%0A%%0D%%0ABye
This command will create a message to dummy@nuldevice.com, with a carbon copy to info@nuldevice.com, with the words "Test message" in the subject field.
The message itself will consist of the following text:
Hi,

This is an automatically created  message.

Bye

The following NT only batch file will check if the correct network drive mappings have been made.
If not, an e-mail message to the helpdesk is generated (assuming the e-mail software is available without the mappings). The user can add more information before actually sending it.
@ECHO OFF
SET ERRORS=0
:: Use your own mappings and search strings here
NET USE P: | FIND /I "%username%" >NUL 2>NUL
IF ERRORLEVEL 1 CALL :ErrorMsg P:
NET USE S: | FIND /I "system" >NUL 2>NUL
IF ERRORLEVEL 1 CALL :ErrorMsg S:
:: Create an e-mail message if any errors were detected
IF %ERRORS% GEQ 1 CALL :Mail
:: Clear variables used in this batch file
FOR %%A IN (BODY DATE ERRORS LINE MESSAGE TIME) DO SET %%A=
GOTO :EOF

:ErrorMsg
SET /A ERRORS = %ERRORS% + 1
NET USE %1 >NUL 2>NUL
IF ERRORLEVEL 1 (
 SET BODY=%BODY%%%0D%%0ADrive%%20%1%%20not%%20mapped
 GOTO :EOF
)
FOR /F "TOKENS=3* DELIMS= " %%A IN ('NET USE %1 ˆ| FIND "Local name"') DO SET MESSAGE=Drive%%20%%A%%20mapped%%20to%%20
:: Replacement of backslashes "\" by "%%5C"
:: prevents interpretation of "\n" as CR/LF
FOR /F "TOKENS=3,4* DELIMS=\ " %%A IN ('NET USE %1 ˆ| FIND "Remote name"') DO SET MESSAGE=%MESSAGE%%%5C%%5C%%A%%5C%%B
SET BODY=%BODY%%%0D%%0A%MESSAGE%
GOTO :EOF

:Mail
FOR /F "TOKENS=2*" %%A IN ('DATE/T') DO SET DATE=%%A
FOR /F %%A IN ('TIME/T') DO SET TIME=%%A
START mailto:helpdesk@ourdomain.com?subject=Drive%%20mapping%%20errorˆ&body=At%%20%DATE%,%%20%TIME%,%%20user%%20%USERNAME%%%20encountered%%20the%%20following%%20drive%%20mapping%%20error(s)%%20on%%20%COMPUTERNAME%:%%0D%%0A%BODY%
GOTO :EOF
Click to view source Click to download the ZIPped sources

As the resulting message content already indicates, using this batch file you will probably run into command length limitations real soon:
At 15/01/2000, 13:43, user ROB encountered the following drive mapping error(s) on SERVER:

Drive P: not mapped
Drive S: mapped to \\SE
Limiting the length of the first line may help a little, but the limit will be about two or maybe three error messages.

Assuming your log files aren't too big, you could use the following NT only batch procedure to create a message to the system administrator, containing the (ASCII) log file:
@ECHO OFF
FOR /F "TOKENS=*" %%A IN (LOGFILE.LOG) DO CALL :AddLine %%A
:: The ":~6" in "%BODY:~6%" removes the "%0D%0A" at the start of the body
START mailto:sysadm@ourdomain.com?subject=Log%%20fileˆ&body=%BODY:~6%
GOTO :EOF

:AddLine
SET LINE=
FOR %%Z IN (%*) DO CALL :AddWord %%Z
:: The ":~3" in "%LINE:~3%" removes the "%20" at the start of the line
SET BODY=%BODY%%%0D%%0A%LINE:~3%
GOTO :EOF

:AddWord
SET LINE=%LINE%%%20%1
GOTO :EOF
Click to view source Click to download the ZIPped sources

I wouldn't go as far as saying that if it isn't mentioned here it isn't possible.
However, I often get questions about how to add attachments, or how to read the message body from a file.
Please believe me, if it were possible in "pure" batch (and if I were aware of that) I would have mentioned it here!
So this is where the third party tools come into view.

Scribe is a small footprint e-mail program (fits on a floppy disk) that can be used as an "ordinary" mail program, plus it can be used to send mail from the command line.

Command line e-mail programs:

Blat:      Send mail via SMTP. Free
GBMailer:   Command-line mailer. GPL
MailSend:   Command-line Internet mailer. Shareware
GetMail:   Receive mail through POP3. Free
If you use an Exchange mail server, consider using MAPISEND from the Exchange Resource Kit for command line mailing.
Mozilla Thunderbird users can compose messages on the command line, similar to the "mailto:" technique described above, but including attachments, using its -compose switch.

WSH based e-mail:

Use CDOSYS to send e-mails in VBScript or HTAs.

GUI to dynamically generate unattended e-mail:

Use Fileaze to create tasks that include anything from capturing web pages to sending files per e-mail, and from compressing to encrypting, plus anything that can be run from a "normal" command line.

New features in HTML5

Besides sending e-mails, HTML5 allows you to send SMS (text messages) and initiate phone calls.
Phone call:
<a href="tel:0123456789">Give us a call!</a>
SMS:
<a href="sms:0123456789?body=This is my text message">Send us a text message!</a>
Notes: (3) As is the case with e-mail messages, you cannot actually send text messages, nor make a phone call, all you can do is open the SMS or phone interface with the number and (for SMS) text already filled in
  (4) Avoid ampersands and doublequotes in the SMS body, or escape them (see Note 1)
  (5) For text messages to multiple cell phones, separate the numbers by commas:
<a href="sms:0123456789,0214365879?body=Text message for both of you">Send us both a text message!</a>

Python Tutorial - Part 2

Python Tutorials Part 2 After installation of Python software on windows machine in previous tutorial, lets proceed ...