diff --git a/src/service_runner.cpp b/src/service_runner.cpp index f6d8573..88611ff 100644 --- a/src/service_runner.cpp +++ b/src/service_runner.cpp @@ -1,4 +1,3 @@ - #include #include #include @@ -55,7 +54,7 @@ bool service_runner::install(bool silent) { // Create service directory std::string remote_service_path = remotepath::service(mServer, mService); - if (!execute_command(mServerEnv.get_SSH_INFO(), sCommand({"mkdir", "-p", remote_service_path}), cMode::Silent)) + if (!execute_command(mServerEnv.get_SSH_INFO(), sCommand({"mkdir", "-p", quote(remote_service_path)}), cMode::Silent)) { std::cerr << "Failed to create service directory " << remote_service_path << std::endl; return false; @@ -71,8 +70,8 @@ bool service_runner::install(bool silent) { // Copy template files { std::cout << "Copying: [LOCAL] " << tinfo.local_template_path() << std::endl << std::string(8,' ')<<"[REMOTE] " << remotepath::service_template(mServer, mService) << "/" << std::endl; - std::vector rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", "ssh","-p", mServerEnv.get_SSH_PORT(), - tinfo.local_template_path().string()+"/", + std::vector rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", quote("ssh -p " + mServerEnv.get_SSH_PORT()), + quote(tinfo.local_template_path().string()+"/"), mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remotepath::service_template(mServer, mService)+"/") }; if (!execute_command(rsync_cmd, silent ? cMode::Silent : cMode::Defaults)) @@ -90,7 +89,7 @@ bool service_runner::install(bool silent) { return false; } std::cout << "Copying: [LOCAL] " << local_service_path << std::endl < rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", "ssh", "-p", mServerEnv.get_SSH_PORT(), + std::vector rsync_cmd = {"rsync", "--delete", "-zrpc", "-e", quote("ssh -p " + mServerEnv.get_SSH_PORT()), quote(local_service_path + "/"), mServerEnv.get_SSH_USER() + "@" + mServerEnv.get_SSH_HOST() + ":" + quote(remotepath::service_config(mServer,mService) + "/") }; diff --git a/src/utils/execute.cpp b/src/utils/execute.cpp index 0154269..3069269 100644 --- a/src/utils/execute.cpp +++ b/src/utils/execute.cpp @@ -98,32 +98,55 @@ bool execute_command(const sSSHInfo * ssh_info, const sCommand command, cMode mo { if (command.get_command_to_run().empty()) return false; - + std::vector commandvec; - - if (ssh_info) - { - std::vector ssh_command = {"/usr/bin/ssh", "-p", ssh_info->port, "-tt", ssh_info->user + "@" + ssh_info->host}; - commandvec.insert(commandvec.end(), ssh_command.begin(), ssh_command.end()); + + // Construct the shell command with proper environment variables and directory + std::string shell_command; + + // Add working directory if provided + if (!command.get_directory_to_run_in().empty()) { + shell_command += "cd " + quote(command.get_directory_to_run_in()) + " && "; } - - commandvec.push_back("bash"); - commandvec.push_back("-c"); - - std::string shell_command = ""; - for (auto & x : command.get_command_to_run()) { - shell_command += x + " "; + + // Add environment variables if provided + for (const auto& env_var : command.get_env_vars()) { + shell_command += env_var.first + "=" + quote(env_var.second) + " "; } - shell_command = shell_command.substr(0, shell_command.size() - 1); - commandvec.push_back(shell_command); - - + + // Add the command arguments properly joined + const auto& args = command.get_command_to_run(); + std::ostringstream cmd_stream; + for (size_t i = 0; i < args.size(); ++i) { + if (i > 0) cmd_stream << " "; + cmd_stream << args[i]; + } + shell_command += cmd_stream.str(); + + if (ssh_info) { + // Use bash -c for SSH to ensure proper command execution + commandvec = { + "/usr/bin/ssh", + "-p", ssh_info->port, + (hasFlag(mode, cMode::CaptureOutput) ? "" : "-tt"), + ssh_info->user + "@" + ssh_info->host, + "bash", "-c", halfquote(shell_command) + }; + } else { + // Local execution + commandvec = {"bash", "-c", halfquote(shell_command)}; + } + + // Remove any empty strings + commandvec.erase( + std::remove_if(commandvec.begin(), commandvec.end(), + [](const std::string& s) { return s.empty(); }), + commandvec.end()); + if (hasFlag(mode, cMode::CaptureOutput)) { ASSERT(output, "Capture output mode requires an output string to be provided"); return __execute_command(commandvec, output); - } - else - { + } else { return __execute_command(commandvec, nullptr); } }