发布
社区首页 >问答首页 >捕获由另一个命令启动的ssh-add输出。

捕获由另一个命令启动的ssh-add输出。
EN

Stack Overflow用户
提问于 2021-02-28 00:04:07
回答 1查看 131关注 0票数 0

这是我问题的完整版本。我包括所有这些细节,以防我的预感是错误的,但你可能想跳到tl;博士下面。

我正在尝试编写一个函数,该函数运行任意命令,并捕获是否将任何输出打印到终端。我不想干扰正在打印的输出。如果这是一个相关的复杂(可能不是),我还想分支到命令的退出代码。

我现在拥有的是:

代码语言:javascript
代码运行次数:0
复制
function run_and_inspect {
    # this subshell ensures the stdout of ${@} is printed and captured
    if output=$(
        set -o pipefail
        "${@}" | tee /dev/tty
    ); then
        did_cmd_work="yes"
    else
        did_cmd_work="no"
    fi

    if [ -z "$output" ]; then
        was_there_output="no"
    else
        was_there_output="yes"
    fi

    echo "output?" $was_there_output
}

一般来说,这样做很好:

代码语言:javascript
代码运行次数:0
复制
$ run_and_inspect true
output? no

$ run_and_inspect "echo hello"
hello
output? yes

但我找到了一个问题命令:

代码语言:javascript
代码运行次数:0
复制
git pull | grep -v 'Already up to date.'

如果没有什么可拉的,这条管道通常不会产生输出。但是,如果ssh-add需要提示输入密码,就会有输出。只是没有被run_and_inspect注意到

代码语言:javascript
代码运行次数:0
复制
function git_pull_quiet {
    git pull | grep -v 'Already up to date.'
}

$ run_and_inspect git_pull_quiet
Enter passphrase for key '/home/foo/.ssh/id_ed25519':
output? no

有输出到我的终端。我认为问题在于它不是来自git pull管道的标准输出,这是run_and_inspect所知道的。它是从哪里来的?我该怎么解决这个问题?我也尝试过重定向stderr (即git pull 2>&1),但是没有运气。有什么方法可以直接监视/dev/tty吗?

tl博士(我想!)

我认为这个问题归结为:为什么密码在log.txt中没有提示?

代码语言:javascript
代码运行次数:0
复制
$ git pull 2>&1 | tee log.txt
Enter passphrase for key '/home/foo/.ssh/id_ed25519':
Already up to date.
$ cat log.txt
Already up to date.
EN

回答 1

Stack Overflow用户

发布于 2021-03-01 00:29:05

为什么密码提示不在log.txt中?

提示符是用文件passphrase()打印的。该函数使用TTY "/dev/tty“执行open(_PATH_TTY,然后对其执行write()

输出直接显示给终端/dev/tty,而不是标准流。

就像您使用tee /dev/tty一样,这意味着您的函数也将无法工作。更愿意保持子程序的稳健性和缓冲性:

代码语言:javascript
代码运行次数:0
复制
if { tmp=$("$@" > >(tee >(cat >&3))); } 3>&1; then

有什么方法可以直接监视/dev/tty吗?

编写您自己的终端模拟器并在其中生成您的进程,然后解析该终端模拟器中的所有输入。像screentmux这样的程序可能是有用的。

解决方法可以是下载proot并打开文件描述符到某个文件,然后创建一个只有/dev/tty文件符号链接到/proc/self/fd/<that file descriptor>的chroot,然后在该chroot中运行带有proot的进程。其思想是,进程将看到带有/dev/tty文件的chroot被替换,并将写入文件描述符,而不是写入终端。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66404663

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档