-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArcGIS_Shell.pyt
More file actions
120 lines (94 loc) · 3.09 KB
/
Copy pathArcGIS_Shell.pyt
File metadata and controls
120 lines (94 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import arcpy
import locale
import os
import subprocess
class Toolbox(object):
def __init__(self):
self.label = "ArcGIS_Shell"
self.alias = "ArcGIS_Shell"
self.tools = [Shell]
class Shell(object):
def __init__(self):
self.label = "Shell"
self.description = (
"Runs a shell command and returns its output."
)
self.canRunInBackground = False
def getParameterInfo(self):
command = arcpy.Parameter(
displayName="Command",
name="command",
datatype="GPString",
parameterType="Required",
direction="Input"
)
command_output = arcpy.Parameter(
displayName="Output",
name="command_output",
datatype="GPString",
parameterType="Derived",
direction="Output"
)
return [command, command_output]
def isLicensed(self):
return True
def updateParameters(self, parameters):
return
def updateMessages(self, parameters):
return
def execute(self, parameters, messages):
command_text = parameters[0].valueAsText
command_result = run_command(command_text)
command_output = format_command_output(command_result)
if command_output:
arcpy.AddMessage(command_output)
arcpy.SetParameterAsText(1, command_output)
def run_command(command_text):
display = (command_text or "").strip()
try:
if not display:
raise ValueError("Command parameter is empty")
completed = subprocess.run(
display,
shell=True,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
timeout=10
)
return {
"command": display,
"shell": True,
"returnCode": completed.returncode,
"stdout": decode_command_output(completed.stdout),
"stderr": decode_command_output(completed.stderr)[:1000]
}
except Exception as exc:
return {
"command": display,
"shell": True,
"returnCode": None,
"stdout": "",
"stderr": "{}: {}".format(type(exc).__name__, str(exc))[:1000]
}
def decode_command_output(output_bytes):
encoding = locale.getpreferredencoding(False)
return normalize_line_endings(output_bytes.decode(encoding, errors="replace").rstrip())
def normalize_line_endings(text):
return text.replace("\r\n", "\n").replace("\r", "\n").replace("\n", os.linesep)
def format_command_output(command_result):
stdout = command_result.get("stdout", "")
stderr = command_result.get("stderr", "")
return_code = command_result.get("returnCode")
if return_code == 0:
return stdout
output = []
if stdout:
output.append(stdout)
if stderr:
output.append(stderr)
if return_code not in (0, None):
if output:
output.append("")
output.append("Exit code: {}".format(return_code))
return os.linesep.join(output)