2016-05-07 32 views
2

我找到了一種不帶參數調用unix外部命令(例如「ls」,「pwd」)的方法。它是這樣說:使用參數調用Unix外部命令

//Child process 
char cwd[1024]; 
getcwd(cwd, sizeof(cwd)); 
char *argv[] = {*args, NULL}//(ex.) {"ls", NULL} 
char *env[] = {cwd, NULL}; 
//concat():method that connects 2 strings 
char *command_source = concat("/bin/", *args); 
execve(command_source, argv, env); 
return 0; 

我想這個代碼轉換,以接受如「ls -l」

+1

調臺的整個環境,只有當前目錄的名稱將會使一些程序不快取代它。這不是你怎麼做的 - 不管你想要做什麼。 –

+0

一個典型的命令在內存中看起來像這樣:'static char * cmd1 [] = {「awk」,「{print $ 1}」,0};'注意引號被剝離並終止0. –

回答

1

假設你知道args和參數的數量參數外部命令它的argcs

... 
char **argv = calloc(sizeof(char*), argcs+1); 
for (int i=0; i<argcs; i++) 
    argv[i]=args[i]; 
argv[argcs]=NULL; 
... 

如果沒有,你可以很容易地通過數組搜索的結局NULL迭代確定argcs

0

你也可以做一個管道;看看命令是如何建立起來的,看到的結構,他們以0結束陣列和報價被剝離:

/* who | awk '{print $1}' | sort | uniq -c | sort -n */ 
/*static char *cmd0[] = {"who", 0}; 
static char *cmd1[] = {"awk", "{print $1}", 0}; 
static char *cmd2[] = {"sort", 0}; 
static char *cmd3[] = {"uniq", "-c", 0}; 
static char *cmd4[] = {"sort", "-n", 0};*/ 

這裏有一些實用功能,當你創建帶有參數的管道。它們經過良好測試和無缺陷。

pipeline.c

#define _XOPEN_SOURCE 500 
/* One way to create a pipeline of N processes */ 

#ifndef STDERR_H_INCLUDED 
#define STDERR_H_INCLUDED 

static void err_sysexit(char const *fmt, ...); 

static void err_syswarn(char const *fmt, ...); 

#endif /* STDERR_H_INCLUDED */ 

/* pipeline.c */ 
#include <assert.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/wait.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include "openshell.h" 
#include <errno.h> 

/* exec_nth_command() and exec_pipe_command() are mutually recursive */ 
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output); 

/* With the standard output plumbing sorted, execute Nth command */ 
static void exec_nth_command(int ncmds, char ***cmds) { 
    assert(ncmds >= 1); 
    if (ncmds > 1) { 
     pid_t pid; 
     Pipe input; 
     if (pipe(input) != 0) 
      err_sysexit("Failed to create pipe"); 
     if ((pid = fork()) < 0) 
      err_sysexit("Failed to fork"); 
     if (pid == 0) { 
      /* Child */ 
      exec_pipe_command(ncmds - 1, cmds, input); 
     } 
     /* Fix standard input to read end of pipe */ 
     dup2(input[0], 0); 
     close(input[0]); 
     close(input[1]); 
    } 
    execvp(cmds[ncmds - 1][0], cmds[ncmds - 1]); 
    err_sysexit("Failed to exec %s", cmds[ncmds - 1][0]); 
    /*NOTREACHED*/ 
} 

/* Given pipe, plumb it to standard output, then execute Nth command */ 
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output) { 
    assert(ncmds >= 1); 
    /* Fix stdout to write end of pipe */ 
    dup2(output[1], 1); 
    close(output[0]); 
    close(output[1]); 
    exec_nth_command(ncmds, cmds); 
} 


/* who | awk '{print $1}' | sort | uniq -c | sort -n */ 
/*static char *cmd0[] = {"who", 0}; 
static char *cmd1[] = {"awk", "{print $1}", 0}; 
static char *cmd2[] = {"sort", 0}; 
static char *cmd3[] = {"uniq", "-c", 0}; 
static char *cmd4[] = {"sort", "-n", 0};*/ 

/*static char **cmds[] = {cmd0, cmd1, cmd2, cmd3, cmd4};*/ 
/*static int ncmds = sizeof(cmds)/sizeof(cmds[0]);*/ 

/* Execute the N commands in the pipeline */ 
void exec_pipeline(int ncmds, char ***cmds) { 
    assert(ncmds >= 1); 
    pid_t pid; 
    if ((pid = fork()) < 0) 
     err_syswarn("Failed to fork"); 
    if (pid != 0) 
     return; 
    exec_nth_command(ncmds, cmds); 
} 

#include <stdarg.h> 

static const char *arg0 = "<undefined>"; 

static void err_vsyswarn(char const *fmt, va_list args) { 
    int errnum = errno; 
    fprintf(stderr, "%s:%d: ", arg0, (int) getpid()); 
    vfprintf(stderr, fmt, args); 
    if (errnum != 0) 
     fprintf(stderr, " (%d: %s)", errnum, strerror(errnum)); 
    putc('\n', stderr); 
} 

static void err_syswarn(char const *fmt, ...) { 
    va_list args; 
    va_start(args, fmt); 
    err_vsyswarn(fmt, args); 
    va_end(args); 
} 

static void err_sysexit(char const *fmt, ...) { 
    va_list args; 
    va_start(args, fmt); 
    err_vsyswarn(fmt, args); 
    va_end(args); 
    exit(1); 
} 

代碼來自從那裏賞金被授予上面的代碼前面一個問題事先殼牌項目。已有詳細的答案 - How to fix these errors in my codeC minishell: adding pipelines也包含了大部分引用代碼。

您還可以閱讀pipe(2)pipe(7)Advanced Linux Programming

+3

這是很好的代碼 - 你從哪裏得到它的,你打算在信貸的到期時給予貸款?是否有任何理由,你不應該被拒絕投票[抄襲](https://stackoverflow.com/questions/13636252/c-minishell-adding-pipelines) –

+2

哪些網站?你應該把這些信譽歸功於那些 - 就像這些網站應該給SO一樣,因爲那是代碼被首先發布的地方。 –

+0

@JonathanLeffler我敢肯定,在這段代碼之前,我已經給了你一個獎勵,你在聊天網站幫了我,教會了我。 –