Windows command line using directory and EXE file parameters - windows

I have been trying to run an application I built and output it to a file. However, I am running into problems with the command line arguments required to do this.
This is an example of my problem using ipconfig.
The following command works:
ipconfig > output.txt
Whereas this will create the file, but not populate it with the ipconfig output:
start /D "C:\>WINDOWS\system32" ipconfig.exe > output.txt
I think it is the use of start that is causing this issue, but I'm not sure.
SOLUTION
This is the code which managed to solve the problem for me:
char path[500]; // Create character array
strcpy (path, "cd "); // Copy 'cd' into the array
strcat (path, toolLocation); // Copy the path of the tool into the array
strcat (path, " & ip.exe > output.txt"); // Append on the name of the exe and output to a file
system (path); // Run the built array
I am creating a character array and then appending to it. The vital bit here was the & being used in the system call. This is working as an and and first cd'ing to the directory before executing the .exe file.

In your command, the > is redirecting the output of start rather than the output of ipconfig. That explains why you are seeing nothing – start is simply not outputting anything.
Based on the comments to the question, you can achieve your goals with ShellExecute like this:
ShellExecute(
0,
"open",
"cmd.exe",
"/C ipconfig > output.txt",
NULL,
SW_HIDE
);

Rather than using start I think you might want to use cd to change the directory.
Try this batch file:
cd "C:\Program Files\Tools\2012"
ip.exe >output.txt
Or for use without a batch and just command line:
"C:\Program Files\Tools\2012" ip.exe >output.txt"
Although system32 is in PATH so I'm not sure why you are accessing the ipconfig exe by it's full path, but this should work.

The error is this:
start /D "C:\>WINDOWS\system32" ipconfig.exe > output.txt
should be
start /D "C:\WINDOWS\system32" ipconfig.exe > output.txt
without > in the path. Although C:\> is shown at the prompt with cmd.exe it is not part of the path name and > is actually invalid for the purpose, to my knowledge.
Additionally I would strongly suggest you use:
start /D "%SystemRoot%\system32" ipconfig.exe > output.txt
Furthermore because start creates a new console (and new stderr and stdout) you are catching the output of start not of ipconfig. So you may wanna use:
pushd "%SystemRoot%\system32" & ipconfig.exe > output.txt & popd
but that will attempt to write output.txt into %SystemRoot%\system32 and will fail on most systems unless you are admin. So give an absolute path or simply leave out the crud:
ipconfig.exe > output.txt
ipconfig.exe is always in the default system PATH variable, so it will work unless the admin has "fixed" the system in which case you can still do:
%SystemRoot%\system32\ipconfig.exe > output.txt

Related

cmd.exe opens the file path with notepad.exe instead of interpreting it as an argument

Given cmd.exe, I observed a special case which I do not understand, and which does not seemed to be explained by https://stackoverflow.com/a/4095133/16545605:
This simple command is executed as one would expect:
> type ..\..\..\..\..\..\windows\win.ini
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1
But what happens when done this way? Well, it opens Notepad with the given file and the shell is blocked until Notepad is closed again:
> cmd.exe /c "type ..\..\..\..\..\..\windows\win.ini"
On the other hand, those three variants behave as someone would expect (as the first example):
> cmd.exe /c type ..\..\..\..\..\..\windows\win.ini
...
> cmd.exe /c "type" "..\..\..\..\..\..\windows\win.ini"
...
> cmd.exe /c "type C:\windows\win.ini"
...
To open Notepad, it is also possible to just give the file name. It seems cmd.exe opens the file with the default program if only the path is given:
> ..\..\..\..\..\..\windows\win.ini
> C:\windows\win.ini
So, it seems that cmd.exe is interpreting the given command as two commands, and only "executes" the second one (opening the file, everything before is ignored). Furthermore, it seems the path has to be relative. My question now is, why, and under which circumstances this behavior happens. Please note, that type is just an example. It also works with echo, ping, ipconfig,...
If you already liked this behavior, lets add another one:
> cmd.exe /c "echo a > output.txt ..\..\..\..\..\..\windows\win.ini"
> type output.txt
a ..\..\..\..\..\..\windows\win.ini
If you do this without cmd.exe \c, additionally a newline is introduced:
> echo a > output2.txt ..\..\..\..\..\..\windows\win.ini
> type output2.txt
a
..\..\..\..\..\..\windows\win.ini
As Linux user, I'm just baffled how unintuitive a shell can be. Is there some documentation why it is as it is, and how to prevent this behavior (without removing the cmd.exe /c part)?
I stumbled over a blog-post analyzing the behavior in the first part of my question in detail: https://hackingiscool.pl/cmdhijack-command-argument-confusion-with-path-traversal-in-cmd-exe/
Basically, given the following command:
> cmd.exe /c "type ..\..\..\..\..\Windows\System32\ipconfig.exe"
Windows interprets type .. as "directory" and then enters the parent directories multiple times as ..\ does until the drive root is reached. Using this exact location we can point to arbitrary known files or executables. Given an path, cmd.exe detects that there is a file at this location and thus executes the found executable instead of interpreting the command as originally intended.

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 make a batch file using CMD?

