Fork and Execvp Not Executing Bash Commands From C correctly.


 
Thread Tools Search this Thread
Top Forums Programming Fork and Execvp Not Executing Bash Commands From C correctly.
# 1  
Old 03-18-2016
Fork and Execvp Not Executing Bash Commands From C correctly.

I had been looking at page 75 of this online book:
http://richard.esplins.org/static/do...linux_book.pdf

I've used the system function in C to call bash commands before, but wanted to learn this way too. The solution in the book worked perfectly. However, I tried changing the simple "ls -l /" they used to this one-liner:

Code:
lsof 2>&1 | grep log | awk '/openbox/ { print $10 }' | sed '1d'

If you're using a red hat based system instead of debian, you'll probably have to change the $10 to $9 in the above.

However, I'm getting the following errors:
Code:
# ./cbash2              
Done with main program.
pyro# lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
lsof: status error on 2>&1: No such file or directory
lsof: status error on |: No such file or directory
lsof: status error on grep: No such file or directory
lsof: status error on log: No such file or directory
lsof: status error on |: No such file or directory
lsof: status error on awk: No such file or directory
lsof: status error on '/openbox: No such file or directory
lsof: status error on { print $10 }': No such file or directory
lsof: status error on |: No such file or directory
lsof: status error on sed: No such file or directory
lsof: status error on '1d': No such file or directory
lsof 4.86
 latest revision: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/
 latest FAQ: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/FAQ
 latest man page: ftp://lsof.itap.purdue.edu/pub/tools/unix/lsof/lsof_man
 usage: [-?abhKlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
 [-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [--] [names]

Here is the code I'm working with now:

Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

// Spawn a child process for the bash part later:
int spawn(char* program, char** arg_list)
{
  pid_t child_pid;

  // Duplicate this process:
  child_pid = fork();
  if (child_pid !=0)
    // This is the parent process.
    return child_pid;
  else {
    // Execute "program" which will call bash:
    execvp (program, arg_list);
    // execvp will only return if an error occurs
    fprintf (stderr, "an error occurred in execvp\n");
    abort();
  }
}

int main()
{
  //Argument list to pass bash commands:
  char* arg_list[] = {
     "lsof",    // argv[0], the name of the program.
     "2>&1",
     "|",
     "grep",
     "log",
     "|",
     "awk",
     "'/openbox/",
     "{ print $10 }'",
     "|",
     "sed",
     "'1d'",
     NULL       // Arg list must end with a null.
  };

  // Spawn the child process running bash.
  spawn("lsof", arg_list);

  printf("Done with main program.\n");

  return 0;
}

Any advice much appreciated!
# 2  
Old 03-19-2016
First, note that you can cut a couple of processes out of your pipe line by using:
Code:
lsof 2>&1 | awk '/log/ && /openbox/ && c++ { print $10 }'

instead of:
Code:
lsof 2>&1 | grep log | awk '/openbox/ { print $10 }' | sed '1d'

Then a few comments about your C code:
  1. The fork() function returns 0 in the child (if a child is created successfully) and returns the PID of the child in the parent (if a child is created successfully), or returns -1 in the parent (if a child could not be created). Your code assumes that fork() never fails! Don't make that assumption.
  2. Operands like 2>&1, |, and grep are shell directives; not operands to be passed to the lsof utility.
  3. Instead of executing lsof, you probably need to execute sh with arguments -c and lsof 2>&1 | awk '/log/ && /openbox/ && c++ { print $10 }'.
This User Gave Thanks to Don Cragun For This Post:
# 3  
Old 03-19-2016
To expand on what Don Cragun already said:

A commandline like

Code:
command1 | command2

is not "a process" but in fact the shell creates two such processes: one for "command1", one for "command2". You need to execute the procedure of using execvp() or fork() for both of them because both are processes in their own right. Only then you need a provision for the pipeline functionality.

A (shell-) pipeline is to connect STDOUT of the one process to the STDIN of the other. But this means there are already two process-environments with such file descriptors that can be connected. Here is a thread that might give you the picture: Trouble with pipes in chat client on linux.

I hope that helps.

bakunin
This User Gave Thanks to bakunin For This Post:
# 4  
Old 03-19-2016
Thank you both! Its working now and the awk one-liner Don Cragun suggest is much cleaner. Thanks again!
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Executing bash file with sudo for the second time, leads to permission denied, for some commands

I have a script that checks if the script has been ran with sudo. If the script is not ran as sudo, the current script is being executed with exec sudo bash. You are asked for a password, you type in the password, success. Everything is perfect - the commands inside the script are ran as sudo.... (1 Reply)
Discussion started by: boqsc
1 Replies

2. UNIX for Dummies Questions & Answers

Bash does not wrap long lines correctly

Ksh is my default shell, but I want use the bash shell since its convenient to me. When I type a long command line in a terminal, it does not wrap to the next line when I reach the end of the line and it wraps onto the same line, overwriting my prompt and the rest of what I typed. $... (5 Replies)
Discussion started by: senthil.ak
5 Replies

3. Shell Programming and Scripting

OSX, bash, cat with <<MARKER executing commands

I have a script that writes another script with cat >/usr/local/bin/myscript.sh <<EOF #!/bin/sh VAR=`run a command here` EOF Problem is, after this is run, I get: $ cat /usr/local/bin/myscript.sh #!/bin/sh VAR=result of command How do I stop that from happening with Macs... (2 Replies)
Discussion started by: jnojr
2 Replies

4. Programming

If I malloc my parameters, then fork and execvp, where do I free them?

Hi, I do the following: i) malloc some parameter structures ii) fork iii) in the child, I call execvp using these parameters obviously, here I can never free() the structures as execvp should not return iiii) I am currently doing waitpid in parent then freeing, but this does not seem to work... (1 Reply)
Discussion started by: misha680
1 Replies

5. Shell Programming and Scripting

Executing many commands at once

Hi, I want to run these two commands one after the other. awk 'BEGIN {OFS="\t"} {print $2}' sort -u rather than typing awk 'BEGIN {OFS="\t"} {print $2}' file1 > file2, then sort -u file2 > file3. Is it possible to run both commands on file1 then get output file3? Its kinda hard for... (5 Replies)
Discussion started by: kylle345
5 Replies

6. Red Hat

How commands are executing ?

Hi Folks, I have a small doubt, the binary commands under /bin and /sbin as well as other path binary files, if you peek deep into that, you can find the difference in the way of normal perl programming and some commands will be like binary files. how are the commands executing like the... (3 Replies)
Discussion started by: gsiva
3 Replies

7. Shell Programming and Scripting

Can BASH execute commands on a remote server when the commands are embedded in shell

I want to log into a remote server transfer over a new config and then backup the existing config, replace with the new config. I am not sure if I can do this with BASH scripting. I have set up password less login by adding my public key to authorized_keys file, it works. I am a little... (1 Reply)
Discussion started by: bash_in_my_head
1 Replies

8. Shell Programming and Scripting

How to get BASH to interpret pipes in a string correctly?

In a BASH library I'm creating, I have two functions that look like: function check_process { PIDFILE=$1 if ; then PID=`cat $PIDFILE` if && ; then return 1 fi; fi; return 0 } function fork_process { CMD=$1 PIDFILE=$2 ... (2 Replies)
Discussion started by: neked
2 Replies

9. Programming

after executing execvp()... program hangs up

Hi , I m actually trying to implement pipes program,but after executing the execvp(),my program is getting hanged up :mad: Actaully i m getting the desired output expected from execvp()...but once results are displayed on the output screen ,program is getting hanged up values of... (3 Replies)
Discussion started by: Crab
3 Replies

10. Shell Programming and Scripting

bash: executing commands and reading exit vals

I have a function that returns a bunch of exit codes, say func1, and in my code I'm trying to execute that function in an if statement. This is the closest I could get. f1call=`func1 $arg1 $arg2` if ]; then ... fi When I run the script the function never gets called. What's the right way... (7 Replies)
Discussion started by: eur0dad
7 Replies
Login or Register to Ask a Question