如何從Linux中的C執行shell腳本?如何在Linux中從C執行shell腳本?
回答
這取決於你想用腳本(或者你想運行其他程序)做什麼。
如果你只是想運行腳本system
是最容易做的事情,但它也做一些其他的事情,包括運行一個shell並讓它運行命令(/ bin/sh在大多數* nix下)。
如果要通過其標準輸入提供shell腳本或使用其標準輸出,可以使用popen
(和pclose
)設置管道。這也使用shell(大多數* nix下的/ bin/sh)來運行該命令。
這兩個都是庫函數,它們在底層做了很多工作,但如果它們不能滿足你的需求(或者你只是想實驗和學習),你還可以直接使用系統調用。這也可以讓你避免讓shell(/ bin/sh)爲你運行你的命令。
感興趣的系統調用是fork
,execve
和waitpid
。您可能需要使用execve
(關於它們的列表,請輸入man 3 exec
)的庫封裝器之一。您可能還想使用其他等待功能之一(man 2 wait
擁有這些功能)。此外,您可能對與fork有關的系統調用clone
和vfork
感興趣。
fork
重複當前程序,其中唯一的主要區別是新進程從調用fork返回0。父進程獲取新進程的進程ID(或錯誤)。
execve
用新程序替換當前程序(保持相同的進程ID)。
waitpid
被父進程用於等待特定的子進程完成。
讓fork和execve步驟分離後,程序可以在創建新過程之前對其進行一些設置(而不會自動搞亂)。這些包括將標準輸入,輸出和標準錯誤更改爲與所使用的父進程不同的文件,更改進程的用戶或組,關閉子進程不需要的文件,更改會話或更改環境變量。
您可能也有興趣pipe
和dup2
系統調用。 pipe
創建一個管道(同時具有輸入和輸出文件描述符)。dup2
將文件描述符複製爲特定的文件描述符(dup
類似,但將文件描述符複製到最低可用文件描述符)。
您可以使用system
:
system("/usr/local/bin/foo.sh");
同時使用sh -c
執行它這將阻止,則返回的狀態代碼。
+1不要忘了包括''
...假設它有可執行位和shebang行。一般來說,'system(「/ bin/sh /usr/local/bin/foo.sh」);'。是的,這實際上調用了兩次shell。 – 2010-09-17 15:07:29
如果您需要更精細的等級控制,您還可以去fork
pipe
exec
路線。這將允許您的應用程序檢索從shell腳本輸出的數據。
如果你確定與POSIX,您還可以使用popen()
/pclose()
#include <stdio.h>
#include <stdlib.h>
int main(void) {
/* ls -al | grep '^d' */
FILE *pp;
pp = popen("ls -al", "r");
if (pp != NULL) {
while (1) {
char *line;
char buf[1000];
line = fgets(buf, sizeof buf, pp);
if (line == NULL) break;
if (line[0] == 'd') printf("%s", line); /* line includes '\n' */
}
pclose(pp);
}
return 0;
}
感謝您使用此示例代碼。 – 2016-12-10 20:20:31
我更喜歡fork + execlp作爲doron提到的「更精細」控件。 示例代碼如下所示。
將命令存儲在char數組參數中,並將malloc空間存儲爲結果。
int fd[2];
pipe(fd);
if ((childpid = fork()) == -1){
fprintf(stderr, "FORK failed");
return 1;
} else if(childpid == 0) {
close(1);
dup2(fd[1], 1);
close(fd[0]);
execlp("/bin/sh","/bin/sh","-c",parameters,NULL);
}
wait(NULL);
read(fd[0], result, RESULT_SIZE);
printf("%s\n",result);
'close(1);'是不需要的,因爲dup2()在重新分配它之前會自行關閉newfd。 – FedericoCapaldo 2017-06-09 23:11:08
一個簡單的方法是.....
#include <stdio.h>
#include <stdlib.h>
#define SHELLSCRIPT "\
#/bin/bash \n\
echo \"hello\" \n\
echo \"how are you\" \n\
echo \"today\" \n\
"
/*Also you can write using char array without using MACRO*/
/*You can do split it with many strings finally concatenate
and send to the system(concatenated_string); */
int main()
{
puts("Will execute sh with the following script :");
puts(SHELLSCRIPT);
puts("Starting now:");
system(SHELLSCRIPT); //it will run the script inside the c code.
return 0;
}
說感謝
尤達@http://www.unix.com/programming/216190-putting-bash-script-c-program.html
- 1. 在shell腳本中執行linux命令
- 2. 從python腳本執行linux shell命令
- 3. 函數從linux的shell腳本不執行在c程序
- 4. C++:在linux shell腳本中運行gdb
- 5. 在shell腳本執行程序的linux
- 6. 從linux shell腳本運行linux可執行文件
- 7. 如何在Linux上的當前shell中執行腳本?
- 8. 如何在cygwin中執行shell腳本?
- 9. 從C#執行Shell腳本文件#
- 10. 如何從bash shell執行.py腳本
- 11. 如何從php/html執行shell腳本?
- 12. 如何從LaTeX執行shell腳本?
- 13. 如何從shell腳本在Linux上
- 14. 從shell腳本執行symbolicatecrash
- 15. 從shell執行R腳本
- 16. 從shell腳本執行SQL
- 17. 從mac執行Shell腳本
- 18. Linux Shell腳本代碼未執行?
- 19. 執行Linux shell腳本時出錯
- 20. Linux shell腳本執行掛起
- 21. 如何在Linux中執行python腳本?
- 22. 在shell腳本中執行php腳本?
- 23. 在SHELL腳本上執行C程序
- 24. 如何從linux shell中逐行運行R腳本?
- 25. 如何在linux shell腳本中使用##
- 26. 如何在Linux shell腳本中聲明?
- 27. 如何在C中執行bash shell腳本?
- 28. 執行shell腳本
- 29. 執行shell腳本
- 30. 我如何從一個Linux shell腳本
還值得注意的是fork()是相當便宜的,因爲內存是寫入時拷貝,並且一旦程序分叉就不會重複。 – Cercerilla 2010-09-17 15:33:26
我是fork/exec的忠實粉絲 - 它可以讓您避免不確定運行環境的環境。但是你可以直接在shell腳本上使用它嗎?正如你所說,通過使用exec,你「避免讓shell(/ bin/sh)爲你運行你的命令」;難道你不需要exec/bin/sh來運行一個shell腳本嗎? – 2010-09-17 16:33:43
@Tom Anderson:如果shell腳本爲有效用戶設置了執行權限並且有一個合適的shabang第一行列出了有效用戶也有權執行的文件,而且它本身不是某種腳本,那麼內核將會用腳本文件調用shabang行上列出的文件。如果腳本的shabang是'#!/ bin/csh',那麼'/ bin/sh'不會在fork/exec場景中運行。如果它是'#!/ bin/sh',那麼它將在fork/exec場景中運行,但是對於此腳本,使用'system'版本'/ bin/sh'將運行兩次。 – nategoose 2010-09-17 16:43:09