Suppose in a CMD (Windows 7) batch file I want to print the contents of a directory. I'd expect to do something like this:
dir | print
But this doesn't work, because print apparently requires a file. Is there an intelligent one-liner to do this? (preferably not involving file manipulation)
You can do the following
dir > f && print f
If you get the error Unable to initialize device PRN, then you will need to specify the printer using the /D: switch with the print command. You can also delete the file after running the command if you want.
dir > f && print f /D:"Printer Name" && del f
To do it without outputting to a file you can just redirect the command output to a shared printer.
dir > \\share\printer
To get a list of shared printers use PowerShell
get-WmiObject -class Win32_printer | ft name, systemName, shareName
I prefer outputting to a file then printing the file, so the name of the print job has some relevance to the actual content.
Is it possible to write the same output to more than one file in Batch?
My reason for wanting to do this is because I have a large batch script that produces a very detailed log. This is fine as it is, but i want to also output a trimmed back version of the log with a lot less detail in it. The Batch cannot be run multiple times either.
Say for instance I have a simple batch:
Echo This is a Batch Script >> Path\File1 & Path\File2
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% >> Path\File1
Appreciate any help.
Maybe you can use the tee command from Unix tools. Downloadable for free from here. Think of it like a "T" that a plumber might put in a pipe to send water two ways.
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee file1 file2 file3
Have a look at some examples as I am not entirely sure what your full processing requirement is, see here.
If you want to do some processing on one stream you can do this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | tee unfiltered.txt | FINDSTR /v "UglyStuff" > filtered.txt
Second answer, because it is different...
You could use some VBScript, like this to send your osql output to both stdout and stderr and then handle the two separately. This saves you needing to install any Unix tools.
Save this as tee.vbs
REM ############################################################################
REM File: tee.vbs
REM Author: Mark Setchell
REM I don't need any Unix purists to tell me it is not functionally idential to
REM the Unix 'tee' command, please. It does a job - that's all. And I also know
REM there is no error checking. It illustrates a technique.
REM ############################################################################
Set fso = CreateObject ("Scripting.FileSystemObject")
Set stdout = fso.GetStandardStream (1)
Set stderr = fso.GetStandardStream (2)
Do While Not WScript.StdIn.AtEndOfStream
REM Read in next line of input
Line = WScript.StdIn.ReadLine()
stdout.WriteLine(Line)
stderr.WriteLine(Line)
Loop
Then run your osql like this:
osql -S%SERVERNAME% -E -d%DATABASENAME% -Q%SQL% | cscript /nologo tee.vbs 2> unfiltered.txt | FINDSTR "goodstuff" > filtered.txt
Basically, whatever the tee.vbs script writes to stderr gets redirected to wherever 2> points, and whatever tee.vbs writes to stdout goes into the FINDSTR command.
Ideally, you could put your filtering inside the tee.vbs file for maximum flexibility.
I'm strugling at passing arguments to a PL/SQL script from a Windows .bat file.
Here is the content of the batch file :
#echo off
set mName = "test"
exit | sqlplus <connection_string> #test.sql %mName%
pause
And here is the content of test.sql :
set verify off
set serveroutput on size unlimited
BEGIN
DBMS_OUTPUT.PUT_LINE('&&1');
END;
/
I would expect to see "test" appearing in the shell but instead, I get the following message :
Enter value for 1:
SP2-0546: User requested Interrupt or EOF detected.
Does anyone have a solution to this problem ?
Remove the spaces around your = sign. Here's my working batch file:
#echo off
set mName="test"
exit | sqlplus <connection_string> #test.sql %mName%
pause
Also note that you can use the -L option on sqlplus for batch jobs:
-L Attempts to log on just once, instead of reprompting on error.
I want to redirect all console text to a file. Here is what I tried:
> sink("test.log", type=c("output", "message"))
> a <- "a"
> a
> How come I do not see this in log
Error: unexpected symbol in "How come"
Here is what I got in test.log:
[1] "a"
Here is what I want in test.log:
> a <- "a"
> a
[1] "a"
> How come I do not see this in log
Error: unexpected symbol in "How come"
What am I doing wrong? Thanks!
You have to sink "output" and "message" separately (the sink function only looks at the first element of type)
Now if you want the input to be logged too, then put it in a script:
script.R
1:5 + 1:3 # prints and gives a warning
stop("foo") # an error
And at the prompt:
con <- file("test.log")
sink(con, append=TRUE)
sink(con, append=TRUE, type="message")
# This will echo all input and not truncate 150+ character lines...
source("script.R", echo=TRUE, max.deparse.length=10000)
# Restore output to console
sink()
sink(type="message")
# And look at the log...
cat(readLines("test.log"), sep="\n")
If you have access to a command line, you might prefer running your script from the command line with R CMD BATCH.
== begin contents of script.R ==
a <- "a"
a
How come I do not see this in log
== end contents of script.R ==
At the command prompt ("$" in many un*x variants, "C:>" in windows), run
$ R CMD BATCH script.R &
The trailing "&" is optional and runs the command in the background.
The default name of the log file has "out" appended to the extension, i.e., script.Rout
== begin contents of script.Rout ==
R version 3.1.0 (2014-04-10) -- "Spring Dance"
Copyright (C) 2014 The R Foundation for Statistical Computing
Platform: i686-pc-linux-gnu (32-bit)
R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.
Natural language support but running in an English locale
R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.
Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.
[Previously saved workspace restored]
> a <- "a"
> a
[1] "a"
> How come I do not see this in log
Error: unexpected symbol in "How come"
Execution halted
== end contents of script.Rout ==
If you are able to use the bash shell, you can consider simply running the R code from within a bash script and piping the stdout and stderr streams to a file. Here is an example using a heredoc:
File: test.sh
#!/bin/bash
# this is a bash script
echo "Hello World, this is bash"
test1=$(echo "This is a test")
echo "Here is some R code:"
Rscript --slave --no-save --no-restore - "$test1" <<EOF
## R code
cat("\nHello World, this is R\n")
args <- commandArgs(TRUE)
bash_message<-args[1]
cat("\nThis is a message from bash:\n")
cat("\n",paste0(bash_message),"\n")
EOF
# end of script
Then when you run the script with both stderr and stdout piped to a log file:
$ chmod +x test.sh
$ ./test.sh
$ ./test.sh &>test.log
$ cat test.log
Hello World, this is bash
Here is some R code:
Hello World, this is R
This is a message from bash:
This is a test
Other things to look at for this would be to try simply pipping the stdout and stderr right from the R heredoc into a log file; I haven't tried this yet but it will probably work too.
You can't. At most you can save output with sink and input with savehistory separately. Or use external tool like script, screen or tmux.
Run R in emacs with ESS (Emacs Speaks Statistics) r-mode. I have one window open with my script and R code. Another has R running. Code is sent from the syntax window and evaluated. Commands, output, errors, and warnings all appear in the running R window session. At the end of some work period, I save all the output to a file. My own naming system is *.R for scripts and *.Rout for save output files.
Here's a screenshot with an example.
You can print to file and at the same time see progress having (or not) screen, while running a R script.
When not using screen, use R CMD BATCH yourscript.R & and step 4.
When using screen, in a terminal, start screen
screen
run your R script
R CMD BATCH yourscript.R
Go to another screen pressing CtrlA, then c
look at your output with (real-time):
tail -f yourscript.Rout
Switch among screens with CtrlA then n
To save text from the console: run the analysis and then choose (Windows) "File>Save to File".
Set your Rgui preferences for a large number of lines, then timestamp and save as file at suitable intervals.
If you want to get error messages saved in a file
zz <- file("Errors.txt", open="wt")
sink(zz, type="message")
the output will be:
Error in print(errr) : object 'errr' not found
Execution halted
This output will be saved in a file named Errors.txt
In case, you want printed values of console to a file you can use 'split' argument:
zz <- file("console.txt", open="wt")
sink(zz, split=TRUE)
print("cool")
print(errr)
output will be:
[1] "cool"
in console.txt file. So all your console output will be printed in a file named console.txt
This may not work for your needs, but one solution might be to run your code from within an Rmarkdown file. You could write both the code and console output to HTML/PDF/Word.
I have a batch file which calls a java program.
The output is redirected to a log file in the same directory.
However the log file is replaced everytime the batch file is run...
I would like to keep the old outputs in the log file and always append the new output to the log file.
Instead of using ">" to redirect like this:
java Foo > log
use ">>" to append normal "stdout" output to a new or existing file:
java Foo >> log
However, if you also want to capture "stderr" errors (such as why the Java program couldn't be started), you should also use the "2>&1" tag which redirects "stderr" (the "2") to "stdout" (the "1"). For example:
java Foo >> log 2>&1
This is not an answer to your original question: "Appending output of a Batch file To log file?"
For reference, it's an answer to your followup question: "What lines should i add to my batch file which will make it execute after every 30mins?"
(But I would take Jon Skeet's advice: "You probably shouldn't do that in your batch file - instead, use Task Scheduler.")
Timeout:
timeout command 1
timeout command 2
Example (1 second):
TIMEOUT /T 1000 /NOBREAK
Sleep:
sleep command (if sleep.exe is installed)
Example (1 second):
sleep -m 1000
Alternative methods:
Sleeping in a batch file
batch script, put to sleep until certain time
Here's an answer to your 2nd followup question: "Along with the Timestamp?"
Create a date and time stamp in your batch files
Example:
echo *** Date: %DATE:/=-% and Time:%TIME::=-% *** >> output.log
Use log4j in your java program instead. Then you can output to multiple media, create rolling logs, etc. and include timestamps, class names and line numbers.
It's also possible to use java Foo | tee -a some.log. it just prints to stdout as well. Like:
user at Computer in ~
$ echo "hi" | tee -a foo.txt
hi
user at Computer in ~
$ echo "hello" | tee -a foo.txt
hello
user at Computer in ~
$ cat foo.txt
hi
hello