如何使用特定分隔符从 argv 执行多个命令
How to execute multiple commands from argv with an specific delimiter
最近我有一个任务,我必须编写一个程序,从命令行获取两个不同的命令,用“+”分隔,例如:
ps -lu myUsername + ls -la
程序的 objective 是通过使用 fork()
和 exec()
同时 运行 任意两个订单,每个订单有任意数量的参数。这是我对这个问题的解决方案:
注意:原来的问题是 运行 在装有 Solaris 5.10 和 c89 或 c99 标准 (gcc 3.4.3) 的机器上
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
int main (int argc, char* argv[]) {
char delimiter = '+';
char* auxp; //auxiliar pointer
int i = 1;
int position;
while(i < argc){
if (strcmp("+", argv[i]) == 0) {
argv[i] = NULL;
position = i;
}
i++;
}
if (fork() == 0) {
execvp(argv[1], &argv[1]);
exit(1);
}
if (fork() == 0) {
execvp(argv[position+1], &argv[position+1]);
exit(1);
}
wait(NULL);
wait(NULL);
exit(0);
}
这对于作业来说已经足够了,但我想让它使用 N 个参数 而不是只有 2 个。我无法找到一个系统的方法来找到所有地址.感谢任何帮助,感谢建议。
只需将分叉移动到循环中:
int main (int argc, char* argv[])
{
char** start = ++argv;
unsigned int n = 0;
for(; *argv; ++argv) // profiting from argv being null terminated, too...
{
if (strcmp("+", *argv) == 0)
{
*argv = NULL;
if (fork() == 0)
{
execvp(*start, start);
exit(1);
}
start = argv + 1;
++n; // but need to count how many times we actually forked!
}
}
while(n--)
{
wait(NULL);
}
exit(0);
}
好的,我也对迭代进行了一些修改 - 指针更好(个人意见...)。
注意:这是未经测试的代码,如果您发现错误请自行修复...
对于 N 个命令的一般情况,需要跟踪每个命令的开始和结束位置,并在找到命令结尾时派生一个新的 child。这可能在 +
分隔符参数处,或者在原始参数列表的末尾。
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
/*
* Note: argc could be in range 0 to INT_MAX.
* Using unsigned int values to avoid arithmetic overflow.
*/
unsigned int start = 1;
unsigned int end = 1;
unsigned int child_count = 0;
/* Note: argv[argc] is a terminating null pointer. */
while(end <= (unsigned int)argc){
if(end == (unsigned int)argc || strcmp("+", argv[end]) == 0){
/* Reached the terminating null pointer or a command separator. */
argv[end] = NULL;
if(start != end){
/*
* Command is not empty.
* Fork a child process to execute the command.
*/
pid_t child = fork();
if(child > 0){
/* Parent forked child successfully. */
child_count++;
}else if(child == 0){
/* This is the child process. Execute command. */
execvp(argv[start], &argv[start]);
exit(1);
}
}
/* Next command starts after this one. */
start = end + 1;
}
/* Looking for terminating null pointer or command separator. */
end++;
}
/* Wait for the child processes to terminate. */
while(child_count){
wait(NULL);
child_count--;
}
exit(0);
}
注意:argv[end] = NULL;
行可以移动到 if(child == 0){
}
块中(但在调用 execvp
之前)以离开 parent的原始参数列表完好无损。
最近我有一个任务,我必须编写一个程序,从命令行获取两个不同的命令,用“+”分隔,例如:
ps -lu myUsername + ls -la
程序的 objective 是通过使用 fork()
和 exec()
同时 运行 任意两个订单,每个订单有任意数量的参数。这是我对这个问题的解决方案:
注意:原来的问题是 运行 在装有 Solaris 5.10 和 c89 或 c99 标准 (gcc 3.4.3) 的机器上
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <strings.h>
int main (int argc, char* argv[]) {
char delimiter = '+';
char* auxp; //auxiliar pointer
int i = 1;
int position;
while(i < argc){
if (strcmp("+", argv[i]) == 0) {
argv[i] = NULL;
position = i;
}
i++;
}
if (fork() == 0) {
execvp(argv[1], &argv[1]);
exit(1);
}
if (fork() == 0) {
execvp(argv[position+1], &argv[position+1]);
exit(1);
}
wait(NULL);
wait(NULL);
exit(0);
}
这对于作业来说已经足够了,但我想让它使用 N 个参数 而不是只有 2 个。我无法找到一个系统的方法来找到所有地址.感谢任何帮助,感谢建议。
只需将分叉移动到循环中:
int main (int argc, char* argv[])
{
char** start = ++argv;
unsigned int n = 0;
for(; *argv; ++argv) // profiting from argv being null terminated, too...
{
if (strcmp("+", *argv) == 0)
{
*argv = NULL;
if (fork() == 0)
{
execvp(*start, start);
exit(1);
}
start = argv + 1;
++n; // but need to count how many times we actually forked!
}
}
while(n--)
{
wait(NULL);
}
exit(0);
}
好的,我也对迭代进行了一些修改 - 指针更好(个人意见...)。
注意:这是未经测试的代码,如果您发现错误请自行修复...
对于 N 个命令的一般情况,需要跟踪每个命令的开始和结束位置,并在找到命令结尾时派生一个新的 child。这可能在 +
分隔符参数处,或者在原始参数列表的末尾。
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char* argv[]) {
/*
* Note: argc could be in range 0 to INT_MAX.
* Using unsigned int values to avoid arithmetic overflow.
*/
unsigned int start = 1;
unsigned int end = 1;
unsigned int child_count = 0;
/* Note: argv[argc] is a terminating null pointer. */
while(end <= (unsigned int)argc){
if(end == (unsigned int)argc || strcmp("+", argv[end]) == 0){
/* Reached the terminating null pointer or a command separator. */
argv[end] = NULL;
if(start != end){
/*
* Command is not empty.
* Fork a child process to execute the command.
*/
pid_t child = fork();
if(child > 0){
/* Parent forked child successfully. */
child_count++;
}else if(child == 0){
/* This is the child process. Execute command. */
execvp(argv[start], &argv[start]);
exit(1);
}
}
/* Next command starts after this one. */
start = end + 1;
}
/* Looking for terminating null pointer or command separator. */
end++;
}
/* Wait for the child processes to terminate. */
while(child_count){
wait(NULL);
child_count--;
}
exit(0);
}
注意:argv[end] = NULL;
行可以移动到 if(child == 0){
}
块中(但在调用 execvp
之前)以离开 parent的原始参数列表完好无损。