Help needed with boost::process::child and mysql cli

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 <boost/algorithm/string/join.hpp> #include <boost/iostreams/copy.hpp> #include <boost/asio/io_context.hpp> #include <boost/process.hpp> 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::vector<std::string> const& args, std::string input_file_path ) { io_context ioCtx; auto work = make_work_guard(ioCtx); std::thread ioThread([&ioCtx] { ioCtx.run(); }); std::future<std::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::vector<std::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]

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 <boost/algorithm/string/join.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/process.hpp>
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::vector<std::string> const& args,
std::string input_file_path
) {
io_context ioCtx;
auto work = make_work_guard(ioCtx);
std::thread ioThread([&ioCtx] {
ioCtx.run();
});
std::future<std::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::vector<std::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
participants (2)
-
dinesh kumar
-
name name