应用程序中的嵌入式控制台工具

时间:2009-10-23 12:13:31

标签: c++ linux bash console

我目前正在开发一个在实际读取数据之前需要进行一些文件预处理的应用程序。

在外部做这件事是不可能的,所以我想出了一个叉子& execve“cut options filename | sort | uniq -c”等...我执行它就像那样。

但是我认为可能已经有另一种方法可以直接在我的代码中重用所有那些古老而优秀的工作工具,而不必通过shell调用它们。

我目前正在查看busybox,看看是否有一种简单的静态链接方式,并以编程方式调用这些工具但还没有运气。

8 个答案:

答案 0 :(得分:4)

Arkaitz,答案是否定,因为你是如何表达这个问题的。

你要求“另一个选择,直接在我的代码中重用所有那些古老而优秀的工作工具,而不必通过shell调用它们”

问题在于,重复使用所有那些古老而优秀的工具的正确和可接受的方式正是你想要避免的 - 通过外壳调用它们(或者至少将它们作为孩子解雇)例如,通过popen进行处理 - 并且绝对不建议尝试将这些工具包含,复制或复制到您的代码中。

用于数据操作的UNIX(和Linux)模型非常强大且经过验证 - 您为什么要避免使用它?

答案 1 :(得分:3)

“古老”工具是为shell使用而构建的,而不是构建/链接到可执行文件中。但是,最近的工具有很多你在命令行预处理器上显示的内容:带有提取器的iostreams(替换cut),std::sortstd::unique来替换相应的程序...

struct S { string col1, col3; 
   bool operator<( const S& s ) { return col1 < s.col1; }
};
vector<S> v;
while( cin ) {
  S s;
  string dummy;
  cin >> s.col1 >> dummy >> col3 >> dummy;
  v.push_back( s );
}
sort(v.begin(), v.end(), S::smaller );
unique( v.begin(), v.end() );

我认为并不太复杂。

答案 2 :(得分:2)

尝试popen()。

char buffer [ BUFFER_SIZE ];
FILE * f = popen( "cut options filename | sort | uniq -c", "r" );
while( /*NOT*/! feof(f) )
  fgets( buffer, BUFFER_SIZE, f );
pclose( f );

参考:How to execute a command and get output of command within C++ using POSIX?

答案 3 :(得分:1)

你必须通过shell来完成它,但是使用“system”调用会更容易。

while(something) {
           int ret = system("foo");

           if (WIFSIGNALED(ret) &&
               (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT))
                   break;
       }

答案 4 :(得分:1)

只需编写另一个有用的'古老而好的'工具;)并从stdin中读取所有数据并将其返回到stdout。

cat *.txt | grep 'blabla' | sort | my_new_tool | tee -o res_file

答案 5 :(得分:1)

这样做的好方法是:

  • 创建2个管道
  • 分叉新流程
  • 使用stdin函数
  • 替换管道子进程的stdoutdup2
  • exec您想要的命令
  • 使用管道从父进程写入和读取

答案 6 :(得分:0)

busybox也是我的第一个想法,尽管您可能还想考虑嵌入像Python这样的脚本引擎并在Python脚本中进行这些操作。

我绝对不会试图从GNU命令行工具中删除这种功能,因为自UNIX早期以来它们已经大大增加并且发展了很多选项。

如果busybox代码似乎太难以适应,那么下一个我看的地方就是Minix source code。查看以前的版本并选择版本1或2 Minixes之一,因为它们是作为教学代码编写的,因此它们更容易和更简单。

答案 7 :(得分:0)

如果您不想调用外部命令(无论是通过exec,popen还是系统等),但又不想修改这些实用程序的源代码并将它们编译到您的代码中(相对简单,只需将'main'更改为' main_cut'等),然后我看到的唯一剩下的选项是将实用程序嵌入代码中并在运行时提取它们或通过指向代码中的数据动态创建文件系统(例如使用软盘或cd映像并写入一个FUSE模块,用于从ram地址中获取磁盘映像数据)。所有这些似乎只是为了使它看起来像一个整齐的实用程序。

就个人而言,如果我真的必须这样做,我将获得所有这些工具的来源并将其作为外部调用进行编译。当然,你不再容易获得管道,你要么必须使用临时文件进行预处理,要么使用更复杂的涉及协同程序的东西。或者也许是套接字。无论你做什么,都会有很多工作和麻烦!