c語言開源shell,c語言開源項目推薦

本文目錄一覽:

如何在C語言中調用shell命令

在linux操作系統中,很多shell命令使用起來非常簡單,這些shell命令的程序實現已經被底層實現好。有時候需要在程序中調用shell命令,這樣可以就不用在控制台上手動輸入shell命令了,下面就以三個函數為例來講解如何在C語言中調用shell命令。

1、system(執行shell 命令)

相關函數 fork,execve,waitpid,popen

表頭文件 #includestdlib.h

定義函數 int system(const char * string);

函數說明 system()會調用fork()產生子進程,由子進程來調用/bin/sh-c

string來執行參數string字元串所代表的命令,此命令執行完後隨

即返回原調用的進程。在調用system()期間SIGCHLD 信號會被暫時

擱置,SIGINT和SIGQUIT 信號則會被忽略。

返回值 如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-

1。若參數string為空指針(NULL),則返回非零值。如果system()調

用成功則最後會返回執行shell命令後的返回值,但是此返回值也有

可能為system()調用/bin/sh失敗所返回的127,因此最好能再檢查

errno 來確認執行成功。

附加說明 在編寫具有SUID/SGID許可權的程序時請勿使用system(),system()會

繼承環境變數,通過環境變數可能會造成系統安全的問題。

範例:

#includestdlib.h

main()

{

system(「ls -al /etc/passwd /etc/shadow」);

}

2、popen(建立管道I/O)

相關函數 pipe,mkfifo,pclose,fork,system,fopen

表頭文件 #includestdio.h

定義函數 FILE * popen( const char * command,const char * type);

函數說明 popen()會調用fork()產生子進程,然後從子進程中調用/bin/sh -c

來執行參數command的指令。參數type可使用「r」代表讀取,「w」

代表寫入。

如何在C語言中執行shell命令

在c語言中調用shell命令的方法實現。

c程序調用shell腳本共有兩種方法

:system()、popen(),分別如下:

system()

不用自己去創建進程,系統已經封裝了這一步,直接加入自己的命令即可

popen()

也可以實現執行的命令,比system

開銷小

以下分別說明:

1)system(shell命令或shell腳本路徑);

system()

會調用fork()產生

子歷程,由子歷程來調用/bin/sh-c

string來履行

參數string字元串所代表的命令,此命令履行

完後隨即返回原調用的歷程。在調用system()期間sigchld

信號會被暫時擱置,sigint和sigquit

信號則會被漠視

回值:如果system()在調用/bin/sh時失敗則返回127,其他失敗原因返回-1。若參數string為空指針(null),則返回非零值。

如果

system()調用成功

則最後會返回履行

shell命令後的返回值,但是此返回值也有可能為system()調用/bin/sh失敗所返回的127,因

此最好能再反省

errno

來確認履行

成功

system命令以其簡略

高效的作用得到很很廣泛

的利用

,下面是一個例子

例:在/tmp/testdir/目錄下有shell腳本tsh.sh,內容為

#!/bin/sh

wget

$1

echo

“done!”

2)popen(char

*command,char

*type)

popen()

會調用fork()產生

子歷程,然後從子歷程中調用/bin/sh

-c來履行

參數command的指令。參數type可應用

「r」代表讀取,「w」代表寫入。遵循此type值,popen()會建立

管道連到子歷程的標準

輸出設備

或標準

輸入設備

,然後返回一個文件指針。隨後歷程便可利用

此文件指針來讀取子歷程的輸出設備

或是寫入到子歷程的標準

輸入設備

中。此外,所有應用

件指針(file*)操作的函數也都可以應用

,除了fclose()以外。

返回值:若成功

則返迴文件指針,否則返回null,差錯

原因存於errno中。注意:在編寫具suid/sgid許可權的程序時請盡量避免應用

popen(),popen()會繼承環境變數,通過環境變數可能會造成系統安全的問題。

例:c程序popentest.c內容如下:

#include

main

{

file

*

fp;

charbuffer[80];

fp=popen(「~/myprogram/test.sh」,」r」);

fgets(buffer,sizeof(buffer),fp);

printf(「%s」,buffer);

pclose(fp);

}

如何用c語言寫一個shell

鳥哥是不會有這個的,可以這樣想(感覺這樣很麻煩,只用一對管道應該也可以,流程也能簡單,控制好進程順序就行。這個編得過):

#include stdio.h

#include stdlib.h

#include string.h

#include fcntl.h

#include unistd.h

#include sys/wait.h

#define CMD_LINE 1024

#define PIPE_MAX 16

#define ARG_MAX 10

typedef struct {

char *arg[ARG_MAX];

char *in;

char *out;

} cmd_t;

extern int parse_token(char *buf, cmd_t cmd[]);

extern int parse(char *buf, cmd_t * cmd);

extern int test_parse(cmd_t cmd[], int len);

int main(int argc, char *argv[])

{

char buf[CMD_LINE];

cmd_t cmd[PIPE_MAX + 1];

int fd[PIPE_MAX][2];

int j, i;

int cmd_len, pipe_len;

pid_t pid;

while (1) {

printf(“my_shell#”);

fgets(buf, CMD_LINE, stdin);

buf[strlen(buf) – 1] = ‘\0’;

cmd_len = parse_token(buf, cmd);

pipe_len = cmd_len – 1;

if (pipe_len PIPE_MAX)

continue;

for (i = 0; i pipe_len; ++i)

pipe(fd[i]);

for (i = 0; i cmd_len; ++i)

if ((pid = fork()) == 0)

break;

if (pid == 0) {

if (pipe_len) {

if (i == 0) {

close(fd[i][0]);

dup2(fd[i][1], 1);

close(fd[i][1]);

for (j = 1; j pipe_len; ++j)

close(fd[j][0]),

close(fd[j][1]);

} else if (i == pipe_len) {

close(fd[i – 1][1]);

dup2(fd[i – 1][0], 0);

close(fd[i – 1][0]);

for (j = 0; j pipe_len – 1; ++j)

close(fd[j][0]),

close(fd[j][1]);

} else {

dup2(fd[i – 1][0], 0);

close(fd[i][0]);

dup2(fd[i][1], 1);

close(fd[i][1]);

for (j = 0; j pipe_len; ++j) {

if ((j != i – 1)

|| (j != i))

close(fd[j][0]),

close(fd[j]

[1]);

}

}

}

if (cmd[i].in) {

int fd = open(cmd[i].in, O_RDONLY);

dup2(fd, STDIN_FILENO);

close(fd);

}

if (cmd[i].out) {

int fd =

open(cmd[i].out,

O_RDWR | O_CREAT | O_TRUNC, 0644);

dup2(fd, STDOUT_FILENO);

close(fd);

}

execvp(cmd[i].arg[0], cmd[i].arg);

fprintf(stderr, “Failed exec\n”);

exit(127);

}

/* parent */

for (i = 0; i pipe_len; ++i)

close(fd[i][0]), close(fd[i][1]);

for (i = 0; i cmd_len; ++i)

wait(NULL);

}

return 0;

}

int parse_token(char *buf, cmd_t cmd[])

{

int n = 0;

#if 1

char *save_p;

char *p = strtok_r(buf, “|”, save_p);

while (p != NULL) {

parse(p, cmd[n++]);

p = strtok_r(NULL, “|”, save_p);

}

#else

cmd[n].arg[0] = “ls”;

cmd[n].arg[1] = “-l”;

cmd[n].arg[2] = NULL;

#endif

return n;

}

int test_parse(cmd_t cmd[], int len)

{

int i;

for (i = 0; i len; ++i) {

printf(“cmd[%d]:”, i);

int j = 0;

while (cmd[i].arg[j])

printf(” %s”, cmd[i].arg[j++]);

if (cmd[i].in)

printf(“\tin:%s”, cmd[i].in);

if (cmd[i].out)

printf(“\tout:%s”, cmd[i].out);

printf(“\n”);

}

return 0;

}

int parse(char *buf, cmd_t * cmd)

{

int i = 0;

cmd-in = NULL;

cmd-out = NULL;

char *p = strtok(buf, ” “);

while (p) {

if (*p == ”) {

if (*(p + 1))

cmd-in = p + 1;

else

cmd-in = strtok(NULL, ” “);

} else if (*p == ”) {

if (*(p + 1))

cmd-out = p + 1;

else

cmd-out = strtok(NULL, ” “);

} else

cmd-arg[i++] = p;

p = strtok(NULL, ” “);

}

cmd-arg[i] = NULL;

return 0;

}

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/245548.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-12 13:09
下一篇 2024-12-12 13:09

相關推薦

  • 掌握magic-api item.import,為你的項目注入靈魂

    你是否曾經想要導入一個模塊,但卻不知道如何實現?又或者,你是否在使用magic-api時遇到了無法導入的問題?那麼,你來到了正確的地方。在本文中,我們將詳細闡述magic-api的…

    編程 2025-04-29
  • AES加密解密演算法的C語言實現

    AES(Advanced Encryption Standard)是一種對稱加密演算法,可用於對數據進行加密和解密。在本篇文章中,我們將介紹C語言中如何實現AES演算法,並對實現過程進…

    編程 2025-04-29
  • 學習Python對學習C語言有幫助嗎?

    Python和C語言是兩種非常受歡迎的編程語言,在程序開發中都扮演著非常重要的角色。那麼,學習Python對學習C語言有幫助嗎?答案是肯定的。在本文中,我們將從多個角度探討Pyth…

    編程 2025-04-29
  • Python被稱為膠水語言

    Python作為一種跨平台的解釋性高級語言,最大的特點是被稱為”膠水語言”。 一、簡單易學 Python的語法簡單易學,更加人性化,這使得它成為了初學者的入…

    編程 2025-04-29
  • Shell腳本與Python腳本的區別

    本文將從多個方面對Shell腳本與Python腳本的區別做詳細的闡述。 一、語法差異 Shell腳本和Python腳本的語法存在明顯差異。 Shell腳本是一種基於字元命令行的語言…

    編程 2025-04-29
  • OpenJudge答案1.6的C語言實現

    本文將從多個方面詳細闡述OpenJudge答案1.6在C語言中的實現方法,幫助初學者更好地學習和理解。 一、需求概述 OpenJudge答案1.6的要求是,輸入兩個整數a和b,輸出…

    編程 2025-04-29
  • Python按位運算符和C語言

    本文將從多個方面詳細闡述Python按位運算符和C語言的相關內容,並給出相應的代碼示例。 一、概述 Python是一種動態的、面向對象的編程語言,其按位運算符是用於按位操作的運算符…

    編程 2025-04-29
  • SDN開源組織中ONOS起步最早

    ONOS是一個開源軟體定義網路(SDN)操作系統,由ON.Lab創建並一直在開發。該平台旨在通過使用網路虛擬化技術使工程師能夠快速靈活地創建和管理網路服務。 一、ONOS的優勢 在…

    編程 2025-04-29
  • Python語言由荷蘭人為中心的全能編程開發工程師

    Python語言是一種高級語言,很多編程開發工程師都喜歡使用Python語言進行開發。Python語言的創始人是荷蘭人Guido van Rossum,他在1989年聖誕節期間開始…

    編程 2025-04-28
  • 如何將Java項目分成Modules並使用Git進行版本控制

    本文將向您展示如何將Java項目分成模塊,並使用Git對它們進行版本控制。分割Java項目可以使其更容易維護和拓展。Git版本控制還可以讓您跟蹤項目的發展並協作開發。 一、為什麼要…

    編程 2025-04-28

發表回復

登錄後才能評論