I had the similar problem with boost process arguments and I followed below approach. Please go through below code snippet and let me know if it's not clear. IIRC, we have to pass the whole command as a single inline command rather passing arguments as separate argument. string cmd; string args; // Split command and it's arguments as two different things u_split_command_arguments( get_command(), cmd, args ); // Find the command's complete executable path. auto complete_command = boost_process::search_path( cmd ); if ( complete_command.empty() ) return error( error_command_notfound, ERR_COMMAND_NOTFOUND, HINT_COMMAND_NOTFOUND, job_id_type( job_id ) ); // XXX // boost::child constructor accepts the command, // arguments as a // separate list. For example, if we configured the job command as psql -c // "COPY table_name // TO STDOUT", then the whole command would be `/usr/local/bin/psql` and it's // argument values like // `-c "COPY table_name TO STDOUT"`. // // If we pass both values individually to the boost::child constructor, we are // getting the // FATAL error as `database " -c " COPY source TO STDOUT WITH CSV"" does not // exist`, which // seems boost is considering to pass these arguments as actual program // argument, than the // command flag arguments. Hence, merging the both command and it's arguments // as single // object, and then passing the whole command at once. cmd = complete_command.generic_string() + " " + args; m_process_group_ = new boost_process::group{}; boost_process::child child_process{}; // without environment variables if ( !m_environment_.size() ) child_process = boost_process::child{cmd, *m_process_group_, boost_process::std_out > cstdout, boost_process::std_err > cstderr}; void u_split_command_arguments( const string &cmd, string &split_cmd, string &args ) { auto pos{0}; for ( auto &x : cmd ) { if ( x == ' ' ) break; split_cmd += x; pos++; } args = cmd.substr( pos ); } On Tue, Oct 15, 2019 at 7:27 PM name name via Boost-users < boost-users@lists.boost.org> wrote:
Hi,
Im use boost::process::child to create a mysql cli child process to import sql file.
Normally im use this command:
/usr/bin/mysql mysql -h127.0.0.1 -utestuser --password='!@#QWE123qwe' -P3306 --default-character-set=utf8mb4 --max-allowed-packet=1GB < /root/create_db.sql
It’s worked well in bash.
But when use boost::process::child, std_err report ERROR 1045 (28000): Access denied for user 'testuser'@'localhost' (using password: YES).
Is there any bugs in my code?
Os: ubuntu 18.04 LTS
Boost: 1.71.0
MySql:5.7.27
Create_db.sql:
DROP DATABASE IF EXISTS test_db;
CREATE DATABASE test_db;
Thanks
[code]
#include <iostream>
#include
#include
#include
#include
using namespace boost::process;
using namespace boost::iostreams;
using namespace boost::asio;
std::string SearchExecutableInPath(std::string const& filename) {
try {
return search_path(filename).generic_string();
}
catch (...) {
return "";
}
}
int RunProcess(
std::string const& executable,
std::vectorstd::string const& args,
std::string input_file_path
) {
io_context ioCtx;
auto work = make_work_guard(ioCtx);
std::thread ioThread([&ioCtx] {
ioCtx.run();
});
std::futurestd::string dataOut, dataErr;
child c;
if (!input_file_path.empty()) {
c = child(
boost::filesystem::absolute(executable),
boost::process::args(args),
std_out > dataOut,
std_err > dataErr,
std_in < boost::filesystem::absolute(input_file_path),
ioCtx
);
}
else {
c = child(
boost::filesystem::absolute(executable),
boost::process::args(args),
std_out > dataOut,
std_err > dataErr,
std_in.close(),
ioCtx
);
}
c.wait();
int result = c.exit_code();
std::string output = dataOut.get();
std::string error = dataErr.get();
if (!output.empty()) {
std::cout << output << std::endl;
}
if (!error.empty()) {
std::cout << error << std::endl;
}
work.reset();
ioThread.join();
return result;
}
int main()
{
// /usr/bin/mysql mysql -h127.0.0.1 -utestuser --password='!@#QWE123qwe' -P3306 --default-character-set=utf8mb4 --max-allowed-packet=1GB < /root/create_db.sql
std::vectorstd::string args;
args.reserve(8);
// mysql cli
args.push_back("mysql");
// connection info
args.push_back("-h127.0.0.1");
args.push_back("-utestuser");
args.push_back("--password='!@#QWE123qwe'");
args.push_back("-P3306");
// encoding
args.push_back("--default-character-set=utf8mb4");
// maybe large sql file
args.push_back("--max-allowed-packet=1GB");
int const ret = RunProcess(
SearchExecutableInPath("mysql"),
args,
"/root/create_db.sql");
std::cout << "ret code: " << ret << std::endl;
return 0;
}
[/code] _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org https://lists.boost.org/mailman/listinfo.cgi/boost-users
-- Regards, Dinesh manojadinesh.blogspot.com