☰
sh 库 API 参考指南:Command、RunningCommand 与特殊关键字参数全解析
2026/9/29 2:26:32 网站建设 项目流程
  • 开发工具

【免费下载链接】sh

Python process launching

项目地址:https://gitcode.com/gh_mirrors/sh/sh
点击查看免费下载

sh是一个以「调用系统命令就像调用普通 Python 函数一样自然」为设计目标的进程启动库(项目名sh,描述为Python process launching)。本篇指南以官方参考文档docs/source/reference.rst为主体骨架,完整梳理 sh 的三大核心类(Command、RunningCommand、OProc)、异常体系与辅助函数,并逐项解析全部特殊关键字参数(special kwargs)。读完本篇,你将掌握 sh 命令对象如何构造与烘焙(bake)、进程如何被 fork/exec 启动与收尾、如何用_out/_err/_tee/_iter等参数精细控制输入输出,以及如何借助_ok_code/_timeout/_done处理退出码、超时与回调,最终能够写出可复用的真实进程调用代码。

一、Command 类:代表一个可执行的程序

1.1 核心职责

Command类表示系统上存在、可以在某个时刻被运行的程序。一个Command实例本身永远不处于运行状态——真正被启动的是RunningCommand实例(底层再包装OProc)。这一点对应源码注释的描述:RunningCommand是「an executing Command object」,而Command只是可执行命令的惰性句柄(见 src/sh/init.py)。

Command实例有两种构造方式:手动实例化,或通过动态属性查找自动构造:

import sh ls1 = sh.Command("ls") ls2 = sh.ls assert ls1 == ls2

sh.ls之所以可用,是因为Command.__getattribute__在属性名不以_开头、且不是bake等保留名时,会调用self.bake(name)动态创建一个新的命令对象(src/sh/init.py)。这也解释了 sh 最经典的「把命令当作函数调用」的语法。

1.2 构造参数

Command(name, search_paths=None):

  • name:程序在$PATH中的名称,或一个完整路径。
  • search_paths:可选,指定查找程序时要搜索的路径列表(默认使用$PATH)。
from sh import Command ifconfig = Command("ifconfig") ifconfig = Command("/sbin/ifconfig")

底层通过_which(path, search_paths)完成查找:找不到可执行文件、无执行权限或文件不可执行时,直接抛出CommandNotFound(path)异常(见Command.__init__,src/sh/init.py)。

1.3 一个常见陷阱:路径与参数必须分开

sh.Command的参数必须是单独的程序名,不能把整条命令行塞进去:

# 错误:会抛出 CommandNotFound 异常,即使给了正确的完整路径 lscmd = sh.Command("/bin/ls -l") tarcmd = sh.Command("/bin/tar cvf /tmp/test.tar /my/home/directory/")

正确做法是两步:

  1. 只用二进制路径构建Command对象;
  2. 在调用时传入参数。
lscmd = sh.Command("/bin/ls") lscmd("-l") tarcmd = sh.Command("/bin/tar") tarcmd("cvf", "/tmp/test.tar", "/my/home/directory/")

1.4 bake():烘焙(部分应用)参数

Command.bake(*args, **kwargs)返回一个新的Command,把*args与**kwargs作为默认参数「烘焙」进去;之后每次调用返回的 Command 都会自动带上这些参数:

from sh import ls long_ls = ls.bake("-l") print(ls("/var")) # 实际执行 ls -l /var print(ls("/tmp")) # 实际执行 ls -l /tmp

从源码看,bake会复制自身、累积_partial_call_args(特殊关键字参数)与_partial_baked_args(参数层),编译成最终 argv 的动作被推迟到__call__/__str__时执行,并且支持多层 bake 中布尔参数的覆盖语义(后层key=False会抑制前层的key=True,见 src/sh/init.py)。bake 的更多实战用法参见 docs/source/sections/baking.rst。

二、RunningCommand 类:正在执行的命令

2.1 概念与获取方式

RunningCommand表示一个「正在或已经被执行」的Command实例,它是OProc(底层进程包装)之上的门面,也是用户与 sh 对象交互最多的类。只有当你以_return_cmd=True执行命令时,它才会被返回;否则 sh 可能直接返回纯字符串输出。

需要特别注意的是:RunningCommand的实例表现得非常像字符串,这是刻意的设计,目的是让「命令输出」用起来更直观。但要警惕:只接受真正str的函数(例如json.dumps)无法直接作用于RunningCommand,即使它看起来像字符串。

2.2 核心方法

