linux c 获取终端输出到文件,LINUX C获取命令行输出结果
在c程序中,system函數可以運行命令行,但是只能得到該命令行的int型返回值,并不能獲得顯示結果。例如system(“ls”)只能得到0或非0,如果要獲得ls的執行結果,則要通過管道來完成的。首先用popen打開一個命令行的管道,然后通過fgets獲得該管道傳輸的內容,也就是命令行運行的結果
在linux上運行的例子如下:
void?executeCMD(const?char?*cmd,?char?*result)
{
char?buf_ps[1024];
char?ps[1024]={0};
FILE?*ptr;
strcpy(ps,?cmd);
if((ptr=popen(ps,?"r"))!=NULL)
{
while(fgets(buf_ps,?1024,?ptr)!=NULL)
{
strcat(result,?buf_ps);
if(strlen(result)>1024)
break;
}
pclose(ptr);
ptr?=?NULL;
}
else
{
printf("popen?%s?error\n",?ps);
}
}
在這段代碼中,參數cmd為要執行的命令行,result為命令行運行結果。輸入的cmd命令最好用... 2>&1 的形式,這樣將標準錯誤也讀進來
這次的項目中更要獲取U盤設備的名稱,網上搜到可以使用blkid命令,執行blkid命令結果如下:
/dev/sda1: UUID="157b922d-8f42-4514-a2f0-f31eb7ceae68" TYPE="ext4"
/dev/sda2: UUID="0e69206a-03eb-498c-a1d3-46c5b2f9d0cc" TYPE="ext4"
/dev/sda3: UUID="7dc1e588-6794-490f-b315-1af7e1fcbdae" TYPE="swap"
/dev/sdb1: UUID="54f1d622-572e-41d6-b177-58a4369ef38f" TYPE="ext3"
/dev/sdc1: UUID="B653-1BCA" TYPE="vfat"
最后一行即為U盤的信息。
在windows上相對要麻煩些,需要用CreateProcessW函數來啟動新的進程,以便執行cmd命令。windows下的例子請看這個調用md5sum.exe來獲得文件md5值的代碼:
int?GetFileMD5W(const?TCHAR?*filefullpath,?char?*MD5key)
{
TCHAR?szfilenameW[MAX_PATH_LENGTH]={0};???//保存文件名
TCHAR?szFilePathW[MAX_PATH_LENGTH]={0};???//保存路徑
TCHAR?szCmdLineW[MAX_PATH_LENGTH]={0};????//保存命令行信息
char?buffer[MAX_PATH_LENGTH]?=?{0};???????//保存命令行輸出
TCHAR?*pos=NULL;
DWORD?bytesRead?=?0;
if?(wcslen(filefullpath)>MAX_PATH_LENGTH)
return?false;
wcscpy(szFilePathW,?filefullpath);
int?i=0;
while?(szFilePathW[i]!=0)
{
if?(szFilePathW[i]==_T('/'))
szFilePathW[i]=_T('\\');
i++;
}
if?((pos=wcschr(szFilePathW,?'\\'))==NULL)???//找到文件路徑最右邊的'\'
{
return?false;
}
wcscpy(szfilenameW,?pos+1);??????????????????//獲得文件名
*pos=0;??????????????????????????????????????//獲得文件所在路徑
if?(wcslen(szfilenameW)==0?||?wcslen(szFilePathW)==0?||?MD5key==NULL)??//檢查文件名或路徑大小是否合適
{
return?false;
}
wsprintf(szCmdLineW,L"cmd.exe?/c?md5sum?\"%s\"?",szfilenameW);???????//給出命令行信息
//eg:?cmd.exe?/c?md5sum?"for?text.txt"
SECURITY_ATTRIBUTES?sa?=?{0};
HANDLE?hRead?=?NULL,?hWrite?=?NULL;??????????????????????????????????//設置管道讀寫句柄
sa.nLength?=?sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor?=?NULL;
sa.bInheritHandle?=?TRUE;
if?(!CreatePipe(&hRead,?&hWrite,?&sa,0))?????????????????????????????//創建管道
{
return?false;
}
STARTUPINFO?si?=?{0};
PROCESS_INFORMATION?pi?=?{0};
si.cb?=?sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError?=?hWrite;??????????????????????????????????????????????//
si.hStdOutput?=?hWrite;?????????????????????????????????????????????//
si.wShowWindow?=?SW_HIDE;
si.dwFlags?=?STARTF_USESHOWWINDOW?|?STARTF_USESTDHANDLES;
//關鍵步驟,CreateProcess函數參數意義請查閱MSDN
if?(!CreateProcessW(NULL,?szCmdLineW
,NULL,NULL,TRUE,NULL,NULL,szFilePathW,&si,π))?????????????//注意,這里將szFilePathW(文件所在路徑)作為倒數第三個參數
{
CloseHandle(hWrite);
CloseHandle(hRead);
return?false;
}
WaitForSingleObject(pi.hProcess,INFINITE);?????????????????????????//等待md5sum結束
//???Close???process???and???thread???handles.
CloseHandle(pi.hProcess);??????????????????????????????????????????//關閉新進程的主線程
CloseHandle(pi.hThread);????????????????????????????????????????//關閉新進程
CloseHandle(hWrite);???????????????????????????????????????????????//關閉管道的寫句柄
ReadFile(hRead,?buffer,?MAX_PATH_LENGTH,?&bytesRead,?NULL);????????//從管道中讀取md5sum的運行結果
CloseHandle(hRead);????????????????????????????????????????????????//關閉管道的讀句柄
if?(NULL!=strstr(buffer,"md5sum"))?????????????????????????????????//如果運行結果中出現了md5sum,多半是執行失敗
{
//TRACE(buffer);
return?-2;
}
else?if?(!strnicmp(buffer,"No?such?file:",strlen("No?such?file:")))?//找不到制定文件
{
//TRACE(buffer);
return?-1;
}
if?(strlen(buffer)<32)??????????????????????????????????????????????//獲得結果小于32位,說明沒有得到md5值
{
//TRACE(buffer);
return?false;
}
strncpy(MD5key,?buffer,?32);????????????????????????????????????????//獲得md5值成功
strcat(MD5key,?"\0");
return?TRUE;
}
總結
以上是生活随笔為你收集整理的linux c 获取终端输出到文件,LINUX C获取命令行输出结果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: KDD 2016 | node2vec:
- 下一篇: C语言段错误的有用总结