Can someone please tell me how I can create a batch file (empty) using CMD? I tried below, didn't work.
echo C:\Users\Yohan\Desktop\test > test.bat
From your command prompt:
type NUL>test.bat
or
copy NUL test.bat
Here NUL does not refer to the ASCII NUL (character of ASCII integer value zero). It's a system reserved word for NUL device (imagine a fake file of zero length).
echo.>>mybatchfile.bat
Note that this will create a file containing a single newline.
If you want to Create the file in C:\Users\Yohan\Desktop\test
First use the CD command to change the current directory, then try. or else it will create in system32 (if you run the cmd from accessories)
Try the below :
> cd C:\Users\Yohan\Desktop\test then
> echo empty >a.bat
Thats it.
From your command prompt:
copy con test.bat
[ctrl]+z
The [ctrl]+z is the End of File marker, closing and saving the empty file.
Basically, you are just copying with the source being the CONsole and the destination being the .BAT file.
just to add another possibility to create an empty file (0 Byte):
break>mybatchfile.bat
The concept behind the creation of an empty file is simple: take nothing and put it in a file. A way to do that is using a command that produce no output and redirect its output to the file, so you just need to know which commands produce no output.
In the old MS-DOS command.com days, that command was rem:
rem Create an empty file > empty.txt
However, such functionality was removed in Windows cmd.exe. Other commands that show nothing and works in Windows are:
break > empty.txt
call > empty.txt
cd . > empty.txt
color > empty.txt
endlocal > empty.txt
setlocal > empty.txt
shift > empty.txt
title > empty.txt
verify off > empty.txt
The problem with these commands is that they do a certain task, so using they to create an empty file seems strange. For example, goto command also show nothing:
goto nextLine > empty.txt
:nextLine
Another example:
(if a == b echo Create an empty file) > empty.txt
Other command that show nothing is exit, so you may write a subroutine that create an empty file with the name given in its parameter this way:
:CreateEmptyFile
exit /B > %1
So, which command should we use? Well, in my particular case I prefer that the purpose of the command be perfectly clear, so I choose an auto-documented set command:
set dummyVar=Create an empty file > empty.txt

Create an empty file on the commandline in windows (like the linux touch command)

