system 関数と同等の機能を有する関数(mysystem)の例です.
execlp(execvp,..)関数は引数に実行するコマンドとその引数を指定すると,そのコマンドを実行してくれますが,実行後,プログラムを終了してしまいます.そこで,そのコマンドを実行後も処理を続行したい場合には,fork により子プロセスを作成し,その子プロセス内にて execlp 等を実行します.execlp 関数の終了後,子プロセスが終了しても親プロセスで続けて処理を行うことができます.
execlp 関数では,通常のシェルで行うようなパイプやリダイレクション処理( | < > etc.)や正規表現(? * etc.)による複雑な処理を行うことができません.複雑な処理を行う場合にはシェルコマンド(/bin/sh etc.)を介してコマンドを実行します.
ex. execlp("/bin/sh","/bin/sh","-c","ls | wc > output.txt",NULL);
例題は,mysystem()関数の実行例とmysystem()関数の実行結果(exit status)により処理を分岐する例です.
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> int mysystem(char* cmd) { int child,status; if ((child = fork()) < 0) { perror("fork"); return EXIT_FAILURE; } if(child == 0){ execlp("/bin/sh","/bin/sh","-c",cmd,NULL); return EXIT_FAILURE; } else { if(wait(&status) < 0) { perror("wait"); exit(1); } } return status; } int main(int argc,char* argv[]) { int status; char cmd[256]; if(argc < 4) { printf("usage: %s \"test-rule\" \"true command\" \"false command\"\n",argv[0]); return 0; } printf("**test of mysystem\n"); mysystem("cat list_76.c | wc"); printf("**execute shell rule\n"); sprintf(cmd,"test %s;",argv[1]); status = mysystem(cmd); if(status) mysystem(argv[3]); else mysystem(argv[2]); return 0; } |
Gami[178]% ./list_76.exe usage: ./list_76.exe "test-rule" "true command" "false command" Gami[179]% ./list_76.exe "-f makefile" "head makefile" "ls" **test of mysystem 43 90 840 **execute shell rule --> true の実行[makefile が存在する] SRC = list_76 OBJS = $(SRC).o COMP = gcc FLAG = -lm -Wall LANG = c all: $(OBJS) $(COMP) -o $(SRC) $(OBJS) $(FLAG) ./$(SRC) Gami[180]% ./list_76.exe "-d folder" "head makefile" "ls -F" **test of mysystem 43 90 840 **execute shell rule --> false の実行[folder というフォルダが存在しない] makefile misc/ list_76.c list_76.exe* list_76.o Gami[181]% |