-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathshell_code_node.py
More file actions
82 lines (72 loc) · 2.45 KB
/
shell_code_node.py
File metadata and controls
82 lines (72 loc) · 2.45 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
"""Shell-based custom node utilities for ComfyUI."""
from __future__ import annotations
import shutil
import subprocess
from typing import List, Tuple
class ShellCodeNode:
"""Execute a /bin/bash script with STRING input and return its output."""
CATEGORY = "utils/code"
FUNCTION = "run"
RETURN_TYPES = ("STRING", "LIST", "STRING", "BOOLEAN")
RETURN_NAMES = ("stdout", "stdout_lines", "stderr", "ok")
OUTPUT_IS_LIST = (False, True, False, False)
INPUT_IS_LIST = False
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"script": (
"STRING",
{
"multiline": True,
"default": "cat",
"placeholder": "script",
},
),
"stdin_text": (
"STRING",
{
"multiline": True,
"default": "",
"placeholder": "stdin_text",
},
),
},
"optional": {
"split_lines": ("BOOLEAN", {"default": True}),
"strip_empty": ("BOOLEAN", {"default": True}),
},
}
def run(
self,
script: str,
stdin_text: str,
split_lines: bool = True,
strip_empty: bool = True,
) -> Tuple[str, List[str], str, bool]:
"""Execute *script* with *stdin_text* and return stdout/lines/stderr/ok."""
try:
bash_path = shutil.which("bash")
if not bash_path:
raise FileNotFoundError("bash executable not found in PATH")
proc = subprocess.run(
[bash_path, "-lc", script],
input=stdin_text,
capture_output=True,
text=True,
check=False,
)
stdout = proc.stdout or ""
stderr = proc.stderr or ""
ok = proc.returncode == 0
except Exception as exc: # pragma: no cover - defensive fallback
stdout = ""
stderr = f"{type(exc).__name__}: {exc}"
ok = False
if split_lines:
stdout_lines = stdout.splitlines()
if strip_empty:
stdout_lines = [line for line in stdout_lines if line.strip()]
else:
stdout_lines = []
return stdout, stdout_lines, stderr, ok