gpt4 book ai didi

linux - 编写一个运行程序的 shell 脚本,模拟用户对程序的输入

转载 作者:太空宇宙 更新时间:2023-11-04 05:16:15 25 4
gpt4 key购买 nike

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

$prg start
$prg pause
$prg stop

我已经编写了一个打开此预测器管理器的 shell 脚本,但是我希望能够通过 shell 脚本输入启动命令。我怎样才能实现这个?我尝试过使用 echo 以及 yes 并将其管道化到程序中,但我不确定我做得是否正确。我怎样才能实现这种自动用户输入

/**  @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++ 代码,看起来您的 cout 上缺少一个“\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

关于linux - 编写一个运行程序的 shell 脚本,模拟用户对程序的输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49041402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com