Semantics of Windows batch programming redirection - batch-file

I have a Windows batch script (my.bat) which has the following line:
DTBookMonitor.exe 2>&1 > log\cmdProcessLog.txt
So, from my understanding, this runs DTBookMonitor, redirects STDERR to STDOUT and then redirects STDOUT to the file log\cmdProcessLog.txt.
I then run my.bat. DTBookMonitor runs for a significant amount of time, and when I run my.bat a second time (while it is already running), it immediately exits from the second instance of my.bat.
Is this purely because of the redirection to cmdProcessLog?

Better late then never :)
Windows redirection locks the output file so that no other process can open the file for writing at the same time. That is why the second instance fails when it tries to redirect output to the same file.

I'd guess it's either due to that, or because DTBookMonitor only allows one instance of it to run at a time. The following test should shed some light on the situation:
Run the first (long) instance of DTBookMonitor
Run a second instance without redirecting any of its output
Alternatively, run a second instance, but redirect the output to a file other than log\cmdProcessLog.txt
Do you get similar results? Different results?

Related

How do I copy everything from my terminal to a file including the stdout and the prompt using C?

I know how to get the stdout into a file using dup/dup2 system calls, but how do I get the entire output that would be normally shown on my terminal(including the prompt that says my username along with the $ symbol and the current working directory) to a file?
Yes you can, but this may be difficult in many details (depending on your expert level). For the shell to behave normally (I would mean exactly as in a terminal), then it needs to interact with a terminal (special system object). So you need to create a program that behave like a terminal, this what pseudo-terminals devices (/dev) are intended for. Read documentation about this to implement it but roughly, your application should behave like the user so should be connected to the slave side of the pseudo-terminal, and the shell to the master side of the pseudo-terminal. Then you can easily log real inputs made by the user and catch outputs made by the shell.
Can't comment cause of low reputation.
I would say there is no way to do that inside a code in C. Instead, you could use bash for example to redirect everything to a file, and leave the code in C as it is.
In this way you have all the info you want to save: prompt, current directory, call to the program (including flags), and of course the output of the program.
Well, you can do:
-For bash prompt PS1: Echo expanded PS1 (in case you want it expanded, if not there is a simple way to do it just echong PS1)
- For executed command: https://unix.stackexchange.com/questions/169259/how-to-capture-command-line-input-into-logfile-and-execute-it-at-the-same-time
- Standard output and error output: Redirect stderr and stdout in a Bash script
And that's all you want to capture, I think.
Look up the script command in Unix systems. If you want to capture all keyboard and std in/out for a command, use the script executable. If you want to see how it's done, look up the source.

Trying to run a batch file from another program and redirecting the output

I have a method to run a batch file with a list of parameters. Those parameters are sent to the batch file and the batch file calls another program that needs the parameter set up in a certain way:
start test --entities=%entities% --tags=%out% --start=%start% --end=%end% --interval=%interval% --wide>%output%
Where output is the file I want the results of running:
test --entities=%entities% --tags=%out% --start=%start% --end=%end% --interval=%interval% --wide
To be placed but I keep getting 1> instead of > when I run the file.
> is just a short form of 1> (1 means STDOUT = Standard output stream). Command repetition will insert the 1 for you, if you didn't write it. That's neither a failure nor a problem.
Your actual problem is, that you redirect the output of the start command - which is empy.
To redirect the output of your batchfile, use
start test --entities=%entities% --tags=%out% --start=%start% --end=%end% --interval=%interval% --wide ^>%output%
You might want to try, if
call test --entities=%entities% --tags=%out% --start=%start% --end=%end% --interval=%interval% --wide >%output%
works even better for you.
Check out Ryan's Guide to Piping and Redirection: http://ryanstutorials.net/linuxtutorial/piping.php .

Batch fork bomb? [duplicate]

