windows cmd dos not show complete output in a text file - windows

if I open windows cmd and type this command:
copy D:\1.txt C:
then I see this result:
Access is denied.
0 file(s) copied.
but with this command:
copy D:\1.txt C:\ > d:\output.txt
output text file shows only this :
0 file(s) copied.
why "Access is denied." is not in output.txt? and how could I have complete output in text file?

Redirecting a command's output to a file via > somefile.txt only redirects the data written to "standard output" stream to the file, it does not include data written to "standard error" stream, which is where the "Access is denied." message is written in your case. To capture all output, you need to append 2>&1 to the end of the command, e.g.:
copy D:\1.txt C:\ > d:\output.txt 2>&1
This can be understood as an instruction to send data written to standard error (stream 2) to standard output (stream 1).
You can also redirect standard error to a different file to standard output with e.g.:
copy D:\1.txt C:\ > d:\output.txt 2> d:\errors.txt

Related

Is there a command to create files using cmd on windows?

I learnt that I can use NUL> but it is working strangely. Whenever I use it, it reports "Access is denied" but the file is created.
You're getting access denied since you're trying to run the nul device (whether you redirect standard output or not is irrelevant):
c:\pax> nul
Access is denied.
c:\pax> nul >myfile.txt
Access is denied.
What you need to do to get an empty file, although there are other ways to do it, is send the output of the nul device to your file, with something like:
c:\pax> type nul >myfile.txt
c:\pax> dir myfile.txt
Volume in drive C has no label.
Volume Serial Number is DEAD-BEEF
Directory of c:\pax
21/06/2018 04:57 PM 0 myfile.txt
1 File(s) 0 bytes
0 Dir(s) 31,415,926,535,902,718,281,828,459 bytes free
Only that first line above is needed to create an empty file, the rest is just to show that it worked.
Just run:
echo.>your_file.txt
copy con abc.txt
and type file content. Use Ctrl+Z to finish
mkdir thisisafile
cd thisisafile
echo.>suchtextmuchwow.txt
echo . >thisisatext.txt
notepad anothertext.txt
copy nul "iambored.txt"
type NUL > 1.txt
Note : using the " notepad " command will give you an error saying " you don't have such a file, do you want to create it? " while the "echo.>" command will directly create.
Note : if you type "echo.>" it'll create a txt file with a single line break but no characters inside, but if you type "echo . >" it'll create a text file with a dot ( . )in it.
Note : If you use "copy nul" the problem with that command is that it will always display that the file was copied and in order to avoid that you can also try the following command: type NUL > 1.txt
you need to try this one it will create new file
echo.>filename
example
echo.>new.txt

Redirection operator in BAT file gives "Cannot open output file >"

I have a BAT script, with the last line being the problem
SET program=%1
SET PWD=%cd%
cd "%~dp0"
"%PWD%\%program%" "filename.txt" ^> "%PWD%\Output.txt" 2^>^&1
And this rightly spits out:
"C:\path\program.exe" "filename.txt" > "C:\Path\Output.txt" 2>&1
However, it then says
Cannot open output file >
And continues on with the script, without any file being created. If I copy and paste what is spit out, it run perfectly.
Note: The behavior is reproducible in an elevated CMD as well.
So, how do I get an EXE to run in a batch script, and redict both stdout and stderr to the same file, without getting an access error?
So your program.exe takes an parameter that is a filename.txt and outputs all to Output.txt
Try without the ^ simbols:
"C:\path\program.exe filename.txt" > "C:\Path\Output.txt" 2>&1
And batch cannot ask for permissions. If you are under c:\ you will need to execute the bat file with administration permission.

How to use wintee to redirect STDERR only?