On a windows machine I get this error
'touch' is not recognized as an internal or external command, operable program or batch file.
I was following these instructions which seem to be linux specific, but on a standard windows commandline it does not work like this:
touch index.html app.js style.css
Is there a windows equivalent of the 'touch' command from the linux / mac os / unix world ? Do I need to create these files by hand (and modify them to change the timestamp) in order to implement this sort of command? I am working with node and that doesn't seem very ... node-ish...
An easy way to replace the touch command on a windows command line like cmd would be:
type nul > your_file.txt
This will create 0 bytes in the your_file.txt file.
This would also be a good solution to use in windows batch files.
Another way of doing it is by using the echo command:
echo.> your_file.txt
echo. - will create a file with one empty line in it.
If you need to preserve the content of the file use >> instead of >
> Creates a new file
>> Preserves content of the file
Example
type nul >> your_file.txt
You can also use call command.
Calls one batch program from another without stopping the parent batch program. The call command accepts labels as the target of the call.
Example:
call >> your_file.txt
---
or even if you don't want make it hard you can Just install Windows Subsystem for Linux (WSL). Then, type.
wsl touch
or
wsl touch textfilenametoedit.txt
Quotes are not needed.
Windows does not natively include a touch command.
You can use any of the available public versions or you can use your own version. Save this code as touch.cmd and place it somewhere in your path
#echo off
setlocal enableextensions disabledelayedexpansion
(for %%a in (%*) do if exist "%%~a" (
pushd "%%~dpa" && ( copy /b "%%~nxa"+,, & popd )
) else (
type nul > "%%~fa"
)) >nul 2>&1
It will iterate over it argument list, and for each element if it exists, update the file timestamp, else, create it.
You can use this command: ECHO >> filename.txt
it will create a file with the given extension in the current folder.
UPDATE:
for an empty file use: copy NUL filename.txt
On windows Power Shell, you can use the following command:
New-Item <filename.extension>
or
New-Item <filename.extension> -type file
Note: New-Item can be replaced with its alias ni
The answer is wrong, it only works when the file does not exist. If the file exists, using the first does nothing, the second adds a line at the end of the file.
The correct answer is:
copy /b filename.ext +,,
I found it here: https://superuser.com/questions/10426/windows-equivalent-of-the-linux-command-touch/764721#764721
I'm surprised how many answers here are just wrong. Echoing nothing into a file will fill the file with something like ECHO is ON, and trying to echo $nul into a file will literally place $nul into the file. Additionally for PowerShell, echoing $null into a file won't actually make a 0kb file, but something encoded as UCS-2 LE BOM, which can get messy if you need to make sure your files don't have a byte-order mark.
After testing all the answers here and referencing some similar ones, I can guarantee these will work per console shell. Just change FileName.FileExtension to the full or relative-path of the file you want to touch; thanks to Keith Russell for the COPY NUL FILE.EXT update:
CMD w/Timestamp Updates
copy NUL FileName.FileExtension
This will create a new file named whatever you placed instead of FileName.FileExtension with a size of 0 bytes. If the file already exists it will basically copy itself in-place to update the timestamp. I'd say this is more of a workaround than 1:1 functionality with touch but I don't know of any built-in tools for CMD that can accomplish updating a file's timestamp without changing any of its other content.
CMD w/out Timestamp Updates
if not exist FileName.FileExtension copy NUL FileName.FileExtension
Powershell w/Timestamp Updates
if (!(Test-Path FileName.FileExtension -PathType Leaf)) {New-Item FileName.FileExtension -Type file} else {(ls FileName.FileExtension ).LastWriteTime = Get-Date}
Yes, it will work in-console as a one-liner; no requirement to place it in a PowerShell script file.
PowerShell w/out Timestamp Updates
if (!(Test-Path FileName.FileExtension -PathType Leaf)) {New-Item FileName.FileExtension -Type file}
Use the following command on the your command line:
fsutil file createnew filename requiredSize
The parameters info as followed:
fsutil - File system utility ( the executable you are running )
file - triggers a file action
createnew - the action to perform (create a new file)
filename - would be literally the name of the file
requiredSize - would allocate a file size in bytes in the created file
install npm on you machine
run the below command in you command prompt.
npm install touch-cli -g
now you will be able to use touch cmd.
You can replicate the functionality of touch with the following command:
$>>filename
What this does is attempts to execute a program called $, but if $ does not exist (or is not an executable that produces output) then no output is produced by it. It is essentially a hack on the functionality, however you will get the following error message:
'$' is not recognized as an internal or external command,
operable program or batch file.
If you don't want the error message then you can do one of two things:
type nul >> filename
Or:
$>>filename 2>nul
The type command tries to display the contents of nul, which does nothing but returns an EOF (end of file) when read.
2>nul sends error-output (output 2) to nul (which ignores all input when written to). Obviously the second command (with 2>nul) is made redundant by the type command since it is quicker to type. But at least you now have the option and the knowledge.
as mentioned
echo >> index.html
it can be any file, with any extension
then do
notepad index.html
this will open your file in the notepad editor
No command – neither typenor echo– is necessary to emulate Unix's/Mac OS X's 'touch' command in a Windows Powershell terminal. Simply use the following shorthand:
$null > filename
This will create an empty file named 'filename' at your current location. Use any filename extension that you might need, e.g. '.txt'.
Source: https://superuser.com/questions/502374/equivalent-of-linux-touch-to-create-an-empty-file-with-powershell (see comments)
For a very simple version of touch which would be mostly used to create a 0 byte file in the current directory, an alternative would be creating a touch.bat file and either adding it to the %Path% or copying it to the C:\Windows\System32 directory, like so:
touch.bat
#echo off
powershell New-Item %* -ItemType file
Creating a single file
C:\Users\YourName\Desktop>touch a.txt
Directory: C:\Users\YourName\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2020-10-14 10:28 PM 0 a.txt
Creating multiple files
C:\Users\YourName\Desktop>touch "b.txt,c.txt"
Directory: C:\Users\YourName\Desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2020-10-14 10:52 PM 0 b.txt
-a---- 2020-10-14 10:52 PM 0 c.txt
Also
Works both with PowerShell and the Command Prompt.
Works with existing subdirectories.
Does not create a file if it already exists:
New-Item : The file 'C:\Users\YourName\Desktop\a.txt' already exists.
For multiple files, creates only the files that do not exist.
Accepts a comma-separated list of filenames without spaces or enclosed in quotes if spaces are necessary:
C:\Users\YourName\Desktop>touch d.txt,e.txt,f.txt
C:\Users\YourName\Desktop>touch "g.txt, 'name with spaces.txt'"
You can also use copy con [filename] in a Windows command window (cmd.exe):
C:\copy con yourfile.txt [enter]
C:\CTRL + Z [enter] //hold CTRL key & press "Z" then press Enter key.
^Z
1 Files Copied.
This will create a file named yourfile.txt in the local directory.
I use cmder (a command line emulator)
It allows you to run all Linux commands inside a Windows machine.
It can be downloaded from https://cmder.net/
I really like it
From the Terminal of Visual Code Studio on Windows 10, this is what worked for me to create a new file:
type > hello.js
echo > orange.js
ni > peach.js
As Raghuveer points out in his/her answer, ni is the PowerShell alias for New-Item, so you can create files from a PowerShell prompt using ni instead of touch.
If you prefer to type touch instead of ni, you can set a touch alias to the PowerShell New-Item cmdlet.
Creating a touch command in Windows PowerShell:
From a PowerShell prompt, define the new alias.
Set-Alias -Name touch -Value New-Item
Now the touch command works almost the same as you are expecting. The only difference is that you'll need to separate your list of files with commas.
touch index.html, app.js, style.css
Note that this only sets the alias for PowerShell. If PowerShell isn't your thing, you can set up WSL or use bash for Windows.
Unfortunately the alias will be forgotten as soon as you end your PowerShell session. To make the alias permanent, you have to add it to your PowerShell user profile.
From a PowerShell prompt:
notepad $profile
Add your alias definition to your profile and save.
If you have Cygwin installed in your PC, you can simply use the supplied executable for touch (also via windows command prompt):
C:\cygwin64\bin\touch.exe <file_path>
Assuming the file exists and you just need to update the timestamp.
type test.c > test.c.bkp && type test.c.bkp > test.c && del test.c.bkp
Use rem. > file.txt (notice the dot attached to the command "rem")
this creates an empty file
Shortest possible vanilla solution is :
.>myfile.txt
You will get an error , but file is created :
If you are using VS Code, there is a command line tool code to help you open a non-exist file in VS Code.
There is something missing in all of the other answers. The Linux touch command has a -t option, which lets you set the last modified time to any arbitrary date and time, not just the current time.
This sets the modification date of filename.txt to 20 December 2012 at 30 minutes after midnight.
touch -t 201212210030 filename.txt
To get the equivalent in Windows, you need to be in PowerShell, it can't be done in Cmd.
Change the creation date/timestamp of a file named filename.txt:
(Get-Item "D:\Test\filename.txt").CreationTime=("21 December 2012 00:30:00")
Change the last write date/timestamp of a file named filename.txt:
(Get-Item "D:\Test\filename.txt").LastWriteTime=("21 December 2012 00:30:00")
Change the last accessed date/timestamp of a file named filename.txt:
(Get-Item "D:\Test\filename.txt").LastAccessTime=("21 December 2012 00:30:00")
Using PowerShell, type: ni index.html or ni style.css or ni app.js
ni <filename>.<extension>
If you have WSL with the appropriate distro like Ubuntu you can have the touch command in the CMD and not just the bash terminal. It works for me on Windows 10 & 11 Windows Terminal
Easy, example with txt file
echo $null >> filename.txt
Yes you can use Node for Touch I just use that and its working all fine in windows Cmd or gitbash
Use type instead of touch
type YOUR_FILE_NAME
However, it is limited to just a single file