wait(timeout=None) 与退出码异常

wait()阻塞等待命令结束并取得退出码;若退出码代表失败则抛出相应异常。它被 sh 自动调用,除非命令以_bg=True异步执行——那时你可能需要手动调用它来确保完成。timeout是非负秒数,超时则抛出TimeoutException。

两个细节值得注意:

  • 多次调用wait()只有第一次会抛异常;
  • 当Command实例被用作另一命令的 stdin(即管道场景,见 docs/source/sections/piping.rst)时,wait()也会被调用于该实例,其异常会被向上传播。
p = sh.sleep(10, _bg=True) try: p.wait(timeout=1) except sh.TimeoutException: print("we timed out waiting") p.kill()
signal 系列
  • signal(sig_num):向进程发送信号,通常配合signal模块使用,如signal.SIGHUP。
  • signal_group(sig_num):向进程组内每个进程发送信号。
  • terminate():signal(SIGTERM)的快捷方式。
  • kill():signal(SIGKILL)的快捷方式。
  • kill_group():signal_group(SIGKILL)的快捷方式。
  • is_alive():返回进程是否仍然存活(bool)。

这些方法在 src/sh/init.py 中通过_OProc_attr_allowlist白名单直接透传到底层OProc(src/sh/init.py)。

2.3 核心属性

  • process:底层OProc实例。
  • stdout:@property,先调用wait(),再返回进程写入 STDOUT 的内容。
  • stderr:@property,先调用wait(),再返回 STDERR 内容。
  • exit_code:@property,先调用wait(),再返回进程退出码。
  • pid:进程 ID。
  • sid:进程会话 ID。除非指定_new_session=False,否则通常与当前 Python 进程的会话不同。
  • pgid:进程组 ID。
  • ctty:控制终端设备(如果存在)。

三、OProc 类:底层进程包装

OProc是RunningCommand之下的底层实现,官方文档明确警告:不要直接使用它的实例,此处记录它仅为了存档说明。

  • wait():阻塞至进程完成,聚合输出,并填充exit_code。
  • stdout/stderr:collections.deque,容量由_internal_bufsize决定,存放进程的 STDOUT/STDERR 内容。
  • exit_code:进程退出码;进程未退出时为None。
  • pid/sid/pgid/ctty:进程 ID、会话 ID、进程组 ID、控制终端。
  • signal(sig_num)/signal_group(sig_num)/terminate()/kill()/kill_group():与RunningCommand同名方法同义。

OProc内部持有两个线程:一个负责 STDIN,一个负责 STDOUT 与 STDERR(详见下文「架构总览」)。

四、异常体系

4.1 ErrorReturnCode

所有「返回码异常」的基类,继承自Exception。它有四个实用属性:

  • full_cmd:完整执行命令字符串,可直接复制到命令行验证。
  • stdout:进程聚合后的完整 STDOUT。
  • stderr:进程聚合后的完整 STDERR。
  • exit_code:进程调整后的退出码(进程被信号终止时为其负值,如 SIGKILL → -9)。

源码中ErrorReturnCode还配有一个元类ErrorReturnCodeMeta,按退出码动态生成ErrorReturnCode_0、ErrorReturnCode_1……等具体子类(见 src/sh/init.py 与类型标注 src/sh/init.pyi),因此你在except中既可以写sh.ErrorReturnCode,也可以精确到sh.ErrorReturnCode_2。

4.2 SignalException

继承ErrorReturnCode。当命令因收到信号而退出时抛出(例如进程被kill)。

4.3 TimeoutException

以下两种情况抛出:

  1. 命令指定了非空_timeout且超时:
import sh try: sh.sleep(10, _timeout=1) except sh.TimeoutException: print("we timed out, as expected")
  1. 给RunningCommand.wait(timeout=...)指定了超时(见上文示例)。

4.4 CommandNotFound

在以下任一条件成立时抛出:

  • 程序在$PATH中找不到;
  • 没有执行该程序的权限;
  • 程序未被标记为可执行。

后两条初看奇怪,但完全符合 Bash 查找可执行程序的真实行为。

注意:CommandNotFound继承自AttributeError,因此它的repr就是缺失属性的名字本身。

五、辅助函数

5.1 which(name, search_paths=None)

把name解析为程序的绝对路径;找不到时返回None。search_paths提供时按该列表查找,否则使用环境变量$PATH。

5.2 pushd(directory)

提供与 Bashpushd行为类似的with上下文:进入指定目录,上下文结束时自动弹出:

import sh with sh.pushd("/tmp"): sh.touch("a_file")

实现上使用可重入锁(reentrant lock),因此多线程在不同with上下文内各自切换目录时行为是正确的。

六、特殊关键字参数(Special Kwargs)完整参考

特殊关键字参数用于改变命令行为,不会传给被调用的程序。它们可用在任何命令上,但部分不能组合使用——sh 会主动检测冲突并报错。若要为每一个命令运行都设置默认特殊参数,请使用default_arguments(见 docs/source/sections/default_arguments.rst)。

在源码中,这些参数的默认值集中定义在Command._call_args字典(src/sh/init.py),并在_extract_call_args中以_前缀从 kwargs 中抽取、剥离,再经_kwarg_validators校验合法性(src/sh/init.py)。下面的默认值即来自该字典(少数与文档中标注的略有出入处,以源码实际值为准,例如_tty_size源码默认(24, 80))。

6.1 控制输出(Controlling Output)

_out(默认None)

指定 STDOUT 的重定向目标。可以是:

  • 字符串 → 视为文件名;
  • 文件对象或类文件对象;
  • 整数 → 文件描述符(如os.pipe()的返回值);
  • io.StringIO对象;
  • 可调用对象(callable)。
import sh sh.ls(_out="/tmp/output")
_err(默认None)

指定 STDERR 的重定向目标,用法同_out。

_err_to_out(默认False)

若为True,把绑定到进程 STDOUT 的文件描述符同时复制到 STDERR,使 STDERR 与 STDOUT 输出到同一处。

_encoding(默认sh.DEFAULT_ENCODING)

进程 STDOUT 的字符编码。默认是 locale 的默认编码;源码中定义为DEFAULT_ENCODING = getpreferredencoding() or "UTF-8"(src/sh/init.py)。

_decode_errors(默认"strict",1.07.0 新增)

Python 如何处理进程输出的解码错误。默认"strict",可改为任何bytes.decode支持的值,如"ignore"。

_tee(默认None,1.07.0 新增)

自 1.07.0 起,只要对 STDOUT 或 STDERR 使用了重定向,sh 内部对应缓冲区就不会再被填充(例如下载文件时用回调处理 STDOUT,内部 STDOUT 缓冲与管道缓冲都不会存数据)。_tee强制其中一个流仍然被填充,相当于把输出「分叉」到两处:回调/重定向目标 + 内部缓冲区。取值:_tee='err'强制填 STDERR,_tee='out'或_tee=True强制填 STDOUT。源码中注释形象地称之为「as if the output is being T'd to both」(src/sh/init.py)。

_truncate_exc(默认True,1.12.0 新增)

异常输出是否截断。

6.2 执行控制(Execution)

_fg(默认False,1.12.0 新增)

以前台模式运行命令:使用os.spawnle()派生,当前进程的 STDIN/OUT/ERR 被os.dup2()到新进程,使新进程成为执行脚本 shell 的前台。仅在你需要启动一个精简、交互式、sh 难以处理的进程时有用(例如ssh)。

⚠️ 警告:_fg=True会绕过 sh 的大量功能——你不会得到进程对象,且大部分(很可能全部)其他特殊 kwargs 都不生效。

若想保留 sh 特性又获得类似效果,请用:

import sh import sys sh.your_command(_in=sys.stdin, _out=sys.stdout, _err=sys.stderr)
_bg(默认False)

后台运行命令。命令立即返回,你必须调用RunningCommand.wait()确保其终止(参见 docs/source/sections/asynchronous_execution.rst)。

_bg_exc(默认True,1.12.9 新增)

是否自动报告后台命令的异常。若设为False,务必自行调用wait(),否则后台命令中发生的异常可能被吞掉。

_async(默认False,2.0.0 新增)

使命令变得可 await。配合_iter=True与async for可以增量地 await 输出。测试用例test_async展示了await python(py.name, _async=True)在事件循环中的用法(tests/sh_test.py)。

_env(默认None)

一个字典,定义进程唯一能访问的环境变量。若不指定,则继承调用进程的环境。

注意:这个字典是进程环境的权威来源。如果你只想修改当前环境中的单个变量,必须把「当前环境副本 + 覆盖后的变量」一起传给 sh(参见 docs/source/sections/envs.rst)。

_timeout(默认None)

给予进程完成的时间(秒)。超时后向进程发送_timeout_signal定义的信号。

_timeout_signal(默认signal.SIGKILL)

当_timeout非空时,超时向进程发送的信号。

_cwd(默认None)

设置进程当前工作目录的字符串。

_ok_code(默认0)

整数、列表或元组,包含被视为「正常」(不抛异常)的退出码。有些行为怪异的程序用非 0 退出码表示成功:

import sh sh.weird_program(_ok_code=[0, 3, 5])

如果进程被信号杀死,默认会抛出SignalException。要屏蔽此行为,可在_ok_code中追加代表该信号的负数:

import sh # SIGINT、SIGKILL、SIGTERM 杀掉进程时不会抛 SignalException p = sh.sleep(3, _bg=True, _ok_code=[0, -2, -9, -15]) # 这里不会抛异常 p.kill()

源码中_ok_code会先被规范化为列表(None回退为[0]),再与ErrorReturnCodeMeta的动态子类机制配合使用(src/sh/init.py)。测试test_ok_code系列验证了整数、列表、range与异常路径的行为(tests/sh_test.py)。更多细节见 docs/source/sections/exit_codes.rst。

_new_session(默认False,2.0.0 起默认值由True改为False)

决定 fork 出的进程是否通过os.setsid()成为独立会话。2.0.0 修改默认值的原因:让被启动进程默认待在 Python 脚本的进程组中,从而正确接收 SIGINT。

_new_group(默认False)

决定 fork 出的进程是否通过os.setpgid()成为独立进程组。

_uid(默认None,1.12.0 新增)

在子进程调用os.execv前假设的用户 ID。需要 root 权限,且不支持 Windows。

_preexec_fn(默认None,1.12.0 新增)

在子进程调用os.execv前运行的函数。普通用户通常不会使用。

_pass_fds(默认空集合{},1.13.0 新增)

一个白名单可迭代对象,其中的整型文件描述符将被子进程继承。传入任何值都会导致_close_fds=True。

_close_fds(默认True,1.13.0 新增)

关闭除 stdin、stdout、stderr 之外所有被继承的文件描述符。传入_pass_fds时会自动启用。注意:这两个参数不能同时显式设置,校验器会报"Passing 'pass_fds' forces 'close_fds' to be True"(src/sh/init.py)。

6.3 通信控制(Communication)

_in(默认None)

指定进程的标准输入。可以是字符串、queue.Queue、类文件对象或任意可迭代对象(参见 docs/source/sections/stdin.rst)。

_piped(默认None)

取值可为True、"out"或"err"。表示该命令正被用作另一命令的输入,因此应增量地返回输出,而不是一次性聚合(参见 docs/source/sections/piping.rst)。

_iter(默认None)

取值可为True、"out"或"err"。使命令进入可迭代模式,可以用for/while循环实时遍历输出:

import sh for line in sh.cat("/tmp/file", _iter=True): print(line)
_iter_noblock(默认None)

与_iter相同,但循环在没有输出时不阻塞,而是返回errno.EWOULDBLOCK:

import sh import errno import time for line in sh.tail("-f", "stuff.log", _iter_noblock=True): if line == errno.EWOULDBLOCK: print("doing something else...") time.sleep(0.5) else: print("processing line!")

注意:_piped与_iter不能同时使用,校验器会报"You cannot iterate when this command is being piped"。

_with(默认False)

显式告知 sh 正在with上下文中运行命令。只有当你在with上下文且同时传参时才需要它:

import sh with sh.contrib.sudo(password="abc123", _with=True): print(sh.ls("/root"))

(关于with上下文详见 docs/source/sections/with.rst。)

_done(默认None,1.11.0 新增)

命令完成时必定被调用的回调——即使退出码本应抛异常也会先调用它;回调运行完毕后,原本要抛的异常照常抛出。回调接收三个参数:RunningCommand实例、表示成功的布尔值、退出码。

官方示例展示了用它实现「最多 10 个并发」的多进程池:

import sh from threading import Semaphore pool = Semaphore(10) def done(cmd, success, exit_code): pool.release() def do_thing(arg): pool.acquire() return sh.your_parallel_command(arg, _bg=True, _done=done) procs = [] for arg in range(100): procs.append(do_thing(arg)) # essentially a join [p.wait() for p in procs]

(完整示例见 docs/source/examples/done.rst。)

6.4 TTY 控制

_tty_in(默认False,即使用os.pipe)

若为True,sh 为 STDIN 创建一个 TTY,相当于模拟终端——就像命令从命令行输入一样。对「要求 STDIN 必须是 TTY」的命令必不可少。

_tty_out(默认True)