I'm currently using wintee to log the result messages from testing scripts. Here's what the command looks like:
test_name.bat [parameters] 2>&1 | wtee log.txt
However, I only would like to archive STDERR to a file, while still displaying both STDOUT and STDERR to the console. The problem emerges from wintee's limitation: it seems to only fork STDIN, STDOUT, and input files.
Here's what I'm trying to do:
Redirect STDOUT to stream 3 (unused stream)
Redirect STDERR to STDOUT
Redirect stream 3 (the redirected STDOUT) to STDERR
This way, the console will still display both streams' messages, while wintee will only fork the messages from (what originally was) STDERR.
However, I'm not sure whether if it's possible, as my understanding of the stream redirection is shallow. I'm trying to see if I can redirect STDOUT to STDERR using another stream in between:
echo Hello World! 3>&2 >3
However, it isn't printing anything.
Is what I'm trying to accomplish possible in native batch (optionally with helps of other tools)? If so, what am I doing wrong?
Set Arg = WScript.Arguments
set WshShell = createObject("Wscript.Shell")
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
On Error Resume Next
Set Fso = CreateObject("Scripting.FileSystemObject")
Set File = Fso.CreateTextFile(Arg(0), True)
If err.number <> 0 then
Outp.WriteLine "Error: " & err.number & " " & err.description & " from " & err.source
err.clear
wscript.exit
End If
Do Until Inp.AtEndOfStream
Line=Inp.readline
outp.writeline Line
File.WriteLine Line
Loop
This Tees StdOut. Changing the 4th line to Set Outp = Wscript.Stderr will make it Tee StdErr.
To use dir | cscript //nologo Tee.vbs.
I do not know the wintee command, but I think I can help you with the redirection issue:
Instead of test_name.bat [parameters] 2>&1 | wtee log.txt, you should write the following:
(test_name.bat [parameters] 2>&1 1> con) | wtee log.txt
This writes the text at STDOUT to the console, redirects the data at STDERR to STDOUT, which is in turn passed to the wtee command.
Note that the console displays all original STDOUT before any STDERR data, because the former is displayed immediately, while the latter is passed through wtee. With pure redirection hacks it is not possible to preserve the original order which the data was returned with. If you insist on that, you need to use a tool other than wintee which has got the required capabilities. Edit: In particular, the pipe is the bottleneck, because there is only one channel, namely STDIN, where it passes data to. So if you insist on STDOUT and SRDERR data to be displayed in the original order while saving the data of one stream to a file, you have no other choice but to modify the script test_name.bat and to avoid piping.
I am trying to explain that using the command dir ":" on the left side of the pipe, which produces output at both STDOUT and STDERR (because of the invalid path ":"):
D:\Data> dir ":"
Volume in drive D has no label.
Volume Seriel Number is 0000-0000
Directory of D:\Data
File Not Found
The File Not Found message appears at STDERR, whereas the rest appears at STDOUT (you can prove that by redirecting like 2> nul or 1> nul to dismiss either of the streams).
On the right side of the pipe, I am using the command find /V "", which simply passes all data it receives at STDIN through and displays it on the console:
D:\Data> dir ":" | find /V ""
File Not Found
Volume in drive D has no label.
Volume Seriel Number is 0000-0000
Directory of D:\Data
The changed order of the console output illustrates what happens: STDERR is displayed immediately, whereas STDOUT is first passed through the pipe before being displayed.
Now let us apply the redirection 2>&1 from your command line:
D:\Data> (dir ":" 2>&1) | find /V ""
Volume in drive D has no label.
Volume Seriel Number is 0000-0000
Directory of D:\Data
File Not Found
This redirects STDERR to STDOUT, so the original STDOUT data together with the redirected ones are piped through. Replacing find /V "" by (> nul find /V "") proves that the right side of the pipe really receives all of the data.
Now let us add the 1> con portion, which constitutes an explicit redirection of STDOUT to the console:
D:\Data> (dir ":" 2>&1 1> con) | find /V ""
Volume in drive D has no label.
Volume Seriel Number is 0000-0000
Directory of D:\Data
File Not Found
The output contains all of the original data. Again replacing find /V "" by (> nul find /V "") proves that this time, the right side of the pipe truly only recieves the File Not Found message, which was originally present at STDERR, but the STDOUT data are not piped through.
Just a side-note:
If you want to do something like wintee with pure batch-file, things become very complicated -- see this example...

batch command to log file

I wanted to capture the contents of DOS command file (.CMD) to a log file.
I can understnd I can capture the individual commands to log file using > or >>.
However I wanted to copy the contents of the complete dos screen into a log file as well.
I have also noticed when I use >> it removes the output message ( 1 file copied) from the dos console and moves in the log file. Is it possibl I can leave the message is displaied in both console and log file.
Any help will be appreciated.
However I wanted to copy the contents of the complete dos screen into a log file as well.
Make sure not to use "echo off" in your script.
it removes the output message ( 1 file copied) from the dos console and moves in the log file
Redirect stderr to stdout before appending:
myscript.bat 2>&1 >> myscript.log
See here a good resource on batch file redirection.
Is it possibl I can leave the message is displaied in both console and log file
You need "tee". Download a good one for Windows from here. Then do this instead of the above.
myscript.bat 2>&1 | tee -a myscript.log
myscript.bat >> myscript.log 2>&1

Batch file detect if NTFS alternate stream can be written to

Background
In Windows 7, when a file is downloaded from the internet, some browsers (e.g. IE and Firefox) flag it as coming from the internet. This is apparent in the properties dialog of the file, which will show a message and an "Unblock" button at the bottom of the properties window.
This property is stored as an alternate stream on the NTFS filesystem - specifically, a stream named "Zone.Identifier". So on a blocked file, you can run the command more < file.exe:Zone.Identifier and you get the output:
[ZoneTransfer]
ZoneId=3
You can clear this data with the command echo. > file.exe:Zone.Identifier. This overwrites the above data with simply a blank line, and while the Zone.Identifier stream still exists on the file, the file is no longer "blocked" as confirmed by the properties dialog.
Problem
FAT32 file systems obviously don't have NTFS alternate streams; so, the command echo. > file.exe:Zone.Identifier gives the output:
The filename, directory name, or volume label syntax is incorrect.
This is output to stdout, so adding 2>NUL on the end does not suppress it. Adding 1>NUL to the end DOES suppress it, however it also suppresses the command from doing anything useful; that is, if you run echo. > file.exe:Zone.Identifier 1>NUL, the Zone.Identifier stream remains.
How can I run the command echo. > file.exe:Zone.Identifier successfully on NTFS, and suppress its error output on FAT32?
Command echo. > file.exe:Zone.Identifier 1>NUL causes redirection of echo. to NUL, the first redirection is ignored.
Adding 2>NUL causes redirection of echo's stderr to NUL. The message you are trying to avoid is printed to stderr by failed redirection and not by echo command by itself.
The solution is to devide the command into two phases by using brackets:
(echo. > file.exe:Zone.Identifier) 2>NUL
This will cause echo. to be executed first and its output redirected to alternative file stream. If trying to write to alternative file stream on FAT filesystem failes, then it's output to stderr will be redirected to NUL.

Resources