I have a python script script.py
which takes command line params
我有一个python脚本script.py,它接受命令行参数
I want to make a wrapper in C so I can call the script.py
using ./script args
我想在C中创建一个包装器,所以我可以使用./script args调用script.py
So far I have this in my script.c
file
到目前为止,我在我的script.c文件中有这个
#include<stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
system("python3.4 script.py");
return 0;
}
How do I modify the script so I can do ./script arg1 arg2
and the C code executes system("python3.4 script.py arg1 arg2");
如何修改脚本以便我可以执行./script arg1 arg2和C代码执行系统(“python3.4 script.py arg1 arg2”);
I don't have experience in C. Above code is from googling
我没有C的经验。以上代码来自谷歌搜索
2 个解决方案
#1
2
Using system()
is needlessly complicated in this case, as it effectively passes the given command string to (forked) sh -c <command>
. This means that you'd have to handle possible quoting of arguments etc. when forming the command string:
在这种情况下使用system()是不必要的复杂,因为它有效地将给定的命令字符串传递给(forked)sh -c
% sh -c 'ls asdf asdf'
ls: cannot access 'asdf': No such file or directory
ls: cannot access 'asdf': No such file or directory
% sh -c 'ls "asdf asdf"'
ls: cannot access 'asdf asdf': No such file or directory
Note the difference between the unquoted and quoted versions.
请注意未引用和引用版本之间的区别。
I'd suggest using execve()
, if executing the python command is the only purpose of your C program, as the exec family of functions do not return on success. It takes an array of const pointers to char as the new argv, which makes handling arguments easier:
我建议使用execve(),如果执行python命令是C程序的唯一目的,因为exec系列函数不会成功返回。它将char指针的一个const指针作为新的argv,这使得处理参数更容易:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PYTHON "/usr/bin/python3"
#define SCRIPT "script.py"
int
main(int argc, char *argv[])
{
/* Reserve enough space for "python3", "script.py", argv[1..] copies
* and a terminating NULL, 1 + 1 + (argc - 1) + 1 */
int newargvsize = argc + 2;
/* VLA could be used here as well. */
char **newargv = malloc(newargvsize * sizeof(*newargv));
char *newenv[] = { NULL };
newargv[0] = PYTHON;
newargv[1] = SCRIPT;
/* execve requires a NULL terminated argv */
newargv[newargvsize - 1] = NULL;
/* Copy over argv[1..] */
memcpy(&newargv[2], &argv[1], (argc - 1) * sizeof(*newargv));
/* execve does not return on success */
execve(PYTHON, newargv, newenv);
perror("execve");
exit(EXIT_FAILURE);
}
As pointed out by others, you should use the official APIs for this, if at all possible.
正如其他人所指出的,如果可能的话,你应该使用官方API。
#2
0
You can generate your command as a string. You just need to loop through argv[] to append each parameters given to the C program at then end of your command string. Then you can use your command string as the argument for the system() function.
您可以将字符串生成为命令。您只需要循环遍历argv []以在命令字符串的末尾追加给予C程序的每个参数。然后,您可以使用命令字符串作为system()函数的参数。
#1
2
Using system()
is needlessly complicated in this case, as it effectively passes the given command string to (forked) sh -c <command>
. This means that you'd have to handle possible quoting of arguments etc. when forming the command string:
在这种情况下使用system()是不必要的复杂,因为它有效地将给定的命令字符串传递给(forked)sh -c
% sh -c 'ls asdf asdf'
ls: cannot access 'asdf': No such file or directory
ls: cannot access 'asdf': No such file or directory
% sh -c 'ls "asdf asdf"'
ls: cannot access 'asdf asdf': No such file or directory
Note the difference between the unquoted and quoted versions.
请注意未引用和引用版本之间的区别。
I'd suggest using execve()
, if executing the python command is the only purpose of your C program, as the exec family of functions do not return on success. It takes an array of const pointers to char as the new argv, which makes handling arguments easier:
我建议使用execve(),如果执行python命令是C程序的唯一目的,因为exec系列函数不会成功返回。它将char指针的一个const指针作为新的argv,这使得处理参数更容易:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define PYTHON "/usr/bin/python3"
#define SCRIPT "script.py"
int
main(int argc, char *argv[])
{
/* Reserve enough space for "python3", "script.py", argv[1..] copies
* and a terminating NULL, 1 + 1 + (argc - 1) + 1 */
int newargvsize = argc + 2;
/* VLA could be used here as well. */
char **newargv = malloc(newargvsize * sizeof(*newargv));
char *newenv[] = { NULL };
newargv[0] = PYTHON;
newargv[1] = SCRIPT;
/* execve requires a NULL terminated argv */
newargv[newargvsize - 1] = NULL;
/* Copy over argv[1..] */
memcpy(&newargv[2], &argv[1], (argc - 1) * sizeof(*newargv));
/* execve does not return on success */
execve(PYTHON, newargv, newenv);
perror("execve");
exit(EXIT_FAILURE);
}
As pointed out by others, you should use the official APIs for this, if at all possible.
正如其他人所指出的,如果可能的话,你应该使用官方API。
#2
0
You can generate your command as a string. You just need to loop through argv[] to append each parameters given to the C program at then end of your command string. Then you can use your command string as the argument for the system() function.
您可以将字符串生成为命令。您只需要循环遍历argv []以在命令字符串的末尾追加给予C程序的每个参数。然后,您可以使用命令字符串作为system()函数的参数。