Can't understand why this causes an error

438 views Asked by At

I have a large directory of music which is listed in a file called op. I have been able to build a command which will randomly pick a song from the op file using some creative math with the nanosecond output from the date command. It works fine from the command line:

sed -n $((10#$(date +%N)%$(wc -l /shared/southpark/music/op|cut -d ' ' -f 1)))p /shared/southpark/music/op

I want to include this command in a c program and read the line in with popen.

#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
        char command[201];
        char buf[501];
        FILE *fp;

        strcpy(command, "sed -n $((10#$(date +%N)%$(wc -l /shared/southpark/music/op|cut -d ' ' -f 1)))p /shared/southpark/music/op");

        if((fp = popen(command, "r")) == NULL)
        {
                fprintf(stderr, "music_player: popen failed\n");
                return(1);
        }

        if(fgets(buf, sizeof(buf), fp) == NULL)
        {
                fprintf(stderr, "music_player: fgets failed\n");
                return(1);
        }

        printf("%s\n", buf);
        pclose(fp);
        return(0);
}

But when I run it, I get the following error:

sh: 1: arithmetic expression: expecting EOF: "10#271445839%2278"
music_player: fgets failed

How can I do this? I'm not understanding the error message.

2

There are 2 answers

0
Deanie On BEST ANSWER

After trying and failing with both of nneonneo's options, I had to resort to placing the command in a bash script file and then I popen'ed the script. It gives me the desired results.

#include <stdio.h>
#include <string.h>

int main (int argc, char *argv[])
{
        char command[201];
        char buf[501];
        FILE *fp;

        strcpy(command, "/dea/testing/popen/get_file");

        if((fp = popen(command, "r")) == NULL)
        {
                fprintf(stderr, "music_player: popen failed\n");
                return(1);
        }

        if(fgets(buf, sizeof(buf), fp) == NULL)
        {
                fprintf(stderr, "music_player: fgets failed\n");
                return(1);
        }

        printf("%s", buf);
        pclose(fp);
        return(0);
}
3
nneonneo On

popen executes your command using

/bin/sh -c "command"

and your sh doesn't understand the 10# base-conversion prefix. You've been running the command in bash previously.

To fix, you have two options:

  1. Discard the unnecessary 10# prefix (it is the default) for sh compatibility
  2. Use bash:

    popen("bash -c 'command'", ...)