If you run a .bat or .cmd file with %0|%0 inside, your computer starts to use a lot of memory and after several minutes, is restarted. Why does this code block your Windows? And what does this code programmatically do? Could it be considered a "bug"?
This is the Windows version of a fork bomb.
%0 is the name of the currently executing batch file. A batch file that contains just this line:
%0|%0
Is going to recursively execute itself forever, quickly creating many processes and slowing the system down.
This is not a bug in windows, it is just a very stupid thing to do in a batch file.
This is known as a fork bomb.
It keeps splitting itself until there is no option but to restart the system.
http://en.wikipedia.org/wiki/Fork_bomb
What it is:
%0|%0 is a fork bomb. It will spawn another process using a pipe | which runs a copy of the same program asynchronously. This hogs the CPU and memory, slowing down the system to a near-halt (or even crash the system).
How this works:
%0 refers to the command used to run the current program. For example, script.bat
A pipe | symbol will make the output or result of the first command sequence as the input for the second command sequence. In the case of a fork bomb, there is no output, so it will simply run the second command sequence without any input.
Expanding the example, %0|%0 could mean script.bat|script.bat. This runs itself again, but also creating another process to run the same program again (with no input).
%0 will never end, but it never creates more than one process because it instantly transfers control to the 2nd batch script (which happens to be itself).
But a Windows pipe creates a new process for each side of the pipe, in addition to the parent process. The parent process can't finish until each side of the pipe terminates. So the main program with a simple pipe will have 3 processes. You can see how the bomb quickly get's out of control if each side of the pipe recursively calls the parent batch!
It's a logic bomb, it keeps recreating itself and takes up all your CPU resources. It overloads your computer with too many processes and it forces it to shut down. If you make a batch file with this in it and start it you can end it using taskmgr. You have to do this pretty quickly or your computer will be too slow to do anything.

create process independent of bash

I have written a program which calculates the amount of battery level available in my laptop. I have also defined a threshold value in the program. Whenever the battery level falls below threshold i would like to call another process. I have used system("./invoke.o") where invoke.o is the program that i have to run. I am running a script which runs the battery level checker program for every 5 seconds. Everything is working fine but when i close the bash shell the automatic invocation of invoke.o is not happening. How should i make the invoke.o to be invoked irrespective of whether bash is closed or not??. I am using UBUNTU LINUX
Try running it as: nohup ./myscript.sh, where the nohup command allows you to close the shell without terminating the process.
You could run your script as a cron job. This lets cron set up standard input and output for you, reschedule the job, and it will send you email if it fails.
The alternative is to run a script in the background with all input and output, including standard error output, redirected.
While you could make a proper daemon out of your program that kind of effort is probably not necessary.
man nohup
man upstart
man 2 setsid (more complex, leads to longer trail of breadcrumbs on daemon launching).

System call time out?

I'm using unix system() calls to gunzip and gzip files. With very large files sometimes (i.e. on the cluster compute node) these get aborted, while other times (i.e. on the login nodes) they go through. Is there some soft limit on the time a system call may take? What else could it be?
The calling thread should block indefinitely until the task you initiated with system() completes. If what you are observing is that the call returns and the file operation as not completed it is an indication that the spawned operation failed for some reason.
What does the return value indicate?
Almost certainly not a problem with use of system(), but with the operation you're performing. Always check the return value, but even more so, you'll want to see the output of the command you're calling. For non-interactive use, it's often best to write stdout and stderr to log files. One way to do this is to write a wrapper script that checks for the underlying command, logs the commandline, redirects stdout and stderr (and closes stdin if you want to be careful), then execs the commandline. Run this via system() rather than the OS command directly.
My bet is that the failing machines have limited disk space, or are missing either the target file or the actual gzip/gunzip commands.
I'm using unix system() calls to
gunzip and gzip files.
Probably silly question: why not use zlib directly from your application?
And system() isn't a system call. It is a wrapper for fork()/exec()/wait(). Check the system() man page. If it doesn't unblock, it might be that your application interferes somehow with wait() - e.g. do you have a SIGCHLD handler?
If it's a Linux system I would recommend using strace to see what's going on and which syscall blocks.
You can even attach strace to already running processes:
# strace -p $PID
Sounds like I'm running into the same intermittent issue indicating a timeout of some kind. My script runs every day. I'm starting to believe GZIP has a timeout.
gzip -vd filename.txt.gz 2>> tmp/errorcatch.txt 1>> logfile.log
stderr: Error for filename.txt.gz
Moves to next command 'cp filename* new/directory/', resulting in zipped version of filename in new directory
stdout from earlier gzip showing successful unzip of SAME file:
filename.txt.gz: 95.7% -- replaced with filename.txt
Successful out file from gzip is not there in source or new directory.
Following alerts, manual run of 'gzip -vd filename.txt.gz' never fails.
Details:
Only one call in script to unzip that file
Call for unzip is inside a function (for more rebust logging and alerting)
Unable to strace in production
Unable to replicate locally
In occurences over last month, found no consistency among file size, only
I'll simply be working around it with a retry logic and general scripting improvements, but I want the next google-er to know they're not crazy. This is happening to other people!

Resources