将 stdout 和 stderr 捕获到不同的变量中

2024-05-03

是否可以存储或捕获 stdout 和 stderr不同的变量,不使用临时文件?现在我这样做是为了获得标准输出out和标准错误err跑步时some_command,但我会 喜欢避免临时文件。

error_file=$(mktemp)
out=$(some_command 2>$error_file)
err=$(< $error_file)
rm $error_file

我认为在说“你不能”做某事之前,人们至少应该亲手尝试一下......

简单干净的解决方案,无需使用eval或任何异国情调的东西

1. 最小版本

{
    IFS=$'\n' read -r -d '' CAPTURED_STDERR;
    IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
} < <((printf '\0%s\0' "$(some_command)" 1>&2) 2>&1)

要求: printf, read

2. 简单测试

用于生成的虚拟脚本stdout and stderr: useless.sh

#!/bin/bash
#
# useless.sh
#

echo "This is stderr" 1>&2
echo "This is stdout" 

将捕获的实际脚本stdout and stderr: capture.sh

#!/bin/bash
#
# capture.sh
#

{
    IFS=$'\n' read -r -d '' CAPTURED_STDERR;
    IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
} < <((printf '\0%s\0' "$(./useless.sh)" 1>&2) 2>&1)

echo 'Here is the captured stdout:'
echo "${CAPTURED_STDOUT}"
echo

echo 'And here is the captured stderr:'
echo "${CAPTURED_STDERR}"
echo

输出capture.sh

Here is the captured stdout:
This is stdout

And here is the captured stderr:
This is stderr

3. 运作原理

命令

(printf '\0%s\0' "$(some_command)" 1>&2) 2>&1

发送标准输出some_command to printf '\0%s\0',从而创建字符串\0${stdout}\n\0 (where \0 is a NUL字节和\n是换行符);字符串\0${stdout}\n\0然后重定向到标准错误,其中标准错误some_command已经存在,因此组成了字符串${stderr}\n\0${stdout}\n\0,然后重定向回标准输出。

之后,命令

IFS=$'\n' read -r -d '' CAPTURED_STDERR;

开始读取字符串${stderr}\n\0${stdout}\n\0直到第一个NULbyte 并将内容保存到${CAPTURED_STDERR}。然后命令

IFS=$'\n' read -r -d '' CAPTURED_STDOUT;

继续读取相同的字符串直到下一个NULbyte 并将内容保存到${CAPTURED_STDOUT}.

4. 使其坚不可摧

上面的解决方案依赖于NUL之间的分隔符字节stderr and stdout,因此如果出于任何原因它将无法工作stderr包含其他NUL bytes.

尽管这种情况很少发生,但通过剥离所有可能的情况,可以使脚本完全牢不可破。NUL字节来自stdout and stderr在将两个输出传递给之前read(消毒)-NUL字节无论如何都会丢失,因为不可能将它们存储到 shell 变量中 https://stackoverflow.com/questions/6570531/assign-string-containing-null-character-0-to-a-variable-in-bash/24511770#24511770:

{
    IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
    IFS=$'\n' read -r -d '' CAPTURED_STDERR;
} < <((printf '\0%s\0' "$((some_command | tr -d '\0') 3>&1- 1>&2- 2>&3- | tr -d '\0')" 1>&2) 2>&1)

要求: printf, read, tr

5. 保留退出状态 – 蓝图(未经清理)

在思考了最终的方法之后,我想出了一个使用的解决方案printf缓存both stdout和退出代码作为两个不同的参数,这样它们就不会干扰。

我做的第一件事是概述一种将退出状态传达给第三个参数的方法printf,这是非常容易以最简单的形式完成的事情(即无需消毒)。

{
    IFS=$'\n' read -r -d '' CAPTURED_STDERR;
    IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
    (IFS=$'\n' read -r -d '' _ERRNO_; exit ${_ERRNO_});
} < <((printf '\0%s\0%d\0' "$(some_command)" "${?}" 1>&2) 2>&1)

要求: exit, printf, read

6. 通过清理保留退出状态 – 牢不可破(重写)

