get the text printed due to executing cmd command in c - c

I have a binary file which prints the result instead of returning the value, if I execute it using cmd I am getting printed text, I managed to execute it from C code but it seems like I can not get the text it usually prints to be stored in a variable I can use later for further decisions.
I do not have that much of experience in C and I googled a lot.
I came across the idea of using clip but my cmd is saying that clip command can not be found.
any help or ideas would be appreciated.

The correct function pair to use on POSIX systems is popen() and
pclose(). You can perhaps use Microsoft's _popen() and
_pclose() unless the warning 'This API cannot be used in applications that execute in the Windows Runtime' matters to you.
You would use it more or less like this. I've had to invent the name of the command you wish to execute since the question doesn't specify that. I chose ./example.exe as the name — and I'm assuming it needs no arguments.
char cmd[] = "./example.exe";
FILE *fp = popen(cmd, "r");
if (fp != NULL)
{
char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(buffer), sizeof(char), fp)) != 0)
{
…process nbytes of data…
…it is not a null-terminated string unless you add the null byte…
}
pclose(fp);
}
else
{
…report error for failure to execute command…
}

You can use the system function from <stdlib.h> to run the command you want. To get the command's output, you modify your command like in this question to save the command's output to a file. Then you can use the file I/O functions in <stdio.h> to process the command output.

In Linux, you may do command substitution and pass its result as arguments to the program, Something like this
./your_program "$(/path/to/your/binary/file)"
Suppose your main is
int main(int argc,char* argv[]){
.
.
return 0;
}
Acess the arguments like argv[1] and so.
Here the $(command) does the substitution and it passes the printed values from the binary as arguments to the pgm. Hope this helps.

Use snprintf function. For e.g.
snprintf(cmdbuff, BUFFER_LEN, "dmidecode --type 17 | grep -i Size | grep -o '\\<[0-9]*\\>' | paste -sd+ | bc");
Here cmdbuff is character array where command will be stored , BUFFER_LEN is a size of the character array
Then use popen and fgets to get the output of command into some buffer as shown below
if((fd = popen(cmdbuff,"r")) != NULL)
{
fgets(buffer, BUFFER_LEN, fd);
sprintf(vnfc_configured_memory, "%s", buffer);
vnfc_configured_totalRAM = atof(vnfc_configured_memory);
}

Related

how to echo std output exactly in C

I'm making essentially a terminal wrapper. I want my program to read from stdin, and for any inputs that come in, echo it EXACTLY the way it is, even if it's wrong.
Right now, I'm doing:
FILE *output = popen(buffer, "r");
memset(buffer, '\0', BUFF_SIZE * 2);
while (fgets(buffer, sizeof(buffer), output) != 0)
{
printf("%s", buffer);
memset(buffer, '\0', BUFF_SIZE * 2);
}
pclose(output);
}
where I'm calling shell commands using popen, but in certain situations, for example, when the command is not found, the output returned by using popen won't be exactly the same compared to when using the terminal without the wrapper. For example, if I input $ asd, linux terminal will return
No command 'asd' found, but there are 24 similar ones
asd: command not found
whereas popen will return:
sh: 1: asd not found
I would like to have the default terminal response rather than what popen returns, would this be possible? If so, how?

C Program - How to get the output of a shell command and compare it with a variable? [duplicate]

I've got a utility that outputs a list of files required by a game. How can I run that utility within a C program and grab its output so I can act on it within the same program?
UPDATE: Good call on the lack of information. The utility spits out a series of strings, and this is supposed to be portable across Mac/Windows/Linux. Please note, I'm looking for a programmatic way to execute the utility and retain its output (which goes to stdout).
As others have pointed out, popen() is the most standard way. And since no answer provided an example using this method, here it goes:
#include <stdio.h>
#define BUFSIZE 128
int parse_output(void) {
char *cmd = "ls -l";
char buf[BUFSIZE];
FILE *fp;
if ((fp = popen(cmd, "r")) == NULL) {
printf("Error opening pipe!\n");
return -1;
}
while (fgets(buf, BUFSIZE, fp) != NULL) {
// Do whatever you want here...
printf("OUTPUT: %s", buf);
}
if (pclose(fp)) {
printf("Command not found or exited with error status\n");
return -1;
}
return 0;
}
Sample output:
OUTPUT: total 16
OUTPUT: -rwxr-xr-x 1 14077 14077 8832 Oct 19 04:32 a.out
OUTPUT: -rw-r--r-- 1 14077 14077 1549 Oct 19 04:32 main.c
For simple problems in Unix-ish environments try popen().
From the man page:
The popen() function opens a process by creating a pipe, forking and invoking the shell.
If you use the read mode this is exactly what you asked for. I don't know if it is implemented in Windows.
For more complicated problems you want to look up inter-process communication.
popen is supported on Windows, see here:
http://msdn.microsoft.com/en-us/library/96ayss4b.aspx
If you want it to be cross-platform, popen is the way to go.
Well, assuming you're on a command line in a windows environment, you can use pipes or command line redirects. For instance,
commandThatOutputs.exe > someFileToStoreResults.txt
or
commandThatOutputs.exe | yourProgramToProcessInput.exe
Within your program, you could use the C standard input functions to read the other programs output (scanf, etc.): http://irc.essex.ac.uk/www.iota-six.co.uk/c/c1_standard_input_and_output.asp . You could also use the file example and use fscanf. This should also work in Unix/Linux.
This is a very generic question, you may want to include more details, like what type of output it is (just text, or a binary file?) and how you want to process it.
Edit: Hooray clarification!
Redirecting STDOUT looks to be troublesome, I've had to do it in .NET, and it gave me all sorts of headaches. It looks like the proper C way is to spawn a child process, get a file pointer, and all of a sudden my head hurts.
So heres a hack that uses temporary files. It's simple, but it should work. This will work well if speed isn't an issue (hitting the disk is slow), or if it's throw-away. If you're building an enterprise program, looking into the STDOUT redirection is probably best, using what other people recommended.
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char* argv[])
{
FILE * fptr; // file holder
char c; // char buffer
system("dir >> temp.txt"); // call dir and put it's contents in a temp using redirects.
fptr = fopen("temp.txt", "r"); // open said file for reading.
// oh, and check for fptr being NULL.
while(1){
c = fgetc(fptr);
if(c!= EOF)
printf("%c", c); // do what you need to.
else
break; // exit when you hit the end of the file.
}
fclose(fptr); // don't call this is fptr is NULL.
remove("temp.txt"); // clean up
getchar(); // stop so I can see if it worked.
}
Make sure to check your file permissions: right now this will simply throw the file in the same directory as an exe. You might want to look into using /tmp in nix, or C:\Users\username\Local Settings\Temp in Vista, or C:\Documents and Settings\username\Local Settings\Temp in 2K/XP. I think the /tmp will work in OSX, but I've never used one.
In Linux and OS X, popen() really is your best bet, as dmckee pointed out, since both OSs support that call. In Windows, this should help: http://msdn.microsoft.com/en-us/library/ms682499.aspx
MSDN documentation says
If used in a Windows program, the _popen function returns an invalid file pointer that causes the program to stop responding indefinitely. _popen works properly in a console application. To create a Windows application that redirects input and output, see Creating a Child Process with Redirected Input and Output in the Windows SDK.
You can use system() as in:
system("ls song > song.txt");
where ls is the command name for listing the contents of the folder song and song is a folder in the current directory. Resulting file song.txt will be created in the current directory.
//execute external process and read exactly binary or text output
//can read image from Zip file for example
string run(const char* cmd){
FILE* pipe = popen(cmd, "r");
if (!pipe) return "ERROR";
char buffer[262144];
string data;
string result;
int dist=0;
int size;
//TIME_START
while(!feof(pipe)) {
size=(int)fread(buffer,1,262144, pipe); //cout<<buffer<<" size="<<size<<endl;
data.resize(data.size()+size);
memcpy(&data[dist],buffer,size);
dist+=size;
}
//TIME_PRINT_
pclose(pipe);
return data;
}

How do I read file into a command line?

Basically what I want to do is have a program with int main(argc, *argv[]) and instead of writing chars into command line, I want to have my program read those words from a file. How could I accomplish this? Is there a special command in Linux for that?
You can use standard redirect operations in a *nix shell to pass files as input:
./myprogram < inputfile.txt
This statement executes your program (myprogram) and pumps the data inside of inputfile.txt to your program
You can also redirect the output of program to a file in a similar fashion:
./myprogram > outputfile.txt
Instead of doing
for(int i = 1; i < argc; i++)
{
insert(&trie, argv[i]);
}
you could doing something like
FILE *input;
char *line;
....
while (fscanf(input, "%ms", &line) != EOF) {
insert(&trie, line);
/* If you make a copy of line in `insert()`, you should
* free `line` at here; if you do not, free it later. */
free(line);
}
Use redirection
yourprogram < youtextfile
will offer the content of yourtextfile as standard input (stdin) to yourprogram. Likewise
yourprogram > yourothertextfile
will send everything the program writes to standard output (stdout) to yourothertextfile
You'll notice when reading man pages that most system calls have a version that works directly with stdin or stdout
For example consider the printf family:
printf ("hello world\n");
is a shorter version of
fprintf (stdout,"hello world\n");
and the same goes for scanf and stdin.
This is only the most basic usage of redirection, which in my opinion is one of the key aspects of "the unix way of doing things". As such, you'll find lots of articles and tutorials that show examples that are a lot more advanced than what I wrote here. Have a look at this Linux Documentation Project page on redirection to get started.
EDIT: getting fed input via redirection ior interactively "looks" the same to the program, so it will react the same to redirected input as it does to console input. This means that if your program expects data line-wise (eg because it uses gets() to read lines), the input text file should be organized in lines.
By default, every program you execute on POSIX-compliant systems has three file descriptors open (see <unistd.h> for the macros' definition): the standard input (STDOUT_FILENO), the standard output (STDOUT_FILENO), and the error output (STDERR_FILENO), which is tied to the console.
Since you said you want read lines, I believe the ssize_t getline(char **lineptr, size_t *n, FILE *stream) function can do the job. It takes a stream (FILE pointer) as a third argument, so you must either use fopen(3) to open a file, or a combination of open(2) and fdopen(3).
Getting inspiration from man 3 getline, here is a program demonstrating what you want:
#define _GNU_SOURCE
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
size_t len;
char *line;
ssize_t bytes_read;
len = 0;
line = NULL;
if (argc > 1)
{
fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror(*argv);
exit(EXIT_FAILURE);
}
}
else
fp = stdin;
while ((bytes_read = getline(&line, &len, fp)) != -1)
printf("[%2zi] %s", bytes_read, line);
free(line);
exit(EXIT_SUCCESS);
}
Without arguments, this program reads lines from the standard input: you can either feed it lines like echo "This is a line of 31 characters" | ./a.out or execute it directly and write your input from there (finish with ^D).
With a file as an argument, it will output every line from the file, and then exit.
You can have your executable read its arguments on the command line and use xargs, the special Linux command for passing the contents of a file to a command as arguments.
An alternative to xargs is parallel.

output redirection in Unix and C

I am trying to run a script inside my C program using system() command. Inside main(), I run the script and it returns the results. How can I put the result of the script in some string and check for conditions? I know I can do it with files but was wondering if its possible to put the result into a string.
Sample would be like:
main()
{
system("my_script_sh"); // How can I get the result of the my_script_sh
}
You can't use the system command for that. The best thing to do is use popen:
FILE *stream;
char buffer[150];
stream = popen("ls", "r");
while ( fgets(buffer, 150, stream) != NULL ){
// Copy the buffer to your output string etc.
}
pclose(stream);
Use popen() and read the stream into a char * buffer.
Well the easiest thing to do would be to take system("my_script_sh") out of your program and invoke the program from the shell with a pipe -- e.g.: my_script_sh | ./your_c_program and then your C program just reads from stdin (file descriptor 0).
If that is not possible, then have a look at man 3 popen. Basically, you use popen instead of system and it gives you a file handle that you can read from to get the output of the program.
Here are a few links that might be useful:
http://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html
http://www.crasseux.com/books/ctutorial/Programming-with-pipes.html
http://www.metalshell.com/source_code/23/Popen.html
http://tldp.org/LDP/lpg/node12.html

How Do I Pipe a String Into a popen() Command in C?

Im working in c (more or less for the first time) for uni, and I need to generate an MD5 from a character array. The assignment specifies that this must be done by creating a pipe and executing the md5 command on the system.
I've gotten this far:
FILE *in;
extern FILE * popen();
char buff[512];
/* popen creates a pipe so we can read the output
* of the program we are invoking */
char command[260] = "md5 ";
strcat(command, (char*) file->name);
if (!(in = popen(command, "r"))) {
printf("ERROR: failed to open pipe\n");
end(EXIT_FAILURE);
}
Now this works perfectly (for another part of the assignment which needs to get the MD5 for a file) but I cant workout how to pipe a string into it.
If I understand correctly, I need to do something like:
FILE * file = popen("/bin/cat", "w");
fwrite("hello", 5, file);
pclose(file);
Which, I think, would execute cat, and pass "hello" into it through StdIn. Is this right?
If you need to get a string into the md5 program, then you need to know what options your md5 program works with.
If it takes a string explicitly on the command line, then use that:
md5 -s 'string to be hashed'
If it takes standard input if no file name is given on the command line, then use:
echo 'string to be hashed' | md5
If it absolutely insists on a file name and your system supports /dev/stdin or /dev/fd/0, then use:
echo 'string to be hashed' | md5 /dev/stdin
If none of the above apply, then you will have to create a file on disk, run md5 on it, and then remove the file afterwards:
echo 'string to be hashed' > file.$$; md5 file.$$; rm -f file.$$
See my comment above:
FILE* file = popen("/sbin/md5","w");
fwrite("test", sizeof(char), 4, file);
pclose(file);
produces an md5 sum
Try this:
static char command[256];
snprintf(command, 256, "md5 -qs '%s'", "your string goes here");
FILE* md5 = popen(md5, "r");
static char result[256];
if (fgets(result, 256, md5)) {
// got it
}
If you really want to write it to md5's stdin, and then read from md5's stdout, you're probably going to want to look around for an implementation of popen2(...). That's not normally in the C library though.

Resources