我在我的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,我想这样做:)
此致 雅科
答案 0 :(得分:3)
exec
函数系列用新进程替换进程。它们仅在发生错误时才返回。
你似乎想要的是system
函数,它为你创建一个shell进程,然后在参数中执行命令。
顺便说一下,无论如何都要设置argument
数组错误,请记住数组索引以 0 开头。此外,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);
将它放在一个单独的功能中,您可以随时调用。请注意,如果您想要为文件写更多内容,那么您可以在程序开头打开它,而不是在退出程序之前关闭它。
答案 1 :(得分:1)
调用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'