shell.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. import os
  4. import sys
  5. import subprocess
  6. from Naked.settings import debug as DEBUG_FLAG
  7. #------------------------------------------------------------------------------
  8. # [ execute function ] (boolean)
  9. # run a shell command and print std out / std err to terminal
  10. # returns True if exit status = 0
  11. # returns False if exit status != 0
  12. #------------------------------------------------------------------------------
  13. def execute(command):
  14. try:
  15. response = subprocess.call(command, shell=True)
  16. if response == 0:
  17. return True
  18. else:
  19. return False
  20. except subprocess.CalledProcessError as cpe:
  21. try:
  22. sys.stderr.write(cpe.output)
  23. except TypeError as te:
  24. sys.stderr.write(str(cpe.output))
  25. except Exception as e:
  26. if DEBUG_FLAG:
  27. sys.stderr.write("Naked Framework Error: unable to run the shell command with the execute() function (Naked.toolshed.shell.py).")
  28. raise e
  29. #------------------------------------------------------------------------------
  30. # [ run function ] (bytes string or False)
  31. # run a shell command
  32. # default =
  33. # success:: print to std out and return the std out string
  34. # error:: print to stderr return False, suppress SystemExit on error to permit ongoing run of calling script
  35. # suppress_stdout = True >> suppress std output stream print (returns string)
  36. # suppress_stderr = True >> suppress std err stream print (returns False)
  37. # suppress_exit_status_call = False >> raise SystemExit with the returned status code
  38. #------------------------------------------------------------------------------
  39. def run(command, suppress_stdout=False, suppress_stderr=False, suppress_exit_status_call=True):
  40. try:
  41. response = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
  42. if not suppress_stdout:
  43. print(response)
  44. return response
  45. except subprocess.CalledProcessError as cpe:
  46. if not suppress_stderr: # error in existing application (non-zero exit status)
  47. try:
  48. sys.stderr.write(cpe.output)
  49. except TypeError as te: # deal with unusual errors from some system executables that return non string type through subprocess.check_output
  50. sys.stderr.write(str(cpe.output))
  51. if not suppress_exit_status_call:
  52. if cpe.returncode:
  53. sys.exit(cpe.returncode)
  54. else:
  55. sys.exit(1)
  56. return False # return False on non-zero exit status codes (i.e. failures in the subprocess executable)
  57. except Exception as e:
  58. if DEBUG_FLAG:
  59. sys.stderr.write("Naked Framework Error: unable to run the shell command with the run() function (Naked.toolshed.shell.py).")
  60. raise e
  61. #------------------------------------------------------------------------------
  62. # [ muterun function ] (NakedObject with attributes for stdout, stderr, exitcode)
  63. # run a shell command and return a response object
  64. # return object attributes : stdout (bytes), stderr (bytes), exitcode (int)
  65. #------------------------------------------------------------------------------
  66. def muterun(command):
  67. try:
  68. from Naked.toolshed.types import NakedObject
  69. response_obj = NakedObject()
  70. response = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
  71. response_obj.stdout = response
  72. response_obj.exitcode = 0
  73. response_obj.stderr = b""
  74. return response_obj
  75. except subprocess.CalledProcessError as cpe:
  76. response_obj.stdout = b""
  77. response_obj.stderr = cpe.output
  78. if cpe.returncode:
  79. response_obj.exitcode = cpe.returncode
  80. else:
  81. response_obj.exitcode = 1
  82. return response_obj
  83. except Exception as e:
  84. if DEBUG_FLAG:
  85. sys.stderr.write("Naked Framework Error: unable to run the shell command with the mute_run() function (Naked.toolshed.shell.py).")
  86. raise e
  87. #------------------------------------------------------------------------------
  88. # RUBY COMMAND EXECUTION
  89. #------------------------------------------------------------------------------
  90. #------------------------------------------------------------------------------
  91. # [ execute_rb function ] (boolean)
  92. # execute a ruby script file in a shell subprocess
  93. #------------------------------------------------------------------------------
  94. def execute_rb(file_path, arguments=""):
  95. try:
  96. if len(arguments) > 0:
  97. rb_command = 'ruby ' + file_path + " " + arguments
  98. else:
  99. rb_command = 'ruby ' + file_path
  100. return execute(rb_command) # return result of execute() of the ruby file
  101. except Exception as e:
  102. if DEBUG_FLAG:
  103. sys.stderr.write("Naked Framework Error: unable to run the shell command with the run_rb() function (Naked.toolshed.shell.py).")
  104. raise e
  105. #------------------------------------------------------------------------------
  106. # [ run_rb function ] (bytes string or False)
  107. # execute a ruby script file in a shell subprocess, return the output
  108. #------------------------------------------------------------------------------
  109. def run_rb(file_path, arguments="", suppress_stdout=False, suppress_stderr=False, suppress_exit_status_call=True):
  110. try:
  111. if len(arguments) > 0:
  112. rb_command = 'ruby ' + file_path + " " + arguments
  113. else:
  114. rb_command = 'ruby ' + file_path
  115. return run(rb_command, suppress_stdout, suppress_stderr, suppress_exit_status_call) # return result of run() of the ruby file
  116. except Exception as e:
  117. if DEBUG_FLAG:
  118. sys.stderr.write("Naked Framework Error: unable to run the shell command with the run_rb() function (Naked.toolshed.shell.py).")
  119. raise e
  120. #------------------------------------------------------------------------------
  121. # [ muterun_rb function ] (NakedObject response object)
  122. #------------------------------------------------------------------------------
  123. def muterun_rb(file_path, arguments=""):
  124. try:
  125. if len(arguments) > 0:
  126. rb_command = 'ruby ' + file_path + " " + arguments
  127. else:
  128. rb_command = 'ruby ' + file_path
  129. return muterun(rb_command) # return result of muterun() of the ruby file
  130. except Exception as e:
  131. if DEBUG_FLAG:
  132. sys.stderr.write("Naked Framework Error: unable to run the shell command with the muterun_rb() function (Naked.toolshed.shell.py).")
  133. raise e
  134. #------------------------------------------------------------------------------
  135. # NODE.JS COMMAND EXECUTION
  136. #------------------------------------------------------------------------------
  137. #------------------------------------------------------------------------------
  138. # [ execute_js function ] (boolean)
  139. # execute a node.js script file in a shell subprocess
  140. # stdout stream to terminal
  141. # returns True for success (=0) exit status code
  142. # returns False for unsuccessful (!=0) exit status code
  143. #------------------------------------------------------------------------------
  144. def execute_js(file_path, arguments=""):
  145. try:
  146. if len(arguments) > 0:
  147. js_command = 'node ' + file_path + " " + arguments
  148. else:
  149. js_command = 'node ' + file_path
  150. return execute(js_command) # return result of execute() of node.js file
  151. except Exception as e:
  152. if DEBUG_FLAG:
  153. sys.stderr.write("Naked Framework Error: unable to run the shell command with the run_js() function (Naked.toolshed.shell.py).")
  154. raise e
  155. #------------------------------------------------------------------------------
  156. # [ run_js function ] (byte string or False)
  157. # execute a node.js script file in a shell subprocess
  158. # print the standard output to the standard output stream by default
  159. # set suppress_output to True to suppress stream to standard output. String is still returned to calling function
  160. # set suppress_exit_status_call to True to suppress raising sys.exit on failures with shell subprocess exit status code (if available) or 1 if not available
  161. # returns the standard output byte string from the subprocess executable on success
  162. # returns False if the subprocess exits with a non-zero exit code
  163. #------------------------------------------------------------------------------
  164. def run_js(file_path, arguments="", suppress_stdout=False, suppress_stderr=False, suppress_exit_status_call=True):
  165. try:
  166. if len(arguments) > 0:
  167. js_command = 'node ' + file_path + " " + arguments
  168. else:
  169. js_command = 'node ' + file_path
  170. return run(js_command, suppress_stdout, suppress_stderr, suppress_exit_status_call) # return result of run() of node.js file
  171. except Exception as e:
  172. if DEBUG_FLAG:
  173. sys.stderr.write("Naked Framework Error: unable to run the shell command with the run_js() function (Naked.toolshed.shell.py).")
  174. raise e
  175. #------------------------------------------------------------------------------
  176. # [ muterun_js function ] (NakedObject response object)
  177. #------------------------------------------------------------------------------
  178. def muterun_js(file_path, arguments=""):
  179. try:
  180. if len(arguments) > 0:
  181. js_command = 'node ' + file_path + " " + arguments
  182. else:
  183. js_command = 'node ' + file_path
  184. return muterun(js_command) # return result of muterun() of node.js file
  185. except Exception as e:
  186. if DEBUG_FLAG:
  187. sys.stderr.write("Naked Framework Error: unable to run the shell command with the muterun_js() function (Naked.toolshed.shell.py).")
  188. raise e
  189. #------------------------------------------------------------------------------
  190. # [ Environment Class ]
  191. # shell environment variables class
  192. # self.env = the environment variable dictionary
  193. # self.vars = the environment variable names list
  194. #------------------------------------------------------------------------------
  195. class Environment():
  196. def __init__(self):
  197. self.env = os.environ
  198. self.vars = list(os.environ.keys())
  199. #------------------------------------------------------------------------------
  200. # [ is_var method ] (boolean)
  201. # return boolean for presence of a variable name in the shell environment
  202. #------------------------------------------------------------------------------
  203. def is_var(self, var_name):
  204. try:
  205. return (var_name in self.vars)
  206. except Exception as e:
  207. if DEBUG_FLAG:
  208. sys.stderr.write("Naked Framework Error: unable to determine if the variable is included in the shell variable list with the is_var() method (Naked.toolshed.shell).")
  209. raise e
  210. #------------------------------------------------------------------------------
  211. # [ get_var method ] (string)
  212. # get the variable value for a variable in the shell environment list
  213. # returns empty string if the variable is not included in the environment variable list
  214. #------------------------------------------------------------------------------
  215. def get_var(self, var_name):
  216. try:
  217. if var_name in self.vars:
  218. return self.env[var_name]
  219. else:
  220. return ""
  221. except Exception as e:
  222. if DEBUG_FLAG:
  223. sys.stderr.write("Naked Framework Error: unable to return the requested shell variable with the get_var() method (Naked.toolshed.shell).")
  224. raise e
  225. #------------------------------------------------------------------------------
  226. # [ get_split_var_list method ] (list of strings)
  227. # return a list of strings split by OS dependent separator from the shell variable assigment string
  228. # if the variable name is not in the environment list, returns an empty list
  229. #------------------------------------------------------------------------------
  230. def get_split_var_list(self, var_name):
  231. try:
  232. if var_name in self.vars:
  233. return self.env[var_name].split(os.pathsep)
  234. else:
  235. return []
  236. except Exception as e:
  237. if DEBUG_FLAG:
  238. sys.stderr.write("Naked Framework Error: unable to return environment variable list with the get_split_var_list() method (Naked.toolshed.shell).")
  239. raise e
  240. if __name__ == '__main__':
  241. pass
  242. # e = Environment()
  243. # pathlist = e.get_split_var_list("PATH")
  244. # for item in pathlist:
  245. # print(item)