Wednesday, March 16, 2011

How to capture and display output from a task via Windows CMD

Hi,

I've got a PHP script which I'm running from a command line (windows) that performs a variety of tasks, and the only output it gives is via 'print' statements which output direct to screen.

What I want to do is capture this to a log file as well.

I know I can do:

php-cli script.php > log.txt

But the problem with this approach is that all the output is written to the log file, but I can't see how things are running in the mean time (so I can stop the process if anything dodgy is happening).

Just to pre-empt other possible questions, I can't change all the print's to a log statement as there are far too many of them and I'd rather not change anything in the code lest I be blamed for something going fubar. Plus there's the lack of time aspect as well. I also have to run this on a windows machine.

Thanks in advance :)

Edit: Thanks for the answers guys, in the end I went with the browser method because that was the easiest and quickest to set up, although I am convinced there is an actual answer to this problem somewhere.

From stackoverflow
  • You can create a powershell script that runs the command, reads the data from the command's STDOUT then outputs the output to both the log file and the terminal for you to watch. You can use the commands Write-Output and Write-Host.

    Microsoft's site: http://www.microsoft.com/technet/scriptcenter/topics/msh/cmdlets/tee-object.mspx

    Another option would be use find a tee program that will read input and divert it to two different outputs. I believe I have seen these for windows but I don't think they are standard.

    Wikipedia: http://en.wikipedia.org/wiki/Tee_(command)

    Jay : actually, powershell already includes "tee" so no need to write a powershell script :-)
  • I have always opened the log file up in my web browser. This allows me to refresh it easily and does not interrupt any writing to the file that windows does. It isn't particularly elegant but it does work!

    Jay : You could also use the "tail" command (there are several Windows versions, such as mtail), which would be real-time and avoid the need for manual refreshing.
  • Slow:

    for /f "delims=" %a in ('php-cli script.php') do @echo %a&echo %a>>log.txt
    

    or in a batch file:

    for /f "delims=" %%a in ('php-cli script.php') do @echo %%a&echo %%a>>log.txt
    
  • You want the "tee" command for Windows. See http://en.wikipedia.org/wiki/Tee_(command)

    Powershell includes a tee command, and there are also numerous versions of tee for Windows available, for instance:

    Also can be implemented in VBScript if you prefer.

    EDIT: Just occurred to me I should also mention the tail command: http://en.wikipedia.org/wiki/Tail_(Unix). Tail allows you to read the last N lines of a file, and also includes a "file monitor" mode that just continually displays the end of the file in real-time. This is perfect for log file monitoring since it allows you to watch the log in real-time without interfering with the process that's writing to the log. There are several implementations of tail for Windows, both command line and GUI based. Microsoft's Services For UNIX packages (or whatever they're calling it now) also include a version of tail. Some examples:

    Some of these go far beyond just displaying the file in real-time as it updates and can send email alerts and colorize string matches, monitor multiple files at once, etc.

What is the Managed C++ equivalent to the C# using statement

How would one code the following C# code in Managed C++

void Foo()
{
    using (SqlConnection con = new SqlConnection("connectionStringGoesHere"))
    {
         //do stuff
    }
}

Clarificaton: For managed objects.