然而,当我们尝试引入消毒措施时,事情会变得非常混乱。发射tr清理流实际上会覆盖我们之前的退出状态,因此显然唯一的解决方案是在丢失之前将后者重定向到一个单独的描述符,将其保留在那里直到tr它的工作执行两次,然后将其重定向回原来的位置。

在文件描述符之间进行一些相当复杂的重定向之后,这就是我得出的结果。

下面的代码是对前面示例的重写(您可以在下面的附录中找到它)。它还可以消毒NUL流中的字节,因此read始终可以正常工作。

{
    IFS=$'\n' read -r -d '' CAPTURED_STDOUT;
    IFS=$'\n' read -r -d '' CAPTURED_STDERR;
    (IFS=$'\n' read -r -d '' _ERRNO_; exit ${_ERRNO_});
} < <((printf '\0%s\0%d\0' "$(((({ some_command; echo "${?}" 1>&3-; } | tr -d '\0' 1>&4-) 4>&2- 2>&1- | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)

要求: exit, printf, read, tr

这个解决方案非常强大。退出代码始终保持在不同的描述符中,直到它到达printf直接作为一个单独的参数。

7. 最终解决方案——具有退出状态的通用函数

我们还可以将上面的代码转换为通用函数。

# SYNTAX:
#   catch STDOUT_VARIABLE STDERR_VARIABLE COMMAND [ARG1[ ARG2[ ...[ ARGN]]]]
catch() {
    {
        IFS=$'\n' read -r -d '' "${1}";
        IFS=$'\n' read -r -d '' "${2}";
        (IFS=$'\n' read -r -d '' _ERRNO_; return ${_ERRNO_});
    } < <((printf '\0%s\0%d\0' "$(((({ shift 2; "${@}"; echo "${?}" 1>&3-; } | tr -d '\0' 1>&4-) 4>&2- 2>&1- | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)
}

要求: cat, exit, printf, read, shift, tr

变更日志: 2022-06-17 // 已替换${3} with shift 2; ${@} after 帕维尔·坦科夫的评论 https://stackoverflow.com/questions/11027679/capture-stdout-and-stderr-into-different-variables/59592881?noredirect=1#comment126850672_59592881(仅限 Bash)。 2023-01-18 // 已替换${@} with "${@}" after cbugk的评论 https://stackoverflow.com/questions/11027679/capture-stdout-and-stderr-into-different-variables/59592881?noredirect=1#comment131497771_59592881.

随着catch函数我们可以启动以下代码片段,

catch MY_STDOUT MY_STDERR './useless.sh'

echo "The \`./useless.sh\` program exited with code ${?}"
echo

echo 'Here is the captured stdout:'
echo "${MY_STDOUT}"
echo

echo 'And here is the captured stderr:'
echo "${MY_STDERR}"
echo

并得到以下结果:

The `./useless.sh` program exited with code 0

Here is the captured stdout:
This is stderr 1
This is stderr 2

And here is the captured stderr:
This is stdout 1
This is stdout 2

8. 最后一个例子发生了什么

下面是一个快速的示意图:

  1. some_command已启动:然后我们有some_command's stdout在描述符 1 上,some_command's stderr在描述符 2 上并且some_command的退出代码重定向到描述符 3
  2. stdout被传送到tr(消毒)
  3. stderr被交换为stdout(暂时使用描述符 4)并通过管道传送到tr(消毒)
  4. 退出代码(描述符 3)被交换为stderr(现在描述符 1)并通过管道传输到exit $(cat)
  5. stderr(现在描述符 3)被重定向到描述符 1,end 扩展为第二个参数printf
  6. 的退出代码exit $(cat)被第三个参数捕获printf
  7. 的输出printf被重定向到描述符 2,其中stdout已经存在
  8. 的串联stdout和输出printf被传送到read

9. POSIX 兼容版本#1(易破解)

流程替代 https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html (the < <()语法)不是 POSIX 标准(尽管它们de facto是)。在不支持的 shell 中< <()语法达到相同结果的唯一方法是通过<<EOF … EOF句法。不幸的是这不允许我们使用NUL字节作为分隔符,因为这些在到达之前会被自动删除read。我们必须使用不同的分隔符。自然的选择落到了CTRL+Z字符(ASCII 字符编号 26)。这里有一个易碎的版本(输出不得包含CTRL+Z字符,否则它们会混合)。

_CTRL_Z_=$'\cZ'

{
    IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" CAPTURED_STDERR;
    IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" CAPTURED_STDOUT;
    (IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" _ERRNO_; exit ${_ERRNO_});
} <<EOF
$((printf "${_CTRL_Z_}%s${_CTRL_Z_}%d${_CTRL_Z_}" "$(some_command)" "${?}" 1>&2) 2>&1)
EOF

要求: exit, printf, read

Note: As shift仅限 Bash,在此 POSIX 兼容版本中,命令 + 参数必须出现在相同的引号下。

10. POSIX 兼容版本#2(牢不可破,但不如非 POSIX 版本)

这是它的牢不可破的版本,直接以函数形式(如果stdout or stderr包含CTRL+Z字符,流将被截断,但永远不会与另一个描述符交换)。

_CTRL_Z_=$'\cZ'

# SYNTAX:
#     catch_posix STDOUT_VARIABLE STDERR_VARIABLE COMMAND
catch_posix() {
    {
        IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" "${1}";
        IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" "${2}";
        (IFS=$'\n'"${_CTRL_Z_}" read -r -d "${_CTRL_Z_}" _ERRNO_; return ${_ERRNO_});
    } <<EOF
$((printf "${_CTRL_Z_}%s${_CTRL_Z_}%d${_CTRL_Z_}" "$(((({ ${3}; echo "${?}" 1>&3-; } | cut -z -d"${_CTRL_Z_}" -f1 | tr -d '\0' 1>&4-) 4>&2- 2>&1- | cut -z -d"${_CTRL_Z_}" -f1 | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)
EOF
}

要求: cat, cut, exit, printf, read, tr

答案的历史

这是以前的版本catch() before 帕维尔·坦科夫的注释(此版本需要将附加参数与命令一起引用):

# SYNTAX:
#  catch STDOUT_VARIABLE STDERR_VARIABLE COMMAND [ARG1[ ARG2[ ...[ ARGN]]]]
catch() {
  {
      IFS=$'\n' read -r -d '' "${1}";
      IFS=$'\n' read -r -d '' "${2}";
      (IFS=$'\n' read -r -d '' _ERRNO_; return ${_ERRNO_});
  } < <((printf '\0%s\0%d\0' "$(((({ shift 2; ${@}; echo "${?}" 1>&3-; } | tr -d '\0' 1>&4-) 4>&2- 2>&1- | tr -d '\0' 1>&4-) 3>&1- | exit "$(cat)") 4>&1-)" "${?}" 1>&2) 2>&1)
}

要求: cat, exit, printf, read, tr

此外,我替换了一个将退出状态传播到当前 shell 的旧示例,因为,Andy在评论中指出,它并不像想象的那样“牢不可破”(因为它没有使用printf缓冲其中一个流)。作为记录,我将有问题的代码粘贴到此处:

保留退出状态(仍然牢不可破)

以下变体还传播退出状态some_command到当前外壳:

{
  IFS= read -r -d '' CAPTURED_STDOUT;
  IFS= read -r -d '' CAPTURED_STDERR;
  (IFS= read -r -d '' CAPTURED_EXIT; exit "${CAPTURED_EXIT}");
} < <((({ { some_command ; echo "${?}" 1>&3; } | tr -d '\0'; printf '\0'; } 2>&1- 1>&4- | tr -d '\0' 1>&4-) 3>&1- | xargs printf '\0%s\0' 1>&4-) 4>&1-)

要求: printf, read, tr, xargs

Later, Andy提交了以下“建议编辑”来捕获退出代码:

简单干净的解决方案,节省退出价值

我们可以在末尾添加stderr,第三条信息,另一个NUL加上exit命令的状态。之后就会输出stderr但之前stdout

{
  IFS= read -r -d '' CAPTURED_STDERR;
  IFS= read -r -d '' CAPTURED_EXIT;
  IFS= read -r -d '' CAPTURED_STDOUT;
} < <((printf '\0%s\n\0' "$(some_command; printf '\0%d' "${?}" 1>&2)" 1>&2) 2>&1)

他的解决方案似乎有效,但有一个小问题,即退出状态需要放置为字符串的最后一个片段,以便我们能够启动exit "${CAPTURED_EXIT}"在圆括号内并且不会污染全局范围,正如我在删除的示例中尝试做的那样。另一个问题是,作为他内心深处的输出printf立即被附加到stderr of some_command,我们无法再进行消毒了NUL字节数stderr,因为现在其中还有our NUL分隔符。

试图找到这个问题的正确解决方案是我写下这篇文章的原因§ 5. 保留退出状态 – 蓝图(未经清理),以及以下部分。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 stdout 和 stderr 捕获到不同的变量中 的相关文章

  • apt-get install tzdata 非交互式

    当我尝试 apt get install y tzdata 将显示用于选择时区的命令行选项 我试图在脚本中使用它来进行一些设置 如何在没有用户输入的情况下使 apt get 运行 我知道重新配置 tzdata 我可以做 echo Ameri
  • Linux shell 脚本:十六进制数字到二进制字符串

    我正在 shell 脚本中寻找一些简单的方法来将十六进制数字转换为 0 和 1 字符的序列 Example 5F gt 01011111 是否有任何命令或简单的方法来完成它 或者我应该为其编写一些开关 echo ibase 16 obase
  • 如何通过 shell 脚本确定网页是否存在?

    我正在尝试制作一个程序 可以将一系列漫画扫描转换为一个 pdf 文件 并且我不想尝试下载图片来确定我是否有正确的网址 是否有一个 shell 脚本命令可以用来检查网页是否存在 在 NIX 下 您可以使用curl发出一个简单的HEAD要求 H
  • 如何显示 zsh 函数定义(如 bash“type myfunc”)?

    如何在 zsh 中显示函数的定义 type foo没有给出定义 在bash中 bash function foo echo hello bash foo hello bash type foo foo is a function foo e
  • Bash 脚本大小限制?

    我有一个 bash 脚本 在 RHEL 或 OS X 上运行时出现以下错误 第 62484 行 意外标记 换行符 附近出现语法错误 第 62484 行 o gz 这是一个自动生成的脚本 用于解决我公司使用的 Grid Engine 计算集群
  • 为什么 C# 处理命令行参数的方式不一致?

    在 C 中 直接从 Main 获取命令行参数会省略 exe 名称 这与 C 的传统相反 通过 Environment GetCommandLineArgs 获取相同的命令行参数包括它 对于这种明显的不一致 我是否缺少一些合理的逻辑原因 cl
  • bash 变量中的 Linux 鞭尾/对话框参数错误

    有人可以解释为什么下面的代码不起作用吗 我要疯狂地想找出答案 bin bash TEST M1 1 wire Interface ON echo TEST RESULT dialog title Config Modules State c
  • 给出 5 个参数,但在终端中只得到 3 个参数

    我想将一个文件传递给一个c 程序 如果我在 IDE 中执行此操作 test string string lt test txt return argc 5 但在终端上我刚刚得到argc 3 看来 这是因为 什么是 lt 意思是 我正在使用
  • powershell stdin 管道和重定向

    你好 我一直在制作一个小的跨平台脚 本 我可以将其卷曲并通过管道传输到bash和Powershell中 基本思想是服务器向解释器发送一个命令 然后它给出一个命令将所有输出重定向到标准输出 bash 中的一个例子是 some commands
  • 为什么我不能将 sed 的输出重定向到文件

    我正在尝试运行以下命令 someprogram tee dev tty sed s 2 gt output file 但当我去查看时 该文件始终是空白的 如果我删除 gt output file从命令末尾 我可以看到 sed 的输出 没有任
  • xsel -o 对于 OS X 等效项

    是否有一个等效的解决方案可以在 OS X 中抓取选定的文本 就像适用于 Linux 的 xsel o 一样 只需要当前的选择 这样我就可以在 shell 脚本中使用文本 干杯 埃里克 你也许可以安装xsel在 MacOS 上 更新 根据 A
  • Unix 命令列出包含字符串但*不*包含另一个字符串的文件

    如何递归查看包含一个字符串且不包含另一个字符串的文件列表 另外 我的意思是评估文件的文本 而不是文件名 结论 根据评论 我最终使用了 find name html exec grep lR base maps xargs grep L ba
  • ReferenceError:MongoDB shell 中未定义 require

    我尝试通过 Windows 命令 Windows 8 1 从 Mongo 客户端连接 MongoDB 当我使用require 在 javascript 中 我遇到如下错误 有人有同样的问题吗 我有错过任何一个吗require有关的npm安装
  • 有一种简单的方法可以忽略时间戳来区分日志文件吗?

    我需要比较两个日志文件 但忽略每行的时间戳部分 确切地说是前 12 个字符 有没有一个好的工具 或者一个聪明的 awk 命令 可以帮助我 根据您使用的 shell 您可以改变方法 Blair https stackoverflow com
  • Bash 解析和 shell 扩展

    我对 bash 解析输入和执行扩展的方式感到困惑 对于输入来说 hello world 作为 bash 中的参数传递给显示其输入内容的脚本 我不太确定 Bash 如何解析它 Example var hello world displaywh
  • 在 bash 中使用单个命令为 shell 变量分配默认值

    我对 bash 3 00 shell 脚本中的变量进行了大量测试 如果未设置变量 则它会分配默认值 例如 if z VARIABLE then FOO default else FOO VARIABLE fi 我似乎记得有一些语法可以在一行
  • 通过特定分隔符删除字符串

    我的文件中有几列 其中第二列有 分隔符 我想删除第二列中的第一个 第三个和第四个字符串 并将第二个字符串留在该列中 但我有正常的分隔符空间 所以我不知道 input 22 16050075 A G 16050075 A G 22 16050
  • 仅打印“docker-container ls -la”输出中的“Names”列

    发出时docker container ls la命令 输出如下所示 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a67f0c2b1769 busybox tail f dev
  • 使用 posix shell 测试字符串中的正则表达式

    如何测试字符串是否与特定字符串匹配正则表达式与基本 无 bash 或任何其他 posix shell 脚本 在 if 语句中 您可以使用expr在 POSIX shell 中计算正则表达式的命令 s Abc expr s alpha 3 e
  • grep 两个分隔符之间的子字符串

    我有很多bash使用的脚本perl内的表达式grep为了提取两个分隔符之间的子字符串 例子 echo BeginMiddleEnd grep oP lt Begin End 问题是 当我将这些脚本移植到运行的平台时busybox 融合的 g

随机推荐

  • flash/flex:渐进式下载与 rtmp

    我试图理解并真正确定何时在 Flex flash 中使用渐进式下载与 rtmp 看来主要的一点是 rtmp 不与 http 一起提供服务 而渐进式下载则由 http 提供 由于它不是 rtmp 因此资源受到保护 因为无法从 swf 外部连接
  • 如何检查数据行中是否存在具有给定名称的列

    我想从数据行中的循环插入一个值 因此在数据行中输入值之前 我想检查表中是否存在特定列名称 请告诉我如何检查 首选 vb net 我得到了答案 并且它正在工作 它是 If dr Table Columns Contains columnnam
  • 未提供 Bouncycastle 加密算法

    我正在尝试将 BouncyCastle 与 android 一起使用来实现 ECDH 和 EL Gamal 我添加了 bouncycastle jar 文件 bcprov jdk16 144 jar 并编写了一些适用于我的计算机 jvm 的
  • gluPerspective 与 gluOrtho2D

    我查看了 MSDN 上关于这两个函数的文档 但是 我不太明白这两个功能之间的区别 一个是用于设置 3D 相机视图 另一个是用于设置 2D 相机视图 如果能得到解答就太好了 预先感谢您的评论 正交投影基本上是没有透视的 3D 投影 本质上 这
  • Jenkins 管道中的导出命令

    如何在 Jenkins 管道中添加 导出 unix 命令 我里面有一个詹金斯 舞台 和 步骤 导出命令的语法是什么 我需要使用导出命令设置环境变量 PATH 您可以更新 PATH像这样 pipeline agent label docker
  • 使用perl求中位数、众数、标准差?

    我有一个数字数组 计算数据集的中位数 众数和标准差的最简单方法是什么 Statistics Basic Mean http p3rl org Statistics Basic Mean Statistics Basic Median htt
  • MySQL 索引创建速度很慢(在 EC2 上)

    我有一张相当简单的桌子 requestparams requestid varchar 64 NOT NULL requestString text ENGINE MyISAM 使用 LOAD DATA 填充表后 我正在更改架构并将 req
  • 如何安排函数在 Qt for Python 的主 UI 线程上运行?

    我正在移植一个 Python GTK 应用程序 因此它使用 Qt for Python PySide2 它使用Python标准实现工作线程threading模块和工作线程使用Gdk threads add idle 与主 GUI 线程交互
  • Jetty9 - Jetty 不是从单独的 {jetty.base} 运行

    在启动 jetty9 服务器作为服务时 我看到以下警告 我对此一无所知 警告 oejs HomeBaseWarning main Jetty 的此实例不是从单独的 jetty base 目录运行 不建议这样做 请参阅文档 http www
  • Case 表达式在 SQL 查询中无法正常工作

    我想连接列supplier使用逗号分隔符创建表并将其放入名为 contact 的别名字段中 我使用过检查空值的案例 假设如果contact number2则为空contact number3将在别名字段中 反之亦然 这是我的查询 SELEC
  • 如何将html设置为extjs中的元素

    1 如何设置HTML到已经创建的面板或任何其他元素 我是初学者 我尝试了下面的方法来设置 HTML 中的一些内容 var clickedElement Ext getCmp id el child gt clickedElement set
  • “排序文件名 | uniq”不适用于大文件

    我可以从小文本文件中删除重复条目 但不能从大文本文件中删除重复条目 我有一个 4MB 的文件 文件的开头如下所示 aa aah aahed aahed aahing aahing aahs aahs aal aalii aalii aali
  • 可扩展性和弹性有什么区别?

    我听说很多人交替使用这两个术语 但在我看来 它们之间还是有区别的 可扩展性 的能力软件系统在其当前硬件资源上处理更大的工作负载 scale up 或当前和额外的硬件资源 向外扩展 应用程序服务不中断 弹性 的能力硬件层下面 通常是云基础设施
  • 在命令行上编译 C++/CX

    我收到链接器错误fatal error C1107 could not find assembly platform winmd please specify the assembly search path using AI or by
  • 尝试构建我的 CUDA 程序时出现错误 MSB4062

    当我尝试构建我的第一个 GPU 程序时 出现以下错误 有什么建议可能会出什么问题吗 错误 1 错误 MSB4062 Nvda Build CudaTasks SanitizePaths 任务 无法从程序集 C Program 加载 文件 M
  • 如何处理 Ipython Notebook 中的引用?

    在 Ipython Notebook 中处理引用的最佳方法是什么 理想情况下 我想要一个 bibtex 文件 然后像在 Latex 中一样 在 Ipython markdown 单元格中拥有一个速记列表 并在笔记本末尾提供完整的参考文献 我
  • 截断浮点数而不向上舍入

    我有一个浮点数 我想将其截断为 3 位 但我不想向上舍入 例如 转换1 0155555555555555 to 1 015 not 1 016 我将如何在 Ruby 中做到这一点 您还可以转换为 BigDecimal 并对其调用 trunc
  • 为应用程序创建了新的 WidgetKit 扩展:SwiftUI 预览不适用于“appex 必须位于应用程序中”

    我使用的是 macOS 12 6 上的 Xcode 14 0 1 我正在尝试使用 WidgetKit 在现有应用程序中创建一个新的手表复杂功能 首先向我的项目添加一个 Widget 扩展模板目标 这会生成一个新文件夹 其中包含意图定义文件
  • UI 引导轮播第一张幻灯片不显示,然后在最后一张幻灯片崩溃

    我正在尝试实现 ui bootstraps 轮播 但是当页面加载时 第一个图像不会显示 但控件和指示器会显示 然后 当第二个图像显示时 我可以使用控件返回到第一个图像 它将显示正常 我可以使用控件到达最后一张幻灯片或让它自动滑动 但是当我到
  • 将 stdout 和 stderr 捕获到不同的变量中

    是否可以存储或捕获 stdout 和 stderr不同的变量 不使用临时文件 现在我这样做是为了获得标准输出out和标准错误err跑步时some command 但我会 喜欢避免临时文件 error file mktemp out some