Lua programming - os.execute() is not working in Windows

I'm creating a function in pure-Lua to scan the files from a directory and put they on a another file.
The command I tryed was:
os.execute( "dir /B C:\\Users\\Fernando\\workspace\\Organizator2\\s1 >
C:\\Users\\Fernando\\workspace\\Organizator2\\temp.txt" )
but... dont works! I did many tests with others simpler commands, like "start notepad" or "mkdir C:\test", and they dont worked too! The worse part is that I tryed this same commands directly in the Prompt, and there is all correct.
I tryed use tooo the io.popen(), but it the system returned "illegal operation" for any command i passed (even a empty string!).
here is the all code:
function ScanDirectory(source, str)
local str = str or "temp.txt"
os.execute("dir /B "..source.." > "..str)
directory = io.open(str,"r")
return directory
end
-- main script
do
local source = "C:\\Users\\Fernando\\workspace\\Organizator2\\s1"
local directory = ScanDirectory(source, "C:\\Users\\Fernando\
\workspace\\Organizator2\\temp.txt")
end
I'm using windows 7 and the Luaforwindows, 5.1, and the LuaEclipse
Have someone ever seen a problem like this?
Please try it with this syntax:
os.execute [["dir /B C:\Users\Fernando\workspace\Organizator2\s1 >
C:\Users\Fernando\workspace\Organizator2\temp.txt"]]
Please note that the backslash (\) is not a special character in this case.
(Lua uses cstrings internally, sometimes it leads to some weird and amazing results :P)
Most of the commands you listed appear to be shell commands that only work within a command prompt. Try running cmd.exe directly to see if you get a prompt, and if so, you can try passing commands to cmd.exe via the /c option. You could also try notepad without the start to see if that runs.
os.execute('cmd.exe /c dir /B C:\\> C:\\test.txt')
That works. Useing Linux-style commands in win is a bad idea at all =)
I just tested your code on my computer and it works correct (with my directories, of course). Maybe you are not getting the expected result because your directory string is broken with an newline char, resulting in:
dir /B C:\Users\Fernando\workspace\Organizator2\s1 > C:\Users\Fernando\
workspace\Organizator2\temp.txt
The correct should be:
dir /B C:\Users\Fernando\workspace\Organizator2\s1 > C:\Users\Fernando\workspace\Organizator2\temp.txt
Please try changing the do end to:
local source = "C:\\Users\\Fernando\\workspace\\Organizator2\\s1"
local directory = ScanDirectory(source, "C:\\Users\\Fernando\\workspace\\Organizator2\\temp.txt")

Resources