【问题标题】:Run bash command asynch with ncurses in c [duplicate]在c中使用ncurses运行bash命令异步[重复]
【发布时间】:2016-12-10 22:06:00
【问题描述】:

我想创建一个简单的程序来让我的无线网络上每时每刻都连接到客户端。为此,我使用nmapC 中查找适当的地址(客户端的MAC、IP)和ncurses 库。

完成我的工作的 bash 脚本如下:

nmap -sP ip/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print " - "$3;}' | sort

c程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <ncurses.h>

#define DELAY 30000

int main(int argc, char *argv[]) {
  raw();
  noecho();
  keypad(stdscr, TRUE);
  initscr();

  while (1) {

    clear();
    int  maxRows_y, maxCols_x;
    getmaxyx(stdscr, maxRows_y, maxCols_x);

    FILE *fp;
    char path[1000];

    fp = popen("nmap -sP 192.168.0.1/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print \" => \"$3;}' | sort", "r");

    while (fgets(path, 1000, fp) != NULL) {
        printw("%s", path);
    }
    pclose(fp);

    refresh();
    usleep(DELAY); // Shorter delay between movements
  }

  endwin();

  return EXIT_SUCCESS;
}

问题是每次我运行管道时程序都会冻结。这会导致其他问题。例如,如果我想使用时钟来计算从程序开始经过的时间,这不会每秒更新一次(1 -> 2 -> 3 -> ..etc),因为我们必须等待管道完成。而且,如果我添加其他功能,例如菜单,这将导致糟糕的用户体验问题。

我想问是否有一种方法可以在后台运行管道并在它完成进程时获得结果而不会中断我程序的其他功能。请记住,我必须连续运行管道,直到程序退出。

更新:

This question 是我展示的第一个。问题是如果我们将代码更改为这个版本,我们最终会没有任何输出。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <ncurses.h>
#include <fcntl.h>
#include <errno.h>

#define DELAY 30000

int main(int argc, char *argv[]) {
  raw();
  noecho();
  keypad(stdscr, TRUE);
  initscr();


  FILE *f = popen("nmap -sP 192.168.0.1/24 | awk '/Nmap scan report for/{printf $5;}/MAC Address:/{print \" => \"$3;}' | sort", "r");
  int d = fileno(f);
  fcntl(d, F_SETFL, O_NONBLOCK);

  while (1) {

    clear();
    int  maxRows_y, maxCols_x;
    getmaxyx(stdscr, maxRows_y, maxCols_x);

    char path[1000];
    ssize_t r = read(d, path, sizeof(path));
    if (r == -1 && errno == EAGAIN) {
      printw("waiting for data....");
    }
        
    else if (r > 0) {
      printw("%s", path);
      fcntl(d, F_SETFL, O_NONBLOCK);
    }
    else {
      printw("pipe closed");
    }
         

    refresh();
    usleep(DELAY); // Shorter delay between movements
  }

  endwin();

  return EXIT_SUCCESS;
}

【问题讨论】:

  • @merlin2011 这不是重复的。看我的更新。它不工作。

标签: c bash pipe ncurses


【解决方案1】:

我认为问题可能是输出闪烁得太快,您看不到它。

如果您稍微更改代码,以便在输出后不清除屏幕(至少几秒钟),我想您会看到数据。

这是一个对我有用的版本。请注意,子网不同,因为我在自己的网络上进行测试。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <ncurses.h>
#include <fcntl.h>
#include <errno.h>

#define DELAY 30000

int main(int argc, char *argv[]) {
    raw();
    noecho();
    keypad(stdscr, TRUE);
    initscr();


    FILE *f = popen("nmap -sP 10.0.0.13/24", "r");

    int d = fileno(f);
    fcntl(d, F_SETFL, O_NONBLOCK);

    bool processingOutput = false;

    while (1) {
        if (!processingOutput)
            clear();
        int  maxRows_y, maxCols_x;
        getmaxyx(stdscr, maxRows_y, maxCols_x);

        char path[1000];
        ssize_t r = read(d, path, sizeof(path));
        if (r == -1 && errno == EAGAIN && !processingOutput) {
            printw("waiting for data....");
        }
        else if (r > 0) {
            processingOutput = true;
            path[r] = '\0';
            printw("%s", path);
        }
        else {
            printw("pipe closed");
            sleep(10);
            processingOutput = false;
        }


        refresh();
        usleep(DELAY); // Shorter delay between movements
    }
    endwin();
    return EXIT_SUCCESS;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2018-04-03
    • 1970-01-01
    • 2020-02-12
    • 2017-08-18
    相关资源
    最近更新 更多