I am trying to use exec to run a command such as dir with cmd using tcl code, however the terminal window opens up and I am unable to store the result, when the command has run, into a variable ?
This is what I've been trying so far,
set res [exec cmd.exe /c "dir" &];
When I print out the variable using,
puts $res
I get back just three or four digit codes instead of the actual result when the command was run.
Any help is appreciated.
set res [exec cmd.exe /c "dir" &]
The & at the end of the exec indicates that the command will be processed in the background. The result returned is the process id of the command.
To do what you want, use:
set res [exec cmd.exe /c "dir"]
It would be far more efficient and less resource hungry to use the built-in glob command to get a list of files or search for a file.
set res [glob *.txt]
set res [glob -directory {C:/Program Files} *]
References: exec glob
Related
I am running an application which opens CMD and connect via API service. Throughout the day new stuff will show up in the CMD and I would like to export that information to txt somewhere and Everytime something new shows up append to the same file, or create a new one. It doesn't really matter
App.exe > /file.txt doesn't really work
Redirection examples
command > filename # Redirect command output to a file (overwrite)
command >> filename # APPEND into a file
command 2> filename # Redirect Errors from operation to a file(overwrite)
command 2>> filename # APPEND errors to a file
command 2>&1 # Add errors to results
command 1>&2 # Add results to errors
command | command # This is the basic form of a PowerShell Pipeline
# In PowerShell 3.0+
command 3> warning.txt # Write warning output to warning.txt
command 4>> verbose.txt # Append verbose.txt with the verbose output
command 5>&1 # Writes debug output to the output stream
command *> out.txt # Redirect all streams (output, error, warning, verbose, and debug) to out.txt
You are not showing any code as to how you are starting/using cmd.exe for your use case. Which just leaves folks trying to help you, to guess. So, redirect of cmd.exe, for example:
$MyOutputFile = C:\MyOutputFile.txt
Start-Process -FilePath c:\windows\system32\cmd.exe -ArgumentList '/c C:\YourCommand.bat' -Wait -NoNewWindow -RedirectStandardOutput $MyOutputFile
Lastly, since you've left us to guess. If you’re launching Process A from PowerShell, but it, Process A is, in turn, launching Process B, then it would be up to Process A to capture or redirect the output of Process B. There’s no way for PowerShell to sub-capture if Process A isn’t doing it.
Resources
About Redirection
How-to: Redirection
PowerShell Redirection Operators
Understanding Streams, Redirection, and Write-Host in PowerShell
Use PowerShell Redirection Operators for Script Flexibility
In OSX, I open a bash terminal and enter a PowerShell console.
In my PowerShell script, I would like to open another PowerShell console and execute a PowerShell script there.
Under Windows, I would do
Invoke-Expression ('cmd /c start powershell -Command test.ps1')
How could I do the samething in OSX?
To start a PowerShell instance in a new terminal window on macOS:
Without being able to pass arguments to it:
PS> open -a Terminal $PSHOME/powershell
If you want to run a given command:
Unfortunately, quite a bit more work is needed if you want to pass a command to run in the new PowerShell instance:
In essence, you need to place your command in a temporary, self-deleting, executable shell script that is invoked via a shebang line:
Note: Be sure to run at least PowerShell Core v6.0.0-beta.6 for this to work.
Function Start-InNewWindowMacOS {
param(
[Parameter(Mandatory)] [ScriptBlock] $ScriptBlock,
[Switch] $NoProfile,
[Switch] $NoExit
)
# Construct the shebang line
$shebangLine = '#!/usr/bin/env powershell'
# Add options, if specified:
# As an aside: Fundamentally, this wouldn't work on Linux, where
# the shebang line only supports *1* argument, which is `powershell` in this case.
if ($NoExit) { $shebangLine += ' -NoExit' }
if ($NoProfile) { $shebangLine += ' -NoProfile' }
# Create a temporary script file
$tmpScript = New-TemporaryFile
# Add the shebang line, the self-deletion code, and the script-block code.
# Note:
# * The self-deletion code assumes that the script was read *as a whole*
# on execution, which assumes that it is reasonably small.
# Ideally, the self-deletion code would use
# 'Remove-Item -LiteralPath $PSCommandPath`, but,
# as of PowerShell Core v6.0.0-beta.6, this doesn't work due to a bug
# - see https://github.com/PowerShell/PowerShell/issues/4217
# * UTF8 encoding is desired, but -Encoding utf8, regrettably, creates
# a file with BOM. For now, use ASCII.
# Once v6 is released, BOM-less UTF8 will be the *default*, in which
# case you'll be able to use `> $tmpScript` instead.
$shebangLine, "Remove-Item -LiteralPath '$tmpScript'", $ScriptBlock.ToString() |
Set-Content -Encoding Ascii -LiteralPath $tmpScript
# Make the script file executable.
chmod +x $tmpScript
# Invoke it in a new terminal window via `open -a Terminal`
# Note that `open` is a macOS-specific utility.
open -a Terminal -- $tmpScript
}
With this function defined, you can invoke PowerShell with a given command - specified as a script block - as follows:
# Sample invocation
Start-InNewWindowMacOS -NoExit { Get-Date }
I don't know anything about powershell on mac, if that even exists but to open a gui application like a terminal on Mac OS X you can use the open command:
open -a /Applications/Utilities/Terminal.app "" would be a new blank window
open -a /Applications/Utilities/Terminal.app somescrip.sh would be to run a script
or you can make an apple script and run that
save the following in a file (~/OpenNewTerminal.scp):
tell application "Terminal"
do script " "
activate
end tell
then you can run it with osascript
osascript ~/OpenNewTerminal.scp
of course the more bash idiomatic way would be to run in a subshell or in the background
subshell:
output=$(ls)
echo $output
background:
./command &
background with redirected output so it doesn't bleed into your current shell:
./command 2>&1 > /dev/null
I have this kind of batch file
start /b ruby script.rb && echo done
...
However, it write 'done' immediately after i run the batch file, which is incorrect, as the script took about 5 mins.
So, how to echo done only after the bg task succesfully end?
thank you!
note: I think that && operator work this way if it is not used in batch file nor in usage to run bg task.
start "" /b cmd /c "ruby script.rb && echo done"
Without the quotes the conditional execution command is seen as the continuation of the start command instead of continuation of the ruby command.
As the && is an operator handled by cmd we need to start a new instance.
The "" at the start are needed as the first quoted argument to start is handled as a window title.
note: && is an conditional execution operator. If the previous command does not generate an error then the following command is executed. In this case with the process running in background, probably, &, the command concatenation operator, should be used to know that the script ended.
Am new to ruby.
I have a terminal command to exeute some process and output the result as an xml file.(it is working properly fine via terminal)
cmd = '"C:\Program Files\shark\hark" -f "ains 02:04" -eT xml > test12.xml'
i need to execute this command using ruby code.
But when i tried using ruby code it outputs the xml file and its contents will be zero.if i quit the terminal using CTRL + C i will get the full data inside the xml file
For exiting the child process i tried to kill the process and killed the ruby.exe from the task list .But nothing happned in the xml file.its contents is still zero
code
def execute
cmd = '"C:\Program Files\shark\hark" -f "ains 02:04" -eT xml > test12.xml'
#pid = Process.spawn(cmd)
sleep(100)
exec( 'Taskkill /F /IM ruby.exe' )
end
execute
whats wrong with my code.
I think that Process.wait doesn't support stream redirection. In other words, |, >, >> and < don't work.
I want to get the result of a simple command from the command line (cmd.exe) using a Windows script (.vbs). How is this done? I haven't been able to find a good/simple example or explanation. You could use the "date" or "time" command to provide an example with.
Such as:
P.S. I am able to write the script code that opens cmd.exe and sends the command.
Thanks!
When in doubt, read the documentation. You probably want something like this:
Set p = CreateObject("WScript.Shell").Exec("%COMSPEC% /c date /t")
Do While p.Status = 0
WScript.Sleep 100
Loop
WScript.Echo p.StdOut.ReadAll
Edit: When using Exec() you pass input via the .StdIn descriptor, not via SendKeys() (which is a rather unreliable way of passing input anyway).
%COMSPEC% is a system environment variable with the full path to cmd.exe and the /c option makes cmd.exe exit after the command (date /t in the example) is finished.
If the command indicates success/failure with an exit code, you can check the ExitCode property after the command finished.
If p.Status <> 0 Then WScript.Echo p.ExitCode
Edit2: Instead of using atprogram interactively, can you construct commandlines that will perform particular tasks without user interaction? With non-interactive commandlines something like this might work:
prompt = "C:\>"
atprogram_cmdline_1 = "atprogram.exe ..."
atprogram_cmdline_2 = "atprogram.exe ..."
'...
Function ReadOutput(p)
text = ""
Do Until Right(text, Len(prompt)) = prompt
text = text & p.StdOut.Read(1)
Loop
ReadOutput = text
End Function
Set cmd = CreateObject("WScript.Shell").Exec("%COMSPEC% /k")
ReadOutput cmd ' skip over first prompt
cmd.StdIn.WriteLine(atprogram_cmdline_1)
WScript.Echo ReadOutput(cmd)
cmd.StdIn.WriteLine(atprogram_cmdline_2)
WScript.Echo ReadOutput(cmd)
'...
cmd.Terminate ' exit CMD.EXE
%COMSPEC% /k spawns a command prompt without running a command. The /k prevents it from closing. Because it isn't closing automatically, you can't use the While p.Status = 0 loop here. If a command needs some time to finish, you need to WScript.Sleep a number of seconds.
Via cmd.StdIn.WriteLine you can run commandlines in the CMD instance. The function ReadOutput() reads the output from StdOut until the next prompt appears. You need to look for the prompt, because read operations are blocking, so you can't simply say "read all that's been printed yet".
After you're finished you quit CMD.EXE via cmd.Terminate.