linux - 为什么在非交互式 bash session 中运行 gradlew 会关闭 session 的标准输入?

标签 linux bash gradle posix

我注意到使用 gradlew 时脚本在 CI 系统中早期成功退出的奇怪问题。 。以下步骤有助于概述这一点。

  1. 创建一个名为 script 的文件内容如下:

    ./gradlew
    echo DONE
    
  2. 获取随机 gradlew来自某处

  3. 运行cat script | bash

请注意,DONE 永远不会出现

AFAICT,以非交互方式运行 bash 会导致 exec java blahgradlew 末尾以某种方式允许java关闭stdin并且永远不允许 echo DONE从通过 stdin 从 cat 读取的脚本中读取。支持这一点的事实是:

  • 将脚本更改为 ./gradlew; echo DONE将打印完成
  • 替换 ./gradlew./gradlew < /dev/null将打印完成

最佳答案

如果您在某处(在您的情况下在 gradlew 内)有一个 exec Something ,您将用以下内容替换当前进程镜像 (bash)其他东西(java)。

来自帮助执行:

exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.

所以问题不在于 stdin 被关闭,发生的事情是新进程 (java) 将是读取该输入的进程 ( “echo DONE”),并且可能不执行任何操作。


举例说明

考虑这个 script.sh:

#!/bin/bash

echo Hello
exec cat
echo World

如果您执行它,为 cat 提供一些输入:

$ ./script.sh <<< "Nice"
Hello
Nice

您可能还期望屏幕上打印出世界一词...错误!
这里没有任何反应,因为在 exec 命令之后执行了其他任何操作。

现在,如果您将脚本通过管道传输到 bash:

$ cat script.sh | bash
Hello        <- bash interpreted "echo Hello" and printed Hello
echo World   <- cat read "echo World" and printed it (no interpertation ocurred)

在这里您可以清楚地看到正在执行的流程图像替换

关于linux - 为什么在非交互式 bash session 中运行 gradlew 会关闭 session 的标准输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50147013/

相关文章:

php - $_FILES 空 - 撕扯我的头发

c++ - 适用于 Linux 的类似 Windows 的消息框 - 这个 C++/Motif 实现是否可行?

android - Gradle 'demo' 项目刷新失败 : Could not fetch model of type 'IdeaProject' using Gradle installation

java - Gradle 配置不适用于两组配置文件和依赖项

Python 替换语句

linux - 在 Windows 中运行时的 CUDA 性能损失

macos - shebang emacs --脚本作为 bash 运行

linux - 查找:-exec 缺少参数不复制

bash - 如何从 Visual Studio 2017(基于目录的项目)中的任意构建任务运行 bash?

android - Gradle Android测试