0

I am trying to implement a program that takes in a process followed by a string consisting of pipeline commands. How do I separate the string of commands, into {individual command/any number of arguments arrays} The "|" is the character that separates the different commands.

For instance, if I put: pipe ls -lt | cat Lebowski | cd .. .

How would i get the system to recognize that there are three separate command line arguments here to be represented in different pipes.

1
  • have a look at strtok Commented Mar 18, 2013 at 21:04

4 Answers 4

2

First of all since pipe is a special symbol you need to escape it when passing to a program:

pipe ls -lt \| cat Lebowski \| cd .. .

in your main function:

main(int argc, char *argv[]) {

the argv contains all these arguments (ls, -lt, |, cat...) at different indices. For example, argv[0] is ls, argv[2] is '|'. argc is the total number of such arguments.

Sign up to request clarification or add additional context in comments.

2 Comments

the first line of your response outlines what I need to have happen. I have to parse arguments WITHOUT the "\" separating the arguments
so you are implementing a shell and reading input with scanf or similar? in that case H2CO3's answer is the one
1

perreal's answer is very good if you want to do this yourself. There is a function getopt() which you can use for this purpose as well and is documented here getopt()

Comments

1

The strtok_r() function is your friend:

char **explode(char *s, const char *sep, size_t *outsz)
{
    size_t allocsz = 4;
    size_t sz = 0;
    char **arr = malloc(allocsz * sizeof(*arr));
    if (arr == NULL) {
        *outsz = 0;
        return NULL;
    }

    char *p, *end;
    for (p = srtok_r(s, sep, &end); p; p = strtok_r(NULL, sep, &end)) {
        if (++sz > allocsz) {
            allocsz <<= 1;
            arr = realloc(arr, sizeof(*arr) * allocsz));
            assert(arr != NULL); // sorry
        }
        arr[sz - 1] = strdup(p);
    }

    *outsz = sz;
    return arr;
}

Usage:

int main()
{
    char sentence[] = "The quick brown fox jumped over the lazy dog.";
    size_t sz;
    char **arr = explode(sentence, " ", &sz);
    int i;
    for (i = 0; i < sz; i++) {
        printf("%s\n", arr[i]);
        free(arr[i]);
    }
    free(arr);
    return 0;
}

Comments

0

Since | is a special character to most common shells, you need to quote them (as others have stated). If you quote all the arguments inside of double-quotes such as

pipe "ls -lt | cat Lebowski | cd .. "

You can parse argv[1] with strtok_r().

3 Comments

I hate to make comments about safety and such, but please please don't suggest using strtok(). strtok_r() is the safe (specifically, reentrant) variant.
@H2CO3 Thanks for the suggestion. It's been a long time since I've done pure C programming.
@H2CO3 Fixed after your suggestion ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.