-1

I am looking to pass the output from detectUpdateHomeML into a program called insertElement as command line arguments.

When I try to use the command

./insertElement  `./detectUpdateHomeML`

the program detectUpdateHomeML no longer outputs to the console nor does insertElement insert anything to the XML file.

When I replace detectUpdateHomeML with a test output program it all works as expected, the output program outputs and insertElement inserts the outputted information into the XML.

Why is it not working with detectUpdateHomeML?

detectUpdateHomeML output:

            std::cout << eventCount << " " << cascadeName << " " << timeFound();

            std::cout << std::flush;

int timeFound() {
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];
  time (&rawtime);
  timeinfo = localtime (&rawtime);
  strftime (buffer,80," %Y-%m-%dT%H:%M:%S",timeinfo);
  puts (buffer);
  eventCount++;
}

insertElement code

   #include "tinyxml2.h"
#include <iostream>

using namespace tinyxml2;

int main( int argc, const char* argv[] ) {

    XMLDocument doc;
    doc.LoadFile("homeML.xml");// Gets the root <homeML> element
    XMLElement *pRoot = doc.FirstChildElement("homeML");



/********************************************************************************************************************************************************************************
* Adds new startTimeStamp to <realTimeInformation> -> <startTimeStamp>.
* 
* TODO - data value is hard coded - it needs to enter the first time stamp recorded of that instance of object recognition.
*
********************************************************************************************************************************************************************************/
    XMLElement *pStartTimeStamp = pRoot->FirstChildElement("mobileDevice")->FirstChildElement("realTimeInformation");
    XMLElement *pRealtimeStore = nullptr;
    XMLElement *pIter0 = pStartTimeStamp->FirstChildElement("runID");
    while (pIter0 != nullptr) {
        pRealtimeStore = pIter0;
        pIter0 = pIter0->NextSiblingElement("startTimeStamp");
    }

    if (pRealtimeStore != nullptr) {
        XMLElement *pNewStartTimeStamp = doc.NewElement("startTimeStamp");
        pNewStartTimeStamp->SetText("pNewTimeStamp");
        pStartTimeStamp->InsertAfterChild(pRealtimeStore, pNewStartTimeStamp);

    }

/********************************************************************************************************************************************************************************
* Adds new mEventID to <event> -> <mEventID>
* 
* It takes in the first argument pass to the program. 
*
********************************************************************************************************************************************************************************/
    XMLElement *pmEventID = pRoot->FirstChildElement("mobileDevice")->FirstChildElement("event");
    XMLElement *pmEventIDStore = nullptr;
    XMLElement *pIter2 = pmEventID->FirstChildElement("mEventID");
    while (pIter2 != nullptr) {
        pmEventIDStore = pIter2;
        pIter2 = pIter2->NextSiblingElement("mEventID");
    }
    if (pmEventIDStore != nullptr) {
        XMLElement *pNewmEventID = doc.NewElement("mEventID");
        pNewmEventID->SetText(argv[1]);
        pmEventID->InsertAfterChild(pmEventIDStore, pNewmEventID);
    }

/********************************************************************************************************************************************************************************
* Adds new timeStamp to <event> -> <timeStamp>.
* 
* It takes in the third argument passed to the program.
*
********************************************************************************************************************************************************************************/
    XMLElement *pEvent = pRoot->FirstChildElement("mobileDevice")->FirstChildElement("event");// Gets the <event> element
    XMLElement *pPrecedent = nullptr;// This is to store the element after which will insert the new element <timeStamp>
    XMLElement *pIter = pEvent->FirstChildElement("mEventID");// Gets the first location immediately before where a <timeStamp> element should be placed
    while (pIter != nullptr) {// Loops through the children of <event> and finds the last <timeStamp> element
        pPrecedent = pIter;// Store pIter as the best known location for the new <timeStamp> element
        pIter = pIter->NextSiblingElement("timeStamp");// Attempt to find the next <timeStamp> element
    }
    if (pPrecedent != nullptr) {
        XMLElement *pNewTimeStamp = doc.NewElement("timeStamp");// Create a new <timeStamp> element
        pNewTimeStamp->SetText(argv[3]);
        pEvent->InsertAfterChild(pPrecedent, pNewTimeStamp);// Insert the new element into the document
    }

/********************************************************************************************************************************************************************************
* Adds new data to <event> -> <data>.
* 
* It takes in the second argument passed to the program.
*
********************************************************************************************************************************************************************************/
    XMLElement *pEventData = pRoot->FirstChildElement("mobileDevice")->FirstChildElement("event");
    XMLElement *pEventDataStore = nullptr;
    XMLElement *pIter1 = pEventData->FirstChildElement("timeStamp");
    while (pIter1 != nullptr) {
        pEventDataStore = pIter1;
        pIter1 = pIter1->NextSiblingElement("data");
    }

    if (pEventDataStore != nullptr) {
        XMLElement *pNewDataEvent = doc.NewElement("data");
        pNewDataEvent->SetText(argv[2]);
        pEventData->InsertAfterChild(pEventDataStore, pNewDataEvent);

    }






    doc.SaveFile("homeML.xml");
}

TestInput.cpp

#include <iostream>
int main()
{using namespace std;
    std::cout << "Hello World!" << " ";
    std:cout << "after space";
    return 0;
}
Colin747
  • 4,955
  • 18
  • 70
  • 118

2 Answers2

0

When you run a program in backticks, the shell captures its standard output and substitutes it on the command line. So, you're actually executing

./insertElement {... whatever the output of ./detectUpdateHomeML is ...}

and since the output was captured, it naturally doesn't display. Try running

OUTPUT=`./detectUpdateHomeML`
echo "output is: $OUTPUT"
./insertElement $OUTPUT

(or just set -x) to see what's actually going on.


Oh, and this appears to be just a shell question - the output itself would be more helpful than your C++ code here.

Useless
  • 64,155
  • 6
  • 88
  • 132
  • Which command? The output of `./detectUpdateHomeML` is being passed as an argument (or multiple arguments, as pointed out in the other answer, if there is whitespace in the output) to `./insertElement`. I don't know what either of those programs do, what the output looks like, what the input should look like, etc. I'm just telling you what you've done, and why the code snippet doesn't help me. – Useless Oct 16 '14 at 14:27
  • Sorry I thought you where asking me to provide the output of the shell from your last line in your answer. – Colin747 Oct 16 '14 at 14:28
0

I think the problem is that insertElement processes only its second argument, therefore you need to encapsulate ./detectUpdateHomeML into quotes:

./insertElement "" "`./detectUpdateHomeML`"

or even better:

./insertElement "" "$( ./detectUpdateHomeML )"
Géza Török
  • 1,397
  • 7
  • 15