diff --git a/packages/sbatch-tui/include/sbatch-tui.hpp b/packages/sbatch-tui/include/sbatch-tui.hpp index 9c0643b2..25232c9f 100644 --- a/packages/sbatch-tui/include/sbatch-tui.hpp +++ b/packages/sbatch-tui/include/sbatch-tui.hpp @@ -17,7 +17,7 @@ namespace sbatch public: virtual void try_load_state(YAML::Node node) noexcept = 0; public: virtual YAML::Node save_state() const = 0; public: virtual ftxui::Component get_interface() = 0; - public: virtual std::string get_submit_command(std::string extra_sbatch_parameter) const = 0; + public: virtual std::vector get_submit_command(std::string extra_sbatch_parameter) const = 0; public: virtual ~Program() = default; // 用于注册程序 @@ -80,8 +80,8 @@ namespace sbatch { return str | ranges::views::transform([](char c) { - // only the following characters need to be escaped: $ ` \ " newline * @ - if (std::set{'$','`','\\','\"','\n','*','@'}.contains(c)) + // only the following characters need to be escaped: $ ` \ " newline * @ space tab + if (std::set{'$', '`', '\\', '\"', '\n', '*', '@', ' ', '\t'}.contains(c)) return '\\' + std::string(1, c); else return std::string(1, c); }) | ranges::views::join("") | ranges::to; diff --git a/packages/sbatch-tui/src/main.cpp b/packages/sbatch-tui/src/main.cpp index 651cf7c3..8ddd32fb 100644 --- a/packages/sbatch-tui/src/main.cpp +++ b/packages/sbatch-tui/src/main.cpp @@ -8,6 +8,7 @@ int main() { using namespace biu::literals; using namespace sbatch; + biu::Logger::Guard log; // 初始化 enum class UserCommandType { Continue, Back, Quit }; @@ -121,9 +122,11 @@ int main() else if (State.UserCommand == UserCommandType::Continue) { State.CurrentInterface = InterfaceType::Confirm; - State.SubmitCommand = Programs[State.ProgramSelected]->get_submit_command( - "--job-name=\"{}\" --output=\"{}\"{}"_f - (escape(State.JobName), escape(State.OutputFile), State.LowPriority ? " --nice=10000" : "")); + State.SubmitCommand = + Programs[State.ProgramSelected]->get_submit_command( + "--job-name={} --output={}{}"_f + (escape(State.JobName), escape(State.OutputFile), State.LowPriority ? " --nice=10000" : "")) + | biu::toLvalue | ranges::views::join(" \\\n ") | ranges::to; } else if (!State.UserCommand) return EXIT_FAILURE; else std::unreachable(); @@ -148,9 +151,10 @@ int main() } catch (...) {} // 提交任务 - boost::replace_all(State.SubmitCommand, "\n", " "); - biu::exec<{.SearchPath = true}> - ({"sh", { "-c", State.SubmitCommand }}); + log.debug("submit command: {}"_f(State.SubmitCommand)); + // -c 对 \\n 的处理与通常情况下不同,我们需要用 -s 然后将命令通过标准输入传入 + biu::exec<{.SearchPath = true, .Stdin = biu::IoType::String}> + ({.Program = "sh", .Args = { "-s"}, .Stdin = State.SubmitCommand}); break; } else if (!State.UserCommand) return EXIT_FAILURE; diff --git a/packages/sbatch-tui/src/mumax3.cpp b/packages/sbatch-tui/src/mumax3.cpp index 0670efef..48a91987 100644 --- a/packages/sbatch-tui/src/mumax3.cpp +++ b/packages/sbatch-tui/src/mumax3.cpp @@ -91,7 +91,7 @@ namespace sbatch | with_title("Misc:") }); } - public: virtual std::string get_submit_command(std::string extra_sbatch_parameter) const override + public: virtual std::vector get_submit_command(std::string extra_sbatch_parameter) const override { auto cpu_string = [&] { return State_.Nomultithread ? "--hint=nomultithread" : ""; }(); @@ -109,14 +109,14 @@ namespace sbatch else if (State_.MemorySchemeSelected == 2) return "--mem={}G"_f(State_.Memory); else std::unreachable(); }(); - return std::vector + return { "sbatch"s, "--partition={}"_f(State_.QueueEntries[State_.QueueSelected]), gpu_string, cpu_string, mem_string, - "--wrap=\"mumax3 \\\"{}\\\"\""_f(escape(escape(State_.InputFile))), + "--wrap=\"mumax3 {}\""_f(escape(escape(State_.InputFile))), extra_sbatch_parameter - } | biu::toLvalue | ranges::views::join(" \\\n") | ranges::to; + }; } }; template void Program::register_child_(); diff --git a/packages/sbatch-tui/src/vasp_cpu.cpp b/packages/sbatch-tui/src/vasp_cpu.cpp index 791bb203..aac90e57 100644 --- a/packages/sbatch-tui/src/vasp_cpu.cpp +++ b/packages/sbatch-tui/src/vasp_cpu.cpp @@ -104,7 +104,7 @@ namespace sbatch }) | with_title("Misc:") }); } - public: virtual std::string get_submit_command(std::string extra_sbatch_parameter) const override + public: virtual std::vector get_submit_command(std::string extra_sbatch_parameter) const override { auto optcell_string = [&] { @@ -134,18 +134,18 @@ namespace sbatch auto srun_string = [&] { if (State_.CpuSchemeSelected == 0 && recommended.Cpus) - return "--ntasks={} --cpus-per-task={}"_f(recommended.Mpi, recommended.Openmp); + return " --ntasks={} --cpus-per-task={}"_f(recommended.Mpi, recommended.Openmp); else return ""s; }(); - return std::vector + return { optcell_string, "sbatch"s, "--partition={} --nodes=1-1"_f(State_.QueueEntries[State_.QueueSelected]), cpu_string, mem_string, - "--wrap=\"srun {} vasp-intel vasp-{}\""_f(srun_string, State_.VaspEntries[State_.VaspSelected]), + "--wrap=\"srun{} vasp-intel vasp-{}\""_f(srun_string, State_.VaspEntries[State_.VaspSelected]), extra_sbatch_parameter - } | biu::toLvalue | ranges::views::join(" \\\n") | ranges::to; + }; } }; template void Program::register_child_(); diff --git a/packages/sbatch-tui/src/vasp_gpu.cpp b/packages/sbatch-tui/src/vasp_gpu.cpp index 3d8a9345..3504aa19 100644 --- a/packages/sbatch-tui/src/vasp_gpu.cpp +++ b/packages/sbatch-tui/src/vasp_gpu.cpp @@ -123,7 +123,7 @@ namespace sbatch }) | with_title("Misc:") }); } - public: virtual std::string get_submit_command(std::string extra_sbatch_parameter) const override + public: virtual std::vector get_submit_command(std::string extra_sbatch_parameter) const override { auto optcell_string = [&] { @@ -154,7 +154,7 @@ namespace sbatch else if (State_.MemorySchemeSelected == 2) return "--mem={}G"_f(State_.Memory); else std::unreachable(); }(); - return std::vector + return { optcell_string, "sbatch"s, @@ -162,7 +162,7 @@ namespace sbatch gpu_string, cpu_string, mem_string, "--wrap=\"srun vasp-nvidia vasp-{}\""_f(State_.VaspEntries[State_.VaspSelected]), extra_sbatch_parameter - } | biu::toLvalue | ranges::views::join(" \\\n") | ranges::to; + }; } }; template void Program::register_child_();