有誰知道如何捕捉到輸出獲取標準輸出(我認爲它的標準輸出)從execvp
而不是系統的終端打印出來(在Linux下C)?從執行的應用
Q
從執行的應用
6
A
回答
6
execvp
替換內存當前正在運行的進程。沒有「捕捉」輸出。
我懷疑你正試圖從現有的進程中運行外部進程,並分析其輸出。對於那些需要使用popen()
它做了fork()
那麼exec()
,返回FILE *
閱讀(這將是您剛剛運行的進程的stdout
)。
1
見popen
的文檔,我認爲這正是你所需要的。
1
正如其他人所說,popen
是你要使用的東西。事情是這樣的......
#include <iomanip>
#include <iostream>
using namespace std;
const int MAX_BUFFER = 255;
int main()
{
string cmd;
cout << "enter cmd: ";
cin >> cmd;
cout << endl << "running " << cmd << "…" << endl;
string stdout;
char buffer[MAX_BUFFER];
FILE *stream = popen(cmd.c_str(), "r");
while (fgets(buffer, MAX_BUFFER, stream) != NULL)
stdout.append(buffer);
pclose(stream);
cout << endl << "output: " << endl << stdout << endl;
}
4
我不信任popen/pclose
,正如我在哪裏SIGCHLD
被處理略有不同太多的系統工作。我不信任由popen
使用的sh
-shell解析,因爲我很少使用它。
短22歲的奧賴利書Using C on the UNIX System, by Dave Curry仍然是這種東西一非常很好的參考。
無論如何,這裏是一些代碼。它有點冗長,因爲它將樣本字符串"/bin/ls /etc"
解析爲數組{"/bin/ls", "/etc", 0}
。但我發現使用字符串格式更容易和縮短98%的時間,雖然這個例子勉強。
此代碼生成/etc.
的列表您需要更改一些內容,例如, NUMBER()
,這與XtNumber()
相同。你需要決定它是否符合你的處理SIGCHLD
。
int main(void) { // list the files in /etc
char buf[100];
FILE *fp;
int pid = spawnfp("/bin/ls /etc", &fp);
while (fgets(buf, sizeof buf, fp))
printf("%s", buf);
fclose(fp); // pclose() replacement
kill(pid, SIGKILL); // pclose() replacement
return 0;
}
在這裏子程序是:
static int spawnpipe(const char *argv[], int *fd) // popen() replacement
{
int pid;
int pipe_fds[2];
if (pipe(pipe_fds) < 0)
FatalError("pipe");
switch ((pid = fork()))
{
case -1:
FatalError("fork");
case 0: // child
close(1);
close(2);
dup(pipe_fds[0]);
dup(pipe_fds[1]);
close(pipe_fds[0]);
close(pipe_fds[1]);
execv(argv[0], (char * const *)argv);
perror("execv");
_exit(EXIT_FAILURE); // sic, not exit()
default:
*fd = pipe_fds[0];
close(pipe_fds[1]);
return pid;
}
}
這一個ASCII字符串轉換爲argv
列表中,這可能是沒用的,你:
Bool convertStringToArgvList(char *p, const char **argv, int maxNumArgs)
{
// Break up a string into tokens, on spaces, except that quoted bits,
// with single-quotes, are kept together, without the quotes. Such
// single-quotes cannot be escaped. A double-quote is just an ordinary char.
// This is a *very* basic parsing, but ok for pre-programmed strings.
int cnt = 0;
while (*p)
{
while (*p && *p <= ' ') // skip spaces
p++;
if (*p == '\'') // single-quote block
{
if (cnt < maxNumArgs)
argv[cnt++] = ++p; // drop quote
while (*p && *p != '\'')
p++;
}
else if (*p) // simple space-delineated token
{
if (cnt < maxNumArgs)
argv[cnt++] = p;
while (*p > ' ')
p++;
}
if (*p)
*p++ = 0; // nul-terminate
}
if (cnt < maxNumArgs)
argv[cnt++] = 0;
return cnt <= maxNumArgs; // check for too many tokens (unlikely)
}
該轉換參數字符串令牌並且更重要的是,fd
到fp
,因爲OP請求stdout
:
int spawnfp(const char *command, FILE **fpp)
{
const char *argv[100];
int fd, pid;
if (!convertStringToArgvList(strdupa(command), argv, NUMBER(argv)))
FatalError("spawnfp");
pid = spawnpipe(argv, &fd);
*fpp = fdopen(fd, "r");
return pid;
}
0
我發現這個答案,它給popen
一個execvp
風格的界面。
https://codereview.stackexchange.com/questions/31063/popen-with-array-of-arguments
相關問題
- 1. 執行應用
- 2. 從Java應用程序執行Pig
- 3. 從C#執行excel應用程序
- 4. 從應用程序執行rails runner
- 5. 從Rails應用程序執行seeds.rb
- 6. 從eclipse執行GWT應用程序
- 7. 從Php執行Java應用程序
- 8. Gamecenter Facebook Like從應用程序執行
- 9. 由DefaultHttpClient執行的殺死應用程序(killProcess)執行執行
- 10. 執行應用程序關閉執行程序應用程序
- 11. 應用程序從哪裏運行的可執行目錄?
- 12. 德爾福執行應用
- 13. 執行從Android的
- 14. 確定是否從另一個java應用程序執行java執行成功
- 15. 從Perl腳本執行.net命令行應用程序
- 16. 從應用程序運行exe可執行文件與系統
- 17. 如何從命令行執行iOS應用程序驗證
- 18. 從Java執行外部應用程序或運行bat文件
- 19. 從命令行執行控制檯應用程序?
- 20. 如果從cmd執行應用程序,寫入命令行
- 21. 從windows應用程序執行命令行
- 22. 如何從java應用程序執行可運行JAR
- 23. 從Silverlight執行JavaScript從瀏覽器應用程序
- 24. 從AJAX執行Javascript函數 - HTML響應
- 25. 從遠程執行得到響應.exe
- 26. 從ASP.NET MVC2應用程序執行Ajax調用的問題應用程序
- 27. 在Netbeans中逐步執行應用程序的執行路徑
- 28. 如何設置從ESL執行的應用程序的應用程序UUID
- 29. 是用戶從shell執行的pelican可執行腳本?
- 30. 如何使用javascript執行從Linux的可執行文件
那麼,它們是否也可以使用參數? – topherg
那麼cin會放棄參數,但是如果你正確地使用w/getline,你可以處理一些「ls -latr」。 – Ternary