From stackoverflow
  • I don't think, there is some syntax sugare like "using( ... ) { ... }";

    You can write only:

    SqlConnection cnn = new SqlConnection( ... );
    try {
        ...
    }
    finally {
        cnn->Dispose();
    }
    
    Christian.K : Wrong, see "jyoung" answer. Besides you cannot call "Dispose()", but must use "delete cnn", and new should be gcnew.
    TcKs : Yes, you right with delete, but the "Dispose()" should be called before, or not?
    Christian.K : No, actually it is not accessible (not public). In C++/CLI, the destructor *is* the Dispose() operation.
    Robert S. : Tip: Never guess an answer on SO.
  • If you're concerned about limiting the variable's lifetime rather than automatic disposal, you can always just put it into its own scope:

    void Foo()
    {
        {
            SqlConnection con = new SqlConnection("connectionStringGoesHere");
            // do stuff
            // delete it before end of scope of course!
        }
    }
    
    Christian.K : This will neither call the destructor at the end of the scope, nor will "Dispose()" be called. It that sense it has the same effect as in C#.
    Mike Hall : Yes, you're correct. It won't. I assumed that would be done in the "do stuff" part. All I was pointing out is that con can't be accessed outside of that new scope.
  • To to that in Managed C++ just use stack semantics.

    void Foo(){
       SqlConnection con("connectionStringGoesHere");
        //do stuff
    }
    

    When con goes out of scope the "Destructor", ie Dispose(), is called.

    orip : +1, http://en.wikipedia.org/wiki/Resource_acquisition_is_initialization
  • Assuming you mean C++/CLI (not the old Managed C++), the following are your options:

    (1) Mimic a using-Block with using automatic / stackbased objects:

    {
      SqlConnection conn(connectionString);
    }
    

    This will call the Destructor of the "conn" Object when the next enclosing block ends. Whether this is the enclosing function, or a block you manually add to limit scope doesn't matter.

    (2) Explicitly call "Dispose", i.e. destruct the object:

    SqlConnection^ conn = nullptr;
    try
    {
      conn = gcnew SqlConnection(conntectionString);
    
    }
    finally
    {
      if (conn != nullptr)
        delete conn;
    }
    

    The first one would be the direct replacement for "using". The second one is an option, typically you won't need to do unless you optionally pass the reference to somewhere else.

    Coderer : Is the first syntax (using bare curly-braces to limit scope) guaranteed to call Dispose even if you leave scope by throwing an exception? I did not think that was the case, but of course I could be wrong.
    Christian.K : Yes its guaranted. Indeed that is the idea here. Destructors of stack-allocated objects are called when the enclosing scope ends (either regularly or prematurely by an exception) - actually that has nothing to do with managed or not. It is also this way in native code.
  • You could do something similar in an auto_ptr style:

    void foo()
    {
        using( Foo, p, gcnew Foo() )
        {
            p->x = 100;
        }
    }
    

    with the following:

    template <typename T>
    public ref class using_auto_ptr
    {
    public:
        using_auto_ptr(T ^p) : m_p(p),m_use(1) {}
        ~using_auto_ptr() { delete m_p; }
        T^ operator -> () { return m_p; }
        int m_use;
    private:
        T ^ m_p;
    };
    
    #define using(CLASS,VAR,ALLOC) \
        for ( using_auto_ptr<CLASS> VAR(ALLOC); VAR.m_use; --VAR.m_use)
    

    For reference:

    public ref class Foo
    {
    public:
        Foo() : x(0) {}
        ~Foo()
        {
        }
        int x;
    };
    

Upgrading to Access 2007, Trust Center Issue

Is there a way to automatically set Trust Center locations in a network environment when upgrading to Access 2007?

From stackoverflow

Validate XML using a custom DTD in PHP

Is there a way (without installing any libraries) of validating XML using a custom DTD in PHP?

From stackoverflow
  • Take a look at PHP's DOM, especially DOMDocument::schemaValidate and DOMDocument::validate.

    The example for DOMDocument::validate is fairly simple:

    <?php
    $dom = new DOMDocument;
    $dom->Load('book.xml');
    if ($dom->validate()) {
        echo "This document is valid!\n";
    }
    ?>
    
    Andrei Savu : the only way to get the validation error is to use a custom error handler. really ugly. php sucks at error handling
    Andrei Savu : http://uk3.php.net/manual/en/domdocument.schemavalidate.php#62032 looks like there is a better way than a custom error handler
  • Does this help? http://www.topxml.com/php_xml_dom/dom_document_function_validate.asp

    <?php
    
    $doc = new DomDocument;
    
    //declare file variable
    
    $file = 'C:/topxml_demo/php/xml_files/employee.xml';
    
    //declare DTD
    
    $dtd  = 'C:/topxml_demo/php/xml_files/employee.dtd';
    
    // Load the xml file into DOMDocument
    
    $doc->Load($file);
    
    //validate the DOMDocument
    
    if ($doc->validate()) {
    
        print "$file is valid against the DTD.\n";
    
     } else {
    
         print "$file is invalid against the DTD.\n";
    
     }
    
    ?>
    
    nickf : you're not using the $dtd variable anywhere there.

How do I log to a table in SQL Server 2000?

I'm writing into a log file, but I want to log into a table named "Log" in my database.

How can I accomplish this?

From stackoverflow
  • Check out logging.apache.org for the log4X that fits the language you are using. I know they have log4j (Java) and log4net (C#/.Net). They also have examples on how to configure the logging framework to log to a database table instead of a file.

  • log4net has an AdoNetAppender, and a sample configuration right here.

    Stuart Helwig : The huge advantage of using log4net too, is that you can switch between logging to your SQL server, and any other method you like (files, event log...whatever) by simply altering your config file.