1 | import platform |
||
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||
2 | from contextlib import contextmanager |
||
3 | from subprocess import PIPE, Popen |
||
4 | |||
5 | from coalib.parsing.StringProcessing import escape |
||
6 | |||
7 | |||
8 | @contextmanager |
||
9 | def run_interactive_shell_command(command, **kwargs): |
||
10 | """ |
||
11 | Runs a command in shell and provides stdout, stderr and stdin streams. |
||
12 | |||
13 | This function creates a context manager that sets up the process, returns |
||
14 | to caller, closes streams and waits for process to exit on leaving. |
||
15 | |||
16 | The process is opened in `universal_newlines` mode. |
||
17 | |||
18 | :param command: The command to run on shell. |
||
19 | :param kwargs: Additional keyword arguments to pass to `subprocess.Popen` |
||
20 | that is used to spawn the process (except `shell`, |
||
21 | `stdout`, `stderr`, `stdin` and `universal_newlines`, a |
||
22 | `TypeError` is raised then). |
||
23 | :return: A context manager yielding the process started from the |
||
24 | command. |
||
25 | """ |
||
26 | process = Popen(command, |
||
27 | shell=True, |
||
28 | stdout=PIPE, |
||
29 | stderr=PIPE, |
||
30 | stdin=PIPE, |
||
31 | universal_newlines=True, |
||
32 | **kwargs) |
||
33 | try: |
||
34 | yield process |
||
35 | finally: |
||
36 | process.stdout.close() |
||
37 | process.stderr.close() |
||
38 | process.stdin.close() |
||
39 | process.wait() |
||
40 | |||
41 | |||
42 | def run_shell_command(command, stdin=None, **kwargs): |
||
43 | """ |
||
44 | Runs a command in shell and returns the read stdout and stderr data. |
||
45 | |||
46 | This function waits for the process to exit. |
||
47 | |||
48 | :param command: The command to run on shell. |
||
49 | :param stdin: Initial input to send to the process. |
||
50 | :param kwargs: Additional keyword arguments to pass to `subprocess.Popen` |
||
51 | that is used to spawn the process (except `shell`, |
||
52 | `stdout`, `stderr`, `stdin` and `universal_newlines`, a |
||
53 | `TypeError` is raised then). |
||
54 | :return: A tuple with `(stdoutstring, stderrstring)`. |
||
55 | """ |
||
56 | with run_interactive_shell_command(command, **kwargs) as p: |
||
57 | ret = p.communicate(stdin) |
||
58 | return ret |
||
59 | |||
60 | |||
61 | def get_shell_type(): # pragma: no cover |
||
62 | """ |
||
63 | Finds the current shell type based on the outputs of common pre-defined |
||
64 | variables in them. This is useful to identify which sort of escaping |
||
65 | is required for strings. |
||
66 | |||
67 | :return: The shell type. This can be either "powershell" if Windows |
||
68 | Powershell is detected, "cmd" if command prompt is been |
||
69 | detected or "sh" if it's neither of these. |
||
70 | """ |
||
71 | out_hostname, _ = run_shell_command(["echo", "$host.name"]) |
||
72 | if out_hostname.strip() == "ConsoleHost": |
||
73 | return "powershell" |
||
74 | out_0, _ = run_shell_command(["echo", "$0"]) |
||
75 | if out_0.strip() == "" and out_0.strip() == "": |
||
76 | return "cmd" |
||
77 | return "sh" |
||
78 | |||
79 | |||
80 | def prepare_string_argument(string, shell=get_shell_type()): |
||
81 | """ |
||
82 | Prepares a string argument for being passed as a parameter on shell. |
||
83 | |||
84 | On `sh` this function effectively encloses the given string |
||
85 | with quotes (either '' or "", depending on content). |
||
86 | |||
87 | :param string: The string to prepare for shell. |
||
88 | :param shell: The shell platform to prepare string argument for. |
||
89 | If it is not "sh" they will be ignored and return the |
||
90 | given string without modification. |
||
91 | :return: The shell-prepared string. |
||
92 | """ |
||
93 | if shell == "sh": |
||
94 | return '"' + escape(string, '"') + '"' |
||
95 | else: |
||
96 | return string |
||
97 | |||
98 | |||
99 | def escape_path_argument(path, shell=get_shell_type()): |
||
100 | """ |
||
101 | Makes a raw path ready for using as parameter in a shell command (escapes |
||
102 | illegal characters, surrounds with quotes etc.). |
||
103 | |||
104 | :param path: The path to make ready for shell. |
||
105 | :param shell: The shell platform to escape the path argument for. Possible |
||
106 | values are "sh", "powershell", and "cmd" (others will be |
||
107 | ignored and return the given path without modification). |
||
108 | :return: The escaped path argument. |
||
109 | """ |
||
110 | if shell == "cmd": |
||
111 | # If a quote (") occurs in path (which is illegal for NTFS file |
||
112 | # systems, but maybe for others), escape it by preceding it with |
||
113 | # a caret (^). |
||
114 | return '"' + escape(path, '"', '^') + '"' |
||
115 | elif shell == "sh": |
||
116 | return escape(path, " ") |
||
117 | else: |
||
118 | # Any other non-supported system doesn't get a path escape. |
||
119 | return path |
||
120 |