编写一个运行程序的外壳脚本,该程序模拟用户输入到程序中



我正在尝试编写一个运行可执行C 程序的Shell脚本。该程序称为预测器管理器,打开时允许用户输入看起来:

$prg start
$prg pause 
$prg stop 

我编写了一个打开此预测器管理器的Shell脚本,但是我希望能够通过Shell脚本输入start命令。我该如何实施?我尝试使用Echo以及是的,并将其输送到程序中,但我不确定我是否正确地进行了操作。我如何实现此自动化用户输入

/**  @file      ProgManager.cpp     Prognostic Manager
*   @class     ProgManager         Prongostic Manager
*   @defgroup  GPIC++    Generic Prognostics Infrastructure-C++
*   @defgroup  Framework Prognostic Framework
*
*   @brief     Main class for C++ Generic Prognostic Infrastructure
*    This class creates the ProgMonitors and Communication Manager.
*
*   @author    Chris Teubert
*   @version   0.1.0
*
*   @pre       Prognostic Configuration File and Prognoster Configuration Files
*
*   @bug       Large delay for ending other threads
*
*      Contact: Chris Teubert (Christopher.a.teubert@nasa.gov)
*      Created: November 11, 2015
*
*   @copyright Copyright (c) 2013-2016 United States Government as represented by
*     the Administrator of the National Aeronautics and Space Administration.
*     All Rights Reserved.
*/
#include <exception>
#include <iostream>
#include <vector>
#include <algorithm>  // For tolower
#include <string>
#include "SharedLib.h"  // for trim
#include "ProgManager.h"
#include "PrognoserFactory.h"
#include "CommManager.h"
namespace PCOE {
    /// CONFIGURABLE PARAMETERS
    const std::string PACKAGE_NAME = "C++ Generic Prognostic Infrastructure";
    const std::string VERSION = "0.1.0";
    const std::string NOTE = "If you have technical issues with the plugin, "
        "please report them by nemailing Christopher Teubert (christopher.a.teubert@nasa.gov).";
    const std::string MODULE_NAME = "PrognosticManager";
Cmd::Cmd() : command(NONE) {}
class CommonPrognoser;
class CommonCommunicator;
static Log &logger = Log::Instance();
ProgManager::ProgManager() : configValues(), configSet(false) { }
ProgManager::ProgManager(const std::string& path) :
    ProgManager(GSAPConfigMap(path)) { }
ProgManager::ProgManager(const GSAPConfigMap& config)
    : configValues(config), configSet(true) { }
void ProgManager::setConfig(const std::string& path) {
    setConfig(GSAPConfigMap(path));
}
void ProgManager::setConfig(const GSAPConfigMap& config) {
    configValues = config;
    configSet = true;
}
void ProgManager::run() {
    /// Setup Log
    logger.Initialize(PACKAGE_NAME, VERSION, NOTE);
    logger.WriteLine(LOG_INFO, MODULE_NAME, "Enabling");
    CommManager &theComm = CommManager::instance();
    if (!configSet) {
        logger.WriteLine(LOG_DEBUG, MODULE_NAME, "No configuration file set - closing progManager");
        return;
    }
    /// SETUP PROGNOSERS
    logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Setting Up Prognosers");
    std::vector<std::unique_ptr<CommonPrognoser> > prognosers;
    if (configValues.includes("Prognosers")) {
        PrognoserFactory &factory = PrognoserFactory::instance();
        for (auto & itStrs : configValues.at("Prognosers")) {
            prognosers.push_back(factory.Create(itStrs));
            // @todo(CT): Add check that component was made correctly
        }
    }
    /// Setup COMMUNICATION
    // Note: This must be done after the prognosers
    theComm.configure(configValues);
    theComm.start();
    /// Setup Main Loop
    unsigned int counter = 0;
    Cmd ctrl;
    logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Enabled");
    /// Main Loop- Handle controls for prognosers
    while (ctrl.command != STOP) {
        counter++;
        /// Handle Commands
        ctrl = control();
        if (ctrl.command == STOP) {
            logger.WriteLine(LOG_INFO, MODULE_NAME, "Stopping");
            /// STOP PROGNOSERS
            for (auto & prognoser : prognosers) {
                prognoser->stop();
            }
            break;
        }
        else if (ctrl.command == START || ctrl.command == RESUME) {
            logger.WriteLine(LOG_INFO, MODULE_NAME, "Starting");
            /// START PROGNOSERS
            for (auto & prognoser : prognosers) {
                prognoser->start();
            }
            logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Started");
        }
        else if (ctrl.command == PAUSE) {
            logger.WriteLine(LOG_INFO, MODULE_NAME, "Pausing");
            /// PAUSE PROGNOSERS
            for (auto & prognoser : prognosers) {
                prognoser->pause();
            }
            logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Paused");
        }
    }  // End while (command != stop)
    logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Cleanup");
    /// CLEANUP ACTIVITIES
    // End each Prognoser
    for (auto & prognoser : prognosers) {
        logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Waiting for Prognoser thread to stop");
        prognoser->join();// Wait for thread to end
    }
    // Stop Communication Manager
    // NOTE: This has to be done after the other threads that used it are stopped
    theComm.stop();
    logger.WriteLine(LOG_DEBUG, MODULE_NAME, "Waiting for Comm thread to stop");
    theComm.join();
    // Stop Log, exit thread
    logger.WriteLine(LOG_INFO, MODULE_NAME, "Stopped");
    logger.Close();
}
Cmd ProgManager::control() {
    logger.WriteLine(LOG_TRACE, MODULE_NAME, "Waiting for Control Command");
    std::string input;
    Cmd c;
    std::cout << "prg $ ";
    std::cin >> input;  // Receive input
    logger.FormatLine(LOG_TRACE, MODULE_NAME, "Control Command received- %s", input.c_str());
    trim(input);
    if (input.length() == 0) {
        c.command = NONE;
        return c;
    }
    const auto marker = input.find_first_of(" t");
    std::string command = (input.substr(0, marker));
    std::transform(command.begin(), command.end(), command.begin(), ::tolower);
    // Fill out Command Structure
    if (command.compare("start") == 0) {
        c.command = START;
        logger.WriteLine(LOG_TRACE, MODULE_NAME, "Start command received");
    }
    else if (command.compare("pause") == 0) {
        c.command = PAUSE;
        logger.WriteLine(LOG_TRACE, MODULE_NAME, "Pause command received");
    }
    else if (command.compare("resume") == 0) {
        c.command = RESUME;
        logger.WriteLine(LOG_TRACE, MODULE_NAME, "Resume command received");
    }
    else if (command.compare("stop") == 0) {
        c.command = STOP;
        logger.WriteLine(LOG_TRACE, MODULE_NAME, "Stop command received");
    }
    else {
        c.command = NONE;
        logger.FormatLine(LOG_WARN, MODULE_NAME, "Command not recognized: %s", command.c_str());
    }
    return c;
}
}

一个选项是,您可以将输入值放在文件中,然后将其重定向到您的程序:

cat InputFileName | YourProgramName

YourProgramName < InputFileName

更新:查看您的C 代码,看起来您在代表上缺少" n"(实际上它将在没有" n"的情况下工作 - 只有在没有" n"的输入后才看到提示符(。

以下代码有效:

#include <iostream>
int main(int argc, const char * argv[]) {
        std::string input;
    while (input != "exit") {
        std::cout << "prg $ n";
        std::cin >> input;  // Receive input
        std::cout << "Entered => " + input + "n";
    }
    return 0;
}

使用输入文件myinput.txt:

1
Start
End
exit

这是我运行的方式:

$ ./Test_CPP < myInput.txt
prg $ Entered => 1
prg $ Entered => Start
prg $ Entered => End
prg $ Entered => exit

或者:

$ cat myInput.txt | ./Test_CPP
prg $ Entered => 1
prg $ Entered => Start
prg $ Entered => End
prg $ Entered => exit

相关内容

  • 没有找到相关文章

最新更新