Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,8 @@ session = [

# Sh Module - Shell utilities
# Use: pip install scitex[sh]
sh = [
"matplotlib",
]
# Real implementation lives in the standalone scitex-sh package.
sh = ["scitex-sh>=0.1.0"]

# Social Module - Social media integration
# Use: pip install scitex[social]
Expand Down
58 changes: 0 additions & 58 deletions src/scitex/sh/README.md

This file was deleted.

106 changes: 15 additions & 91 deletions src/scitex/sh/__init__.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,20 @@
#!/usr/bin/env python3
from __future__ import annotations
"""SciTeX sh — thin compatibility shim for scitex-sh.

import os
Aliases ``scitex.sh`` to the standalone ``scitex_sh`` package via ``sys.modules``.
``scitex.sh is scitex_sh``.

__FILE__ = __file__
__DIR__ = os.path.dirname(__FILE__)
Install: ``pip install scitex[sh]`` (or ``pip install scitex-sh``).
See: https://github.com/ywatanabe1989/scitex-sh
"""

from typing import Union
import sys as _sys

from ._execute import execute
from ._security import quote, validate_command
from ._types import CommandInput, ReturnFormat, ShellResult
try:
import scitex_sh as _real
except ImportError as _e: # pragma: no cover
raise ImportError(
"scitex.sh requires the 'scitex-sh' package. "
"Install with: pip install scitex[sh] (or: pip install scitex-sh)"
) from _e


def sh(
command_str_or_list: CommandInput,
verbose: bool = True,
return_as: ReturnFormat = "dict",
timeout: int = None,
stream_output: bool = False,
) -> Union[str, ShellResult]:
"""
Executes a shell command safely (list format only).

Parameters:
- command_str_or_list: Command to execute (MUST be list format)
- verbose: Whether to print command and output
- return_as: Return format ("dict" or "str")
- timeout: Timeout in seconds (None for no timeout)
- stream_output: Whether to stream output in real-time (default: False)

Returns:
- If return_as="str": output string
- If return_as="dict": ShellResult dict

Security Notes:
- Only list format is allowed to prevent shell injection
- Each argument is treated as a literal string
- For pipes/redirects, use Python subprocess chaining

Examples:
--------
>>> from scitex.sh import sh
>>> sh(["ls", "-la", "/home"])
>>> sh(["git", "status"])
>>> sh(["sleep", "10"], timeout=5) # Will timeout after 5 seconds
>>> sh(["./compile.sh"], stream_output=True) # Stream output in real-time
>>>
>>> # For grep-like filtering, use Python:
>>> result = sh(["ls", "-la"])
>>> filtered = [l for l in result['stdout'].split('\\n') if '.py' in l]
"""
result = execute(
command_str_or_list,
verbose=verbose,
timeout=timeout,
stream_output=stream_output,
)

if return_as == "dict":
return result
else:
if result["success"]:
return result["stdout"]
else:
return result["stderr"]


def sh_run(command: CommandInput, verbose: bool = True) -> ShellResult:
"""
Executes a shell command and returns detailed results.

Parameters:
- command: Command to execute (MUST be list format)
- verbose: Whether to print command and output

Returns:
- ShellResult dict with stdout, stderr, exit_code, success

Examples:
--------
>>> from scitex.sh import sh_run
>>> result = sh_run(["ls", "-la"])
>>> if result['success']:
... print(result['stdout'])
"""
return execute(command, verbose=verbose)


# Legacy functions moved from gen module
from ._shell_legacy import run_shellcommand, run_shellscript

__all__ = ["sh", "sh_run", "quote", "run_shellcommand", "run_shellscript"]

# EOF
_sys.modules[__name__] = _real
Loading
Loading