若为True,sh 为 STDOUT 创建 TTY,否则使用os.pipe。对「要求 STDOUT 是 TTY」的命令必要(如带颜色的输出;相关 FAQ 见 docs/source/sections/faq.rst 中faq_tty_out)。

_unify_ttys(默认False,1.13.0 新增)

若为True,sh 将 STDOUT 与 STDIN 的 TTY 合并为单一伪终端。某些挑剔的程序(如 SSH)期望面对单个伪终端时必需。

_tty_size(默认(20, 80),源码实际默认(24, 80))

STDOUT TTY 的(行, 列)尺寸。改变它可能影响程序每行打印多少内容。

6.5 性能与优化(Performance & Optimization)

_in_bufsize(默认0)

STDIN 缓冲区大小:0无缓冲,1行缓冲,其他数值为对应大小的缓冲。

_out_bufsize(默认1)

STDOUT 缓冲区大小,取值语义同上。

_err_bufsize(默认1)

同_out_bufsize,作用于 STDERR。

_internal_bufsize(默认3 * 1024**2个块)

命令内部存储 STDOUT/ERR 的量。这个值表示缓冲区块数,不是总字节数:例如值设为 100 且 STDOUT 行缓冲时,可取出 100 行;STDOUT 无缓冲时,只能取出 100 个字符。源码注释也强调:这是 CHUNK 数而非 BYTE 数,使用deque,溢出时最先的条目被挤出(src/sh/init.py)。

_no_out(默认False,1.07.0 新增)

禁用 STDOUT 的内部存储。适合命令产生海量而你不需要的输出——避免这些数据占用 sh 内部内存。

_no_err(默认False,1.07.0 新增)

禁用 STDERR 的内部存储,用途同上。

_no_pipe(默认False,1.07.0 新增)

类似_no_out,显式告知 sh 该命令永远不会被用于管道输出,因此不必用内部输出填满其管道缓冲——同样用于节约内存。注意:_piped与_no_pipe冲突,校验器会报"Using a pipe doesn't make sense if you've disabled the pipe"。

6.6 程序参数(Program Arguments)

这些参数影响命令选项如何被喂给程序。

_long_sep(默认"=",1.12.0 新增)

分隔「程序长参数名」与「值」的字符。例如程序期望--name value形式时,设_long_sep=" ":

import sh sh.your_program(key=value, _long_sep=" ")

将向程序发送["--key value"]。若程序期望长参数名与值完全分开,传None:

import sh sh.your_program(key=value, _long_sep=None)

将发送["--key", "value"]。

_long_prefix(默认"--",1.12.0 新增)

长参数的前缀字符。有些程序使用单横线且不理解双横线,此时可改为"-"。

_arg_preprocess(默认None,1.12.0 新增)

高级选项:允许基于其他命令参数或变量,在运行时重写命令参数。它通常只在配合bake(docs/source/sections/baking.rst)时有用,目前仅用于构造contrib包装器(docs/source/sections/contrib.rst):

import sh def processor(args, kwargs): return args, kwargs my_ls = sh.bake.ls(_arg_preprocess=processor)

⚠️ 警告:_arg_preprocess的函数接口可能随时变动,仅限 sh 内部使用,非必要不要使用。

6.7 其他(Misc)

_log_msg(默认None,1.12.0 新增)

自定义Command实例的日志头。默认日志形如:

import logging import sh logging.basicConfig(level=logging.INFO) sh.ls("-l")
INFO:sh.command:<Command '/bin/ls -l'>: starting process INFO:sh.command:<Command '/bin/ls -l', pid 28952>: process started INFO:sh.command:<Command '/bin/ls -l', pid 28952>: process completed

如果你觉得<Command ..段冗长,可用_log_msg自定义:

import logging import sh logging.basicConfig(level=logging.INFO) def custom_log(ran, call_args, pid=None): return ran sh.ls("-l", _log_msg=custom_log)
INFO:sh.command:/bin/ls -l: starting process INFO:sh.command:/bin/ls -l: process started INFO:sh.command:/bin/ls -l: process completed

回调参数含义:

  • ran:程序的执行串与参数(尽可能接近你在 shell 中输入的样子);
  • call_args:传给命令的所有特殊 kwargs 的字典;
  • pid:fork 后进程的 PID,默认None——因为_log_msg回调实际上被调用两次:第一次在进程 spawn 前构造RunningCommand实例的 logger,第二次在进程 spawn 后(此时才有 pid)。

七、架构总览:进程如何被启动与收尾

docs/source/sections/architecture.rst详细描述了 sh 的进程生命周期,理解它能让你更从容地使用上述特殊参数。

7.1 启动(Launch)

启动一个进程时:

  1. 打开 STDIN/OUT/ERR 的管道和/或 TTY;
  2. 打开一条用于从子进程向父进程传递 pre-exec 异常的管道;
  3. 打开一条子/父进程启动同步管道;
  4. os.fork()出子进程。

此后存在两个并发进程:

子进程:

  1. 若_bg=True,忽略SIGHUP;
  2. 若_new_session=True,用os.setsid()成为会话首进程;否则用os.setpgrp()成为进程组首进程;
  3. 将会话 ID 写入连接父进程的管道(用于同步会话/组逻辑完成);
  4. os.dup2()将之前设置好的 TTY/管道 fd 映射到 STDIN/OUT/ERR;
  5. 若是会话首进程且 STDIN 是 TTY(_tty_in=True),获取控制终端,成为会话的控制进程;
  6. 若设置了自定义_uid,设置 GID/UID;
  7. 关闭所有大于 STDERR 的文件描述符;
  8. 调用os.execv。

父进程:

  1. 通过异常管道检查子进程是否报告异常;
  2. 阻塞读取子进程的会话 ID(同步确认子进程已完成会话/组切换,从而能准确获取其 sid 与 pgid);
  3. 若使用 TTY 作为 STDIN(_tty_in=True),关闭 TTY 的回显,使发往 STDIN 的数据不被回显到 STDOUT。

7.2 运行(Running)

OProc实例持有两个内部线程:一个负责 STDIN,一个负责 STDOUT 与 STDERR。STDOUT/ERR 线程持续对连接到 STDOUT/ERR 的 TTY/管道 master 端执行select.select;一旦可读,就读出数据并聚合到相应位置。

7.3 缓冲(Buffers)

理解 sh 的数据流需要区分两类缓冲:

  1. 底层管道/TTY 缓冲:STDOUT/ERR 所连管道或 TTY 自身的缓冲。TTY(默认输出)缓冲为 0,输出即时——进程写一个字节,sh 收到一个字节;管道缓冲则通常为 4–64KB(参见pipe(2))。
  2. sh 内部缓冲:STDOUT、STDERR 各一个。数据从 TTY/管道 master 端读出后、被送往对应输出处理器(队列、文件对象、函数等)之前,暂存于此。直到达到_internal_bufsize指定的大小,缓冲才冲刷到输出处理器。

7.4 退出(Exit)

  • STDIN 线程关闭:进程结束后内部线程必须结束,因为 STDIN 读端(连接进程)已关闭,再向写端写入将失败。
  • STDOUT/ERR 线程关闭:略复杂——进程虽已退出,但管道/TTY 缓冲中可能仍有数据待收集。因此线程继续select.select读端,直到读不到数据(表示结束),才退出读循环。
  • 退出码处理:从被回收的进程取得退出码。若进程因信号终止,退出码为该信号的负值——例如 SIGKILL 对应退出码 -9(这与_ok_code支持负数、ErrorReturnCode.exit_code的语义一致)。
  • Done 回调:若指定了_done,回调会以(RunningCommand实例、成功布尔值、调整后退出码)执行;回调返回后错误处理继续。也就是说,_done无论成败都会被调用,且它无法阻止后续ErrorReturnCode异常的抛出。

八、速查与延伸阅读

  • 特殊参数总表定义见 src/sh/init.py(Command._call_args),校验规则见同文件 src/sh/init.py。
  • 参数编译(compile_args/_aggregate_keywords)在 src/sh/init.py,它决定sh.ls("-l", "/tmp", color="never")如何变成['-l', '/tmp', '--color=never']。
  • 类型标注可参考 src/sh/init.pyi,其中ErrorReturnCode_0至ErrorReturnCode_15等动态异常子类均有声明。
  • 相关主题文档:退出码 docs/source/sections/exit_codes.rst、重定向 docs/source/sections/redirection.rst、异步执行 docs/source/sections/asynchronous_execution.rst、管道 docs/source/sections/piping.rst、子命令 docs/source/sections/subcommands.rst、环境变量 docs/source/sections/envs.rst、with上下文 docs/source/sections/with.rst。
  • 开发工具

【免费下载链接】sh

Python process launching

项目地址:https://gitcode.com/gh_mirrors/sh/sh
点击查看免费下载

相关推荐

上一篇:pumpkin-book异常检测:异常检测公式推导解析
下一篇:终极指南:llm.c中Transformer架构的CUDA实现详解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询