How do we save logs while building the code? - c

I am building code in C using make , how would I save build logs ?

If you both want to save the log and see it on the console, you could use the tee command:
make 2>&1 | tee build.log
The 2>&1 part is telling the shell to redirect stderr to stdout.

Typically the most interesting output (compiler warnings and errors) goes to stderr. In bash:
$ make 2> out
Then inspect the file nameed out. The 2> is a Bash output redirection operator.

Shell output redirection will help you here.
make 2>&1 > output.log
See: make output redirection

If you want to save the output of make then use:
make 1>std.out 2> err.out
The 1 means the standardoutput and 2 the erroroutput

If you use standard make, I assume you do it through a terminal, so you would only have to do : make >> mylogfile.log.
For more tricks about I/O redirection, take a look here.

make 2>&1 > output.log
This will help you

In addition to redirection proposed by another answers, consider the script utility which writes the complete log of your interaction with a shell and its children or with another program: both input and output.
Sometimes you have to intervene during make, fix something in place when it fails, restart again. When a thing like that is done in a hurry, it's beneficial to have a protocol of what you've done without having to think of logging or recording when you do it.

Related

Output to terminal different than I redirect output to file AND output to terminal

So for some reason when I run my script and have it output to the terminal just as it would, I get my intended output. Yet when I redirect the output to a file, I don't receive full output.
Let's say I have an executable named "filename" and run it "./filename", the output on the terminal is, let's say :
a
b
c
Yet if I do "./filename > output.txt" or "./filename |& tee output.txt", the output on the terminal AND the output.txt text file is just, let's say:
a
b
I know this isn't very specific, but my output is huge. I was thinking this would be general enough to provide general solutions/ possible problems.
I'm using a program someone else made, so I don't know where this additional output is called. Yet, it shouldn't matter since the functionality of the program doesn't change, just what's being output.
Without a minimal code sample to reproduce, it's very hard to guess what's going on.
But some things you could try:
Redirect all output streams to your file, i.e. your-script &> output.txt
Run it through strace and look for write and open calls to see what's going on
Read and debug the source code to figure out what's going on

Estimating the execution time of code on local linux system

I spend most of my time solving problems on Topcoder/SPOJ. So definitely I thought of performance (execution time) of my code on my system before submitting the code.
So, on searching I found time command in linux. But the problem is that it also includes the time for inputting the values for several test cases, in addition to processing time. So I thought of making an input file and sending that content to my code.
Something like
cat input.txt > ./myprogram
But this doesn't work. (I am not good at linux pipelining). Can anyone point out the mistake, or a better approach to judge my code execution time?
EDIT
All of my programs read from stdin
You need this:
./myprogram < input.txt
Or if you insist on the Useless Use of Cat:
cat input.txt | ./myprogram
You can put time in front of ./myprogram in either case.
You might want to look at xargs.
Something along the lines of
cat input.txt | xargs ./myprogram
You can add below code in your script for
assign the file descriptor to file for input and output fd # 3 is
Input file
exec 3< input.txt
Use read command in while loop to read the file line by line
while read -u 3 -r a
do

How can I redirect console output to file?

I'm new to c.
Is there any simple way to redirect all the console's output (printfs etc.) to a file using some general command line \ linkage parameter (without having to modify any of the original code)?
If so what is the procedure?
Use shell output redirection
your-command > outputfile.txt
The standard error will still be output to the console. If you don't want that, use:
your-command > outputfile.txt 2>&1
or
your-command &> outputfile.txt
You should also look into the tee utility, which can make it redirect to two places at once.
On unices, you can also do:
your-command | tee output file.txt
That way you'll see the output and be able to interact with the program, while getting a hardcopy of the standard output (but not standard input, so it's not like a teletype session).
As mentioned above, you can use the > operator to redirect the output of your program to a file as in:
./program > out_file
Also, you can append data to an existing file (or create it if it doesnt exit already by using >> operator:
./program >> out_file
If you really want to learn more about the (awesome) features that the command line has to offer I would really recommend reading this book (and doing lots of programming :))
http://linuxcommand.org/
Enjoy!
In Unix shells you can usually do executable > file 2> &1, whch means "redirect standard output to file and error output to standard output"

How to log output of unfinished / non-responding / hanging command in win7?

I want redirect console output of a command.
The thing is the command hangs midway (more or less) and even though it outputs to console the logfile is empty. I have also tried wtee.exe like so: com.exe | %pat%wtee.exe log.txt but it does not work.I need something that dumps the console in realtime.
I'm open to pretty much any solution including c++ and powershell csript etc.
For the record i need it to post some verbose output ( https://superuser.com/questions/564468/how-can-i-store-encfs6-xml-in-another-location-and-still-make-it-detectable )
Thanks in advance
UPDATE:
Wohoo it works.
Apparently i have to delete the logfile before i run the batch script + i had to redirect stderr to stdout before piping to wtee.exe like so:
mycommand.exe 2>&1 | wtee.exe %abspath%log.txt
if i use
mycommand.exe 2>&1 | wtee.exe -a %abspath%log.txt
then i do not have to delete the file every time.
Interesting idea the one with baretail but there is no need for it now. the stream is sent both to the console and to the log file.
Thanks a bunch
UPDATE2: i also used the gnuwin32 tag since tee and wtee are pretty much the same and so this applies to tee.exe, i think!
How exactly does it 'not work'? What happens if you redirect STDOUT and STDERR to a file (command >log.txt 2>&1)? Do you still get output on the console? If so, the command doesn't write to STDOUT, so tee (or wtee for that matter) doesn't get any input, because the pipe connects STDOUT of command with STDIN of tee. In that case try redirecting the handles 3-9 until you find the handle that the command writes to. Example:
command 3>log.txt
You can compensate for the missing console output by displaying the log file in a pager (e.g. baretail).
Once you found the handle you can redirect it to STDOUT and then pipe it into tee:
command 5>&1 | tee log.txt

How to redirect output away from /dev/null

I have an application that runs the a command as below:
<command> <switches> >& /dev/null
I can configure <command>, but I have no control over <switches> . All the output generated by this command goes to /dev/null. I want the output to be visible on screen or redirected to a log file.
I tried to use freopen() and related functions to reopen /dev/null to another file, but could not get it working.
Do you have any other ideas? Is this possible at all?
Thanks for your time.
PS: I am working on Linux.
Terrible Hack:
use a text editor in binary mode open the app, find '/dev/null/' and replace it with a string of the same length
e.g '~/tmp/log'
make a backup first
be carefull
be very carefull
did I mention the backup?
Since you can modify the command you run you can use a simple shell script as a wrapper to redirect the output to a file.
#!/bin/bash
"$#" >> logfile
If you save this in your path as capture_output.sh then you can add capture_output.sh to the start of your command to append the output of your program to logfile.
Append # at the end of your command so it becomes <command> # >& /dev/null, thus commenting out the undesired part.
Your application is probably running a shell and passing it that command line.
You need to make it run a script written by you. That script will replace >/dev/null in the command line with >>/your/log and call the real shell with the modified command line.
The first step is to change the shell used by the application. Changing the environment variable SHELL should suffice, i.e., run your application as
SHELL=/home/user/bin/myshell theApp
If that doesn't work, try momentarily linking /bin/sh to your script.
myshell will call the original shell, but after pattern-replacing the parameters:
#!/bin/bash
sh ${1+"${#/\>\/dev\/null/>>\/your\/log}"}
Something along these lines should work.
You can do this with an already running process by using gdb. See the following page: http://etbe.coker.com.au/2008/02/27/redirecting-output-from-a-running-process/
Can you create an alias for that command? If so, alias it to another command that dumps output to a file.
The device file /dev/tty references your application's controlling terminal - if that hasn't changed, then this should work:
freopen("/dev/tty", "w", stdout);
freopen("/dev/tty", "w", stderr);
Alternatively, you can reopen them to point to a log file:
freopen("/var/log/myapp.log", "a", stdout);
freopen("/var/log/myapp.err", "a", stderr);
EDIT: This is NOT a good idea and certainly not worth trying unless you know what this can break. It works for me, may work for you as well.
Ok, This is a really bad hack and probably not worth doing. Assuming that none of the other commands works, and you simply do not have access to the binary/application (which contains the command with /dev/null) and you cannot re-direct the output to other file (by replacing /dev/null).
Then, you can delete /dev/null ($> rm /dev/null) and create your own file at its place (preferably with a soft link) where all the data can be directed. When you are done, you can create the /dev/null once again using following command:
$> mknod -m 666 /dev/null c 1 3
Just to be very clear, this is a bad hack and certainly requires root permissions to work. High chances that your re-directed file may contain data from many other applications/binaries which are running and use /dev/null as sink.
It may not exactly redirect, but it allows to get the output wherever it's being sent
strace -ewrite -p $PID
It's not that cleen (shows lines like: write(#,) ), but works! (and is single-line :D ) You might also dislike the fact, that arguments are abbreviated. To control that use -s parameter that sets the maxlength of strings displayed.
It catches all streams, so You might want to filter that somehow.
You can filter it:
strace -ewrite -p $PID 2>&1 | grep "write(1"
shows only descriptor 1 calls. 2>&1 is to redirect stderr to stdout, as strace writes to stderr by default.
In perl, if you just want to redirect STDOUT to something slightly more useful, you can just do something like:
open STDOUT, '>>', '/var/log/myscript.log';
open STDERR, '>>', '/var/log/myscript.err';
at the beginning of your script, and that'll redirect it for the rest of your script.
Along the lines of e-t172's answer, can you set the last switch to (or append to it):
; echo
If you can put something inline before passing things to /dev/null (not sure if you are dealing with a hardcoded command), you could use tee to redirect to something of your choice.
Example from Wikipedia which allows escalation of a command:
echo "Body of file..." | sudo tee root_owned_file > /dev/null
http://en.wikipedia.org/wiki/Tee_(command)

Resources