def fork_exec(cmd, exec_env=None, logfile=None, pass_fds=None):
 env = os.environ.copy()
 if (exec_env is not None):
  for (env_name, env_val) in exec_env.items():
   if callable(env_val):
    env[env_name] = env_val(env.get(env_name))
   else:
    env[env_name] = env_val
 pid = os.fork()
 if (pid == 0):
  if logfile:
   fds = [1, 2]
   with open(logfile, 'r+b') as fptr:
    for desc in fds:
     try:
      os.dup2(fptr.fileno(), desc)
     except OSError:
      pass
  if (pass_fds and hasattr(os, 'set_inheritable')):
   for fd in pass_fds:
    os.set_inheritable(fd, True)
  args = shlex.split(cmd)
  os.execvpe(args[0], args, env)
 else:
  return pid

def fork_exec ( cmd , exec_env = None , logfile = None , pass_fds = None ) : env = os . environ . copy ( ) if ( exec_env is not None ) : for ( env_name , env_val ) in exec_env . items ( ) : if callable ( env_val ) : env [ env_name ] = env_val ( env . get ( env_name ) ) else : env [ env_name ] = env_val pid = os . fork ( ) if ( pid == 0 ) : if logfile : fds = [ 1 , 2 ] with open ( logfile , 'r+b' ) as fptr : for desc in fds : try : os . dup2 ( fptr . fileno ( ) , desc ) except OSError : pass if ( pass_fds and hasattr ( os , 'set_inheritable' ) ) : for fd in pass_fds : os . set_inheritable ( fd , True ) args = shlex . split ( cmd ) os . execvpe ( args [ 0 ] , args , env ) else : return pid
execute a command using fork/exec .