簡體   English   中英

調用shell腳本后返回主C程序

[英]Return to main C program after calling shell script

我在Raspberry-Pi上運行了一個C程序,該程序不斷從AVR讀取串行信息。 我想寫一個使用簡單的shell腳本接收到的命令的歷史記錄:

#!/bin/bash

echo "Command $2 received from address $1" 

date_time=$(date)                       #read current date from terminal
echo " $date_time Address: $1 Cmd: $2" >> file.txt      #echo address & command to file, redirect stdio

exit 0

當在終端中使用適當的參數調用該腳本時,該腳本可以完美運行,但是,我希望每次從串行線路讀取命令時都執行該腳本。 C程序當前讀取命令和地址並將其打印到標准io,因此我想做的是在此之后調用腳本,以將數據寫入文件。

當像這樣在我的代碼中調用腳本時:

    char* args[3];
char* program="ioExport.sh";
    args[1]=addr;
    args[2]=cmd;
    args[3]=NULL;
    execv(program,args);

它退出主程序。 調用腳本后如何返回主程序? 還是在將腳本作為后台進程運行時有辦法做到這一點? 我知道使用標准C文件I / O進行操作要簡單得多,但是如果可以使用Shell,我想這樣做:)

問候,哈科

exec函數家族用新進程替換了該進程。 它們僅在出現錯誤的情況下返回。

您似乎想要的是system函數,該函數為您創建一個shell進程,然后在自變量中執行命令。

順便說一句,您反正將argument數組設置為錯誤,請記住數組索引從零開始 另外, argument數組中的第一個條目應為程序名稱,這意味着您需要將argument[0]設置為program ,並且當然要將數組大小更改為4。


但是,正如trojanfoe所指出的那樣,除非收到消息時還需要運行一些其他特殊命令,否則根本不需要調用Shell腳本。如果您只想將一些日志記錄信息打印到文件中,則可以可以很容易地從程序內部完成:

/* First get the date and time string */
time_t now = time(NULL);
char *timestring = ctime(&now);

/* It contains a trailing newline, remove that by */
/* overwriting the newline with the string terminator */
timestring[strlen(timestring) - 1] = '\0';

/* Open the file for appending (i.e. writing at the end) */
FILE *file = fopen("file.txt", "a");

/* And write your message to your file */
fprintf(file, "%s Address: %s Cmd: %s\n", timestring, addr, cmd);

/* Close the file */
fclose(file);

將其放在單獨的函數中,可在需要時調用。 並請注意,如果您想向文件中寫入更多內容,則可以在程序開始時將其打開,直到退出該程序才將其關閉。

尤其如此頻繁地調用shell腳本會削弱程序的性能,因此請使用內置的日志記錄功能。 您可能需要更改logData()的語義,因為我不知道您的“命令”和“地址”采用什么形式。

logger.h:

#pragma once

#include <stdbool.h>

extern bool logOpen(const char *filename);
extern void logData(const char *command, const char *address);
extern void logClose();

logger.c:

#include "logger.h"
#include <stdio.h>
#include <sys/time.h>

static FILE *logfp = NULL;

bool logOpen(const char *filename) {
    logfp = fopen(filename, "w+");
    return logfp != NULL;
}

void logData(const char *command, const char *address) {
    struct timeval tv;
    struct tm tm;

    if (!logfp)
        return;

    gettimeofday(&tv, 0);
    localtime_r(&tv.tv_sec, &tm);

    fprintf(logfp, "%02d:%02d:%02d.%03u: command='%s' address='%s'\n",
        tm.tm_hour, tm.tm_min, tm.tm_sec, (unsigned)(tv.tv_usec / 1000),
        command, address);

}

void logClose() {
    if (logfp) {
        fclose(logfp);
        logfp = NULL;
    }
}

main.c中:

#include "logger.h"

int main(int argc, const char **argv) {

    logOpen("file.log");

    logData("Command 1", "Address 1");
    logData("Command 2", "Address 2");
    logData("Command 3", "Address 3");
    logData("Command 4", "Address 4");

    logClose();
    return 0;
}

編譯和測試:

$ clang -o test main.c logger.c
$ ./test
$ more file.log
13:40:08.399: command='Command 1' address='Address 1'
13:40:08.399: command='Command 2' address='Address 2'
13:40:08.399: command='Command 3' address='Address 3'
13:40:08.399: command='Command 4' address='Address 4'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM