这是我的问题。我有一个C ++脚本,它将字符串作为将用于提交消息的消息。
这适用于几乎所有情况,但是当**First Iteration**
1 - 2017-04-05
2 - 2017-04-05
3 - 2017-04-05
**Second Iteration**
1 - 2017-04-06
2 - 2017-04-06
3 - 2017-04-06
**Third Iteration**
1 - 2017-04-07
2 - 2017-04-07
3 - 2017-04-07
包含转义单引号或双引号时出现问题,因此命令如下所示:
<msg>
所以git会感到困惑。
我不想考虑如何在提交消息中转义这些引号,所以我认为最好的方法是避免使用git commit -m 'A new message \' with many escaped \" \' quotes \"'
标志,只是做一个简单的-m
并以某种方式将git commit
传递给vi或ed,然后退出并保存。
我尝试使用ed:
<msg>
VI :
git commit | ed << <msg>
正如你所看到的,我对Linux很陌生,而且我还没有在网上找到任何描述我想要做的事情。 所以问题又是:在没有调用git commit | vi << I << <msg> << :wq
标志的情况下,提交git特定消息的shell命令的正确顺序是什么。我在这里做错了什么?
答案 0 :(得分:3)
如果您刚刚运行Git,请不要生成shell;直接生成git
并将["git", "commit", "-m", message]
作为其argv传递。在C ++中:
#include <string>
extern "C" {
#include <sys/wait.h>
#include <unistd.h>
}
struct child_process {
FILE* file;
pid_t pid;
child_process(FILE* file_, pid_t pid_) :
file(file_),
pid(pid_) {}
};
template<std::size_t n> static child_process popenv(std::string const& path, std::string const (&args)[n]) {
char const* const c_path = path.c_str();
char const* c_argv[n + 2];
c_argv[0] = c_path;
c_argv[n + 1] = NULL;
std::size_t i = 1;
for (std::string const& arg : args) {
c_argv[i++] = arg.c_str();
}
int fds[2];
pipe(fds);
pid_t const pid = fork();
if (pid == -1) {
throw std::system_error(errno, std::system_category());
}
if (pid == 0) {
dup2(fds[1], 1);
execvp(c_path, const_cast<char* const*>(c_argv));
_exit(EXIT_FAILURE);
}
return child_process(fdopen(fds[0], "r"), pid);
}
static int pclosev(child_process const& process) {
int status;
fclose(process.file);
if (waitpid(process.pid, &status, 0) == -1) {
throw std::system_error(errno, std::system_category());
}
return status;
}
std::string const message = "A new message ' with many escaped \" ' quotes \"";
child_process p = popenv("git", {"commit", "-m", message});
// read from p.file; use pclosev() instead of pclose()
如果由于某种原因确实需要shell,请在其argv中传递消息并运行git commit -m "$1"
。
如果您确实需要git commit
出于某种原因从标准输入中读取其消息,请运行git commit -F -
。 (-
可以替换为任何文件来读取该文件。)