summaryrefslogtreecommitdiff
path: root/azurelinuxagent/common/utils/shellutil.py
diff options
context:
space:
mode:
Diffstat (limited to 'azurelinuxagent/common/utils/shellutil.py')
-rw-r--r--azurelinuxagent/common/utils/shellutil.py107
1 files changed, 107 insertions, 0 deletions
diff --git a/azurelinuxagent/common/utils/shellutil.py b/azurelinuxagent/common/utils/shellutil.py
new file mode 100644
index 0000000..d273c92
--- /dev/null
+++ b/azurelinuxagent/common/utils/shellutil.py
@@ -0,0 +1,107 @@
+# Microsoft Azure Linux Agent
+#
+# Copyright 2014 Microsoft Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Requires Python 2.4+ and Openssl 1.0+
+#
+
+import platform
+import os
+import subprocess
+from azurelinuxagent.common.future import ustr
+import azurelinuxagent.common.logger as logger
+
+if not hasattr(subprocess,'check_output'):
+ def check_output(*popenargs, **kwargs):
+ r"""Backport from subprocess module from python 2.7"""
+ if 'stdout' in kwargs:
+ raise ValueError('stdout argument not allowed, '
+ 'it will be overridden.')
+ process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
+ output, unused_err = process.communicate()
+ retcode = process.poll()
+ if retcode:
+ cmd = kwargs.get("args")
+ if cmd is None:
+ cmd = popenargs[0]
+ raise subprocess.CalledProcessError(retcode, cmd, output=output)
+ return output
+
+ # Exception classes used by this module.
+ class CalledProcessError(Exception):
+ def __init__(self, returncode, cmd, output=None):
+ self.returncode = returncode
+ self.cmd = cmd
+ self.output = output
+ def __str__(self):
+ return ("Command '{0}' returned non-zero exit status {1}"
+ "").format(self.cmd, self.returncode)
+
+ subprocess.check_output=check_output
+ subprocess.CalledProcessError=CalledProcessError
+
+
+"""
+Shell command util functions
+"""
+def run(cmd, chk_err=True):
+ """
+ Calls run_get_output on 'cmd', returning only the return code.
+ If chk_err=True then errors will be reported in the log.
+ If chk_err=False then errors will be suppressed from the log.
+ """
+ retcode,out=run_get_output(cmd,chk_err)
+ return retcode
+
+def run_get_output(cmd, chk_err=True, log_cmd=True):
+ """
+ Wrapper for subprocess.check_output.
+ Execute 'cmd'. Returns return code and STDOUT, trapping expected exceptions.
+ Reports exceptions to Error if chk_err parameter is True
+ """
+ if log_cmd:
+ logger.verbose(u"run cmd '{0}'", cmd)
+ try:
+ output=subprocess.check_output(cmd,stderr=subprocess.STDOUT,shell=True)
+ output = ustr(output, encoding='utf-8', errors="backslashreplace")
+ except subprocess.CalledProcessError as e :
+ output = ustr(e.output, encoding='utf-8', errors="backslashreplace")
+ if chk_err:
+ if log_cmd:
+ logger.error(u"run cmd '{0}' failed", e.cmd)
+ logger.error(u"Error Code:{0}", e.returncode)
+ logger.error(u"Result:{0}", output)
+ return e.returncode, output
+ return 0, output
+
+
+def quote(word_list):
+ """
+ Quote a list or tuple of strings for Unix Shell as words, using the
+ byte-literal single quote.
+
+ The resulting string is safe for use with ``shell=True`` in ``subprocess``,
+ and in ``os.system``. ``assert shlex.split(ShellQuote(wordList)) == wordList``.
+
+ See POSIX.1:2013 Vol 3, Chap 2, Sec 2.2.2:
+ http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_02
+ """
+ if not isinstance(word_list, (tuple, list)):
+ word_list = (word_list,)
+
+ return " ".join(list("'{0}'".format(s.replace("'", "'\\''")) for s in word_list))
+
+
+# End shell command util functions