如何转义c中popen()函数中使用的命令中的特殊字符?

如何转义c中popen()函数中使用的命令中的特殊字符?,c,linux,shell,escaping,popen,C,Linux,Shell,Escaping,Popen,我想将系统命令输出存储在Linux中c程序的变量中。 在这种情况下,我需要通过popen()函数在c程序中运行一个长线性命令。我有下面的长命令,在终端运行良好 awk '{if(l1){print ($2-l1)/1024"kB/s",($10-l2)/1024"kB/s"} else{l1=$2; l2=$10;}}' <(grep wlan0 /proc/net/dev) <(sleep 1; grep wlan0 /proc/net/dev) 但我还是会 sh

我想将系统命令输出存储在Linux中c程序的变量中。 在这种情况下,我需要通过popen()函数在c程序中运行一个长线性命令。我有下面的长命令,在终端运行良好

    awk '{if(l1){print ($2-l1)/1024"kB/s",($10-l2)/1024"kB/s"} else{l1=$2; l2=$10;}}'     <(grep wlan0 /proc/net/dev) <(sleep 1; grep wlan0 /proc/net/dev)
但我还是会
sh:1:语法错误:“(”意外
-(c/net/dev)-
错误:无法关闭命令流

错误

编辑2: Pinetwig指出,该命令的长度为140字节,而command_LEN。我分配的值是124。我将该值增加到1024,但结果没有改变。 我认为错误与字符串“awk”{if(l1){print($2-l1)/1024,($10-l2)/1024}或者{l1=$2;l2=$10;}}}}有关

sh: 1: Syntax error: "(" unexpected
来自于使用bash(或ksh)功能:


不是答案,而是旁注:

既然可以直接处理
/proc/net/dev
伪文件,为什么还要使用外部命令呢?它是Linux内核提供的用户空间接口,因此在可预见的将来不会以不兼容的方式改变

就我个人而言,我会使用如下内容:

#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

struct interface {
    struct interface   *next;
    unsigned long long  rx_bytes;
    unsigned long long  rx_packets;
    unsigned long long  rx_errors;
    unsigned long long  rx_dropped;
    unsigned long long  rx_fifo;
    unsigned long long  rx_frame;
    unsigned long long  rx_compressed;
    unsigned long long  rx_multicast;
    unsigned long long  tx_bytes;
    unsigned long long  tx_packets;
    unsigned long long  tx_errors;
    unsigned long long  tx_dropped;
    unsigned long long  tx_fifo;
    unsigned long long  tx_collisions;
    unsigned long long  tx_carrier;
    unsigned long long  tx_compressed;
    char                name[];
};

void free_interfaces(struct interface *next)
{
    while (next != NULL) {
        struct interface *curr = next;
        next = next->next;
        curr->next = NULL;
        curr->name[0] = '\0';
        free(curr);
    }
}

struct interface *list_interfaces(void)
{
    struct interface  *list = NULL;
    struct interface  *iface;

    FILE              *in;
    unsigned long long field[16];
    char              *name, *next, *ends;
    size_t             i, namelen;

    char              *line = NULL;
    size_t             size = 0;
    ssize_t            len;

    in = fopen("/proc/net/dev", "rb");
    if (in == NULL)
        return NULL; /* errno was set by fopen() */

    while (1) {

        len = getline(&line, &size, in);
        if (len < (ssize_t)1)
            break;

        name = line;
        while (*name == ' ')
            name++;

        ends = name;
        while (*ends != '\0' && *ends != '\n' && *ends != ' ' && *ends != ':')
            ends++;

        if (*ends != ':' || ends == name)
            continue;

        namelen = (size_t)(ends - name);
        next = ends + 1;

        for (i = 0; i < 15; i++) {
            ends = NULL;
            errno = 0;
            field[i] = strtoull(next, &ends, 0);
            if (ends == NULL || ends == next || errno != 0) {
                ends = NULL;
                break;
            }
            next = ends;
        }
        if (ends == NULL)
            continue;

        iface = malloc(sizeof (struct interface) + namelen + 1);
        if (iface == NULL) {
            fclose(in);
            free_interfaces(list);
            errno = ENOMEM;
            return NULL;
        }

        memcpy(iface->name, name, namelen);
        iface->name[namelen] = '\0';

        iface->rx_bytes      = field[0];
        iface->rx_packets    = field[1];
        iface->rx_errors     = field[2];
        iface->rx_dropped    = field[3];
        iface->rx_fifo       = field[4];
        iface->rx_frame      = field[5];
        iface->rx_compressed = field[6];
        iface->rx_multicast  = field[7];

        iface->tx_bytes      = field[8];
        iface->tx_packets    = field[9];
        iface->tx_errors     = field[10];
        iface->tx_dropped    = field[11];
        iface->tx_fifo       = field[12];
        iface->tx_collisions = field[13];
        iface->tx_carrier    = field[14];
        iface->tx_compressed = field[15];

        iface->next = list;
        list = iface;
    }

    free(line);
    line = NULL;

    if (ferror(in) || !feof(in)) {
        fclose(in);
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    if (fclose(in)) {
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    errno = 0;
    return list;
}

int main(void) {
    struct interface *list, *curr;

    list = list_interfaces();
    if (!list) {
        fprintf(stderr, "Cannot get network interface statistics: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    for (curr = list; curr != NULL; curr = curr->next)
        printf("%s: %llu bytes, %llu packets sent; %llu bytes, %llu packets received.\n",
               curr->name, curr->tx_bytes, curr->tx_packets, curr->rx_bytes, curr->rx_packets);

    free_interfaces(list);
    return EXIT_SUCCESS;
}
#定义POSIX_C_SOURCE200809L
#包括
#包括
#包括
#包括
结构接口{
结构接口*next;
无符号长rx_字节;
无符号长rx_数据包;
无符号长rx_错误;
未签名的长-长rx_被丢弃;
无符号长接收fifo;
无符号长rx_帧;
无符号长rx_压缩;
无符号长rx_多播;
无符号长tx_字节;
无符号长tx_数据包;
无符号长发送错误;
未签名的长-长发送被丢弃;
无符号长发送fifo;
无符号长-长tx_碰撞;
无符号长tx_载波;
无符号长tx_压缩;
字符名[];
};
无效自由_接口(结构接口*下一步)
{
while(下一步!=NULL){
结构接口*curr=next;
下一步=下一步->下一步;
当前->下一步=空;
当前->名称[0]='\0';
免费(货币);
}
}
结构接口*列表接口(无效)
{
结构接口*list=NULL;
结构接口*iface;
文件*in;
无符号长字段[16];
char*name,*next,*结束;
尺寸i,名称len;
char*line=NULL;
大小\u t大小=0;
西泽特伦;
in=fopen(“/proc/net/dev”,“rb”);
if(in==NULL)
return NULL;/*错误号由fopen()设置*/
而(1){
len=getline(&line,&size,in);
如果(长度<(ssize_t)1)
打破
名称=行;
而(*name='')
name++;
结束=名称;
而(*ends!='\0'&&&&*ends!='\n'&&&*ends!=''&&*ends!=':')
结束++;
如果(*结束!=':'| |结束==名称)
继续;
namelen=(size_t)(ends-name);
下一步=结束+1;
对于(i=0;i<15;i++){
ends=NULL;
errno=0;
字段[i]=strtoull(下一个,&ends,0);
如果(ends==NULL | | ends==next | | errno!=0){
ends=NULL;
打破
}
下一个=结束;
}
if(ends==NULL)
继续;
iface=malloc(sizeof(结构接口)+namelen+1);
if(iface==NULL){
fclose(in);
自由接口(列表);
errno=ENOMEM;
返回NULL;
}
memcpy(iface->name,name,namelen);
iface->name[namelen]='\0';
iface->rx_字节=字段[0];
iface->rx_数据包=字段[1];
iface->rx_错误=字段[2];
iface->rx_drop=字段[3];
iface->rx_fifo=字段[4];
iface->rx_帧=字段[5];
iface->rx_compressed=字段[6];
iface->rx_多播=字段[7];
iface->tx_字节=字段[8];
iface->tx_数据包=字段[9];
iface->tx_errors=字段[10];
iface->tx_drop=字段[11];
iface->tx_fifo=字段[12];
iface->tx_碰撞=字段[13];
iface->tx_载波=字段[14];
iface->tx_compressed=字段[15];
iface->next=列表;
列表=iface;
}
自由线;
行=空;
如果(ferror(in)| |!feof(in)){
fclose(in);
自由接口(列表);
errno=EIO;
返回NULL;
}
如果(fclose(in)){
自由接口(列表);
errno=EIO;
返回NULL;
}
errno=0;
退货清单;
}
内部主(空){
结构接口*列表,*当前;
列表=列表_接口();
如果(!列表){
fprintf(stderr,“无法获取网络接口统计信息:%s。\n”,strerror(errno));
返回退出失败;
}
对于(curr=list;curr!=NULL;curr=curr->next)
printf(“%s:%llu字节,%llu数据包已发送;%llu字节,%llu数据包已接收。\n”,
curr->name,curr->tx\u字节,curr->tx\u数据包,curr->rx\u字节,curr->rx\u数据包);
自由接口(列表);
返回退出成功;
}

下面的修改示例每五秒钟输出一次网络传输速率,直到中断或终止(通过INT(Ctrl+C或TERM信号)

#定义POSIX_C_SOURCE200809L
#包括
#包括
#包括
#包括
#包括
#包括
结构接口{
结构接口*next;
无符号长rx_字节;
无符号长rx_数据包;
无符号长rx_错误;
未签名的长-长rx_被丢弃;
无符号长接收fifo;
无符号长rx_帧;
无符号长rx_压缩;
无符号长rx_多播;
无符号长tx_字节;
无符号长tx_数据包;
无符号长发送错误;
未签名的长-长发送被丢弃;
无符号长发送_
sh: 1: Syntax error: "(" unexpected
<(grep wlan0 /proc/net/dev)
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

struct interface {
    struct interface   *next;
    unsigned long long  rx_bytes;
    unsigned long long  rx_packets;
    unsigned long long  rx_errors;
    unsigned long long  rx_dropped;
    unsigned long long  rx_fifo;
    unsigned long long  rx_frame;
    unsigned long long  rx_compressed;
    unsigned long long  rx_multicast;
    unsigned long long  tx_bytes;
    unsigned long long  tx_packets;
    unsigned long long  tx_errors;
    unsigned long long  tx_dropped;
    unsigned long long  tx_fifo;
    unsigned long long  tx_collisions;
    unsigned long long  tx_carrier;
    unsigned long long  tx_compressed;
    char                name[];
};

void free_interfaces(struct interface *next)
{
    while (next != NULL) {
        struct interface *curr = next;
        next = next->next;
        curr->next = NULL;
        curr->name[0] = '\0';
        free(curr);
    }
}

struct interface *list_interfaces(void)
{
    struct interface  *list = NULL;
    struct interface  *iface;

    FILE              *in;
    unsigned long long field[16];
    char              *name, *next, *ends;
    size_t             i, namelen;

    char              *line = NULL;
    size_t             size = 0;
    ssize_t            len;

    in = fopen("/proc/net/dev", "rb");
    if (in == NULL)
        return NULL; /* errno was set by fopen() */

    while (1) {

        len = getline(&line, &size, in);
        if (len < (ssize_t)1)
            break;

        name = line;
        while (*name == ' ')
            name++;

        ends = name;
        while (*ends != '\0' && *ends != '\n' && *ends != ' ' && *ends != ':')
            ends++;

        if (*ends != ':' || ends == name)
            continue;

        namelen = (size_t)(ends - name);
        next = ends + 1;

        for (i = 0; i < 15; i++) {
            ends = NULL;
            errno = 0;
            field[i] = strtoull(next, &ends, 0);
            if (ends == NULL || ends == next || errno != 0) {
                ends = NULL;
                break;
            }
            next = ends;
        }
        if (ends == NULL)
            continue;

        iface = malloc(sizeof (struct interface) + namelen + 1);
        if (iface == NULL) {
            fclose(in);
            free_interfaces(list);
            errno = ENOMEM;
            return NULL;
        }

        memcpy(iface->name, name, namelen);
        iface->name[namelen] = '\0';

        iface->rx_bytes      = field[0];
        iface->rx_packets    = field[1];
        iface->rx_errors     = field[2];
        iface->rx_dropped    = field[3];
        iface->rx_fifo       = field[4];
        iface->rx_frame      = field[5];
        iface->rx_compressed = field[6];
        iface->rx_multicast  = field[7];

        iface->tx_bytes      = field[8];
        iface->tx_packets    = field[9];
        iface->tx_errors     = field[10];
        iface->tx_dropped    = field[11];
        iface->tx_fifo       = field[12];
        iface->tx_collisions = field[13];
        iface->tx_carrier    = field[14];
        iface->tx_compressed = field[15];

        iface->next = list;
        list = iface;
    }

    free(line);
    line = NULL;

    if (ferror(in) || !feof(in)) {
        fclose(in);
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    if (fclose(in)) {
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    errno = 0;
    return list;
}

int main(void) {
    struct interface *list, *curr;

    list = list_interfaces();
    if (!list) {
        fprintf(stderr, "Cannot get network interface statistics: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    for (curr = list; curr != NULL; curr = curr->next)
        printf("%s: %llu bytes, %llu packets sent; %llu bytes, %llu packets received.\n",
               curr->name, curr->tx_bytes, curr->tx_packets, curr->rx_bytes, curr->rx_packets);

    free_interfaces(list);
    return EXIT_SUCCESS;
}
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

struct interface {
    struct interface   *next;
    unsigned long long  rx_bytes;
    unsigned long long  rx_packets;
    unsigned long long  rx_errors;
    unsigned long long  rx_dropped;
    unsigned long long  rx_fifo;
    unsigned long long  rx_frame;
    unsigned long long  rx_compressed;
    unsigned long long  rx_multicast;
    unsigned long long  tx_bytes;
    unsigned long long  tx_packets;
    unsigned long long  tx_errors;
    unsigned long long  tx_dropped;
    unsigned long long  tx_fifo;
    unsigned long long  tx_collisions;
    unsigned long long  tx_carrier;
    unsigned long long  tx_compressed;
    char                name[];
};


static volatile sig_atomic_t done = 0;

static void done_handler(int signum)
{
    done = 1;
}

static int install_done(const int signum)
{
    struct sigaction act;
    sigemptyset(&act.sa_mask);
    act.sa_handler = done_handler;
    act.sa_flags = 0;
    if (sigaction(signum, &act, NULL) != -1)
        errno = 0;
    return errno;
}


void free_interfaces(struct interface *next)
{
    while (next != NULL) {
        struct interface *curr = next;
        next = next->next;
        curr->next = NULL;
        curr->name[0] = '\0';
        free(curr);
    }
}

struct interface *find_interface(struct interface *list, const char *const name)
{
    if (!name)
        return NULL;

    while (list != NULL)
        if (!strcmp(list->name, name))
            return list;
        else
            list = list->next;

    return NULL;
}

struct interface *list_interfaces(void)
{
    struct interface  *list = NULL;
    struct interface  *iface;

    FILE              *in;
    unsigned long long field[16];
    char              *name, *next, *ends;
    size_t             i, namelen;

    char              *line = NULL;
    size_t             size = 0;
    ssize_t            len;

    in = fopen("/proc/net/dev", "rb");
    if (in == NULL)
        return NULL; /* errno was set by fopen() */

    while (1) {

        len = getline(&line, &size, in);
        if (len < (ssize_t)1)
            break;

        name = line;
        while (*name == ' ')
            name++;

        ends = name;
        while (*ends != '\0' && *ends != '\n' && *ends != ' ' && *ends != ':')
            ends++;

        if (*ends != ':' || ends == name)
            continue;

        namelen = (size_t)(ends - name);
        next = ends + 1;

        for (i = 0; i < 15; i++) {
            ends = NULL;
            errno = 0;
            field[i] = strtoull(next, &ends, 0);
            if (ends == NULL || ends == next || errno != 0) {
                ends = NULL;
                break;
            }
            next = ends;
        }
        if (ends == NULL)
            continue;

        iface = malloc(sizeof (struct interface) + namelen + 1);
        if (iface == NULL) {
            fclose(in);
            free_interfaces(list);
            errno = ENOMEM;
            return NULL;
        }

        memcpy(iface->name, name, namelen);
        iface->name[namelen] = '\0';

        iface->rx_bytes      = field[0];
        iface->rx_packets    = field[1];
        iface->rx_errors     = field[2];
        iface->rx_dropped    = field[3];
        iface->rx_fifo       = field[4];
        iface->rx_frame      = field[5];
        iface->rx_compressed = field[6];
        iface->rx_multicast  = field[7];

        iface->tx_bytes      = field[8];
        iface->tx_packets    = field[9];
        iface->tx_errors     = field[10];
        iface->tx_dropped    = field[11];
        iface->tx_fifo       = field[12];
        iface->tx_collisions = field[13];
        iface->tx_carrier    = field[14];
        iface->tx_compressed = field[15];

        iface->next = list;
        list = iface;
    }

    free(line);
    line = NULL;

    if (ferror(in) || !feof(in)) {
        fclose(in);
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    if (fclose(in)) {
        free_interfaces(list);
        errno = EIO;
        return NULL;
    }

    errno = 0;
    return list;
}

static void set_timespec(struct timespec *const ptr, const double seconds)
{
    if (ptr) {
        if (seconds <= 0.0) {
            ptr->tv_sec = 0;
            ptr->tv_nsec = 0;
        } else {
            const long s = (long)seconds;
            const long ns = (seconds - (double)s) * 1000000000.0;
            ptr->tv_sec = s;
            if (ns < 0L)
                ptr->tv_nsec = 0L;
            else
            if (ns < 1000000000L)
                ptr->tv_nsec = ns;
            else
                ptr->tv_nsec = 999999999L;
        }
    }
}

static double get_timespec(const struct timespec *const ptr)
{
    if (ptr)
        return (double)ptr->tv_sec + (double)ptr->tv_nsec / 1000000000.0;
    else
        return 0.0;
}

int main(void) {
    struct interface *before, *after;
    double            interval = 5.0;

    if (install_done(SIGINT) || install_done(SIGTERM)) {
        fprintf(stderr, "Cannot install signal handlers: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    before = NULL;
    after  = list_interfaces();
    if (!after) {
        fprintf(stderr, "Cannot get network interface statistics: %s.\n", strerror(errno));
        return EXIT_FAILURE;
    }

    while (!done) {
        struct interface *curr, *prev;
        struct timespec   req, rem;
        double            duration = interval;
        double            tx_rate, rx_rate;

        set_timespec(&req, duration);
        if (nanosleep(&req, &rem) == -1 && errno == EINTR)
            duration -= get_timespec(&rem);
        if (done)
            break;
        if (duration <= 0.0)
            continue;

        free_interfaces(before);
        before = after;
        after = list_interfaces();
        if (!after) {
            fprintf(stderr, "Cannot get network interface statistics: %s.\n", strerror(errno));
            return EXIT_FAILURE;
        }

        rx_rate = 0.0;
        tx_rate = 0.0;

        for (curr = after; curr != NULL; curr = curr->next) {
            if (!strcmp(curr->name, "lo"))
                continue;

            prev = find_interface(before, curr->name);
            if (prev) {
                const double rx = ((double)curr->rx_bytes - (double)prev->rx_bytes) * 8.0 / 1024.0 / duration;
                const double tx = ((double)curr->tx_bytes - (double)prev->tx_bytes) * 8.0 / 1024.0 / duration;

                printf("%s: %9.0f kbits/s sent, %9.0f kbits/s received\n", curr->name, tx, rx);

                rx_rate += rx;
                tx_rate += tx;
            }
        }

        printf("Total: %9.0f kbits/s sent, %9.0f kbits/s received\n\n", tx_rate, rx_rate);
        fflush(stdout);
    }

    return EXIT_SUCCESS;
}
/* feature-test macro needed for asprintf(3) */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

/* Should be a command-line parameter */
#define COUNT 60

/* Open a statistic file */
FILE* open_stat(const char* iface, const char* stat) {
  char* filename = NULL;
  FILE* file;
  if (asprintf(&filename,
               "/sys/class/net/%s/statistics/%s",
               iface, stat) < 0) {
    perror("asprintf");
  }
  else {
    file = fopen(filename, "r");
    if (file)
      setvbuf(file, NULL, _IONBF, 0);
    else
      perror(filename);
  }
  free(filename);
  return file;
}

/* Read a statistic from a statistic file */
unsigned long read_stat(FILE* statfile) {
  unsigned long value;
  rewind(statfile);
  int n = fscanf(statfile, "%lu", &value);
  if (n != 1) { perror("scanf"); return -1; }
  return value;
}

/* Sample main file */
int main(int argc, char** argv) {
  const char* iface = "wlan0";
  if (argc > 1) iface = argv[1];
  FILE* recvf = open_stat(iface, "rx_bytes");
  if (!recvf) exit(1);
  FILE* xmitf = open_stat(iface, "tx_bytes");
  if (!xmitf) exit(1);
  unsigned long recv = read_stat(recvf);
  unsigned long xmit = read_stat(xmitf);
  for(int i = 0; i < COUNT; ++i) {
    sleep(1);
    unsigned long new_recv = read_stat(recvf);
    unsigned long new_xmit = read_stat(xmitf);
    printf("in: %6.3f kB/s, out: %6.3f kB/s\n",
           (new_recv - recv) / 1024.0,
           (new_xmit - xmit) / 1024.0);
    recv = new_recv;
    xmit = new_xmit;
  }
  fclose(recvf);
  fclose(xmitf);
  return 0;
}