无法从 Go 应用程序运行 `op`

问题描述 投票:0回答:3

我正在尝试围绕 1Password CLI 可执行文件编写一个小型 Go 包装应用程序

op
,如下所示:

package main

import (
    "fmt"
    "log"
    "os/exec"
)

func main() {
    op := exec.Command("op", "item", "list")
    out, err := op.Output()
    if e, ok := err.(*exec.ExitError); ok {
        log.Fatal(e, ": ", string(e.Stderr))
    }
    fmt.Println(string(out))
}

但是,我不断收到以下错误:

2023/04/13 09:48:51 exit status 1: [ERROR] 2023/04/13 09:48:51 error initializing client: connecting to desktop app: read: connection reset, make sure the CLI is correctly installed and Connect with 1Password CLI is enabled in the 1Password app

但是当我从 Python 脚本中执行同样的操作时,如下所示:

#!/usr/bin/env python

import subprocess

subprocess.run(["op", "item", "list"])

...我得到的输出很好。

有趣的是,当我从 Go 应用程序调用 Python 脚本(名为

op.py
时,它工作正常(修改后的 Go 应用程序如下所示):

package main import ( "fmt" "log" "os/exec" ) func main() { op := exec.Command("/usr/bin/python3.11", "./op.py") //op := exec.Command("op", "item", "list") out, err := op.Output() if e, ok := err.(*exec.ExitError); ok { log.Fatal(e, ": ", string(e.Stderr)) } fmt.Println(string(out)) }
我可以测试它是由 Go 应用程序打印的,而不是由 Python 脚本打印的,因为如果我删除 

fmt.Printf(...)

,则不会打印任何内容。

总结一下:

    Go ->
  • op
    :不起作用
  • Python (
  • ./op.py
    ) -> 
    op
    :工作正常
  • Go -> Python (
  • ./op.py
    ) -> 
    op
    :工作正常
go subprocess ipc 1password
3个回答
2
投票
我从

op

 虚拟环境访问 
pyenv
 时遇到同样的问题。我认为问题在于 pyenv 的 
python
 可执行文件由用户(我)拥有。
将所有权更改为root:Python解释器的root及其所在目录实际上有所帮助。不知道幕后发生了什么。

以下是步骤(我使用

--copies

 创建虚拟环境,因此它不使用符号链接 - 因为符号链接会指向根拥有的文件):

$ python -m venv --copies .venv $ .venv/bin/python -c "import subprocess; subprocess.call(['op', 'signin'])" [ERROR] 2023/05/16 16:01:18 connecting to desktop app: read: connection reset, make sure the CLI is correctly installed and Connect with 1Password CLI is enabled in the 1Password app # chown -R root:root .venv/ $ .venv/bin/python -c "import subprocess; subprocess.call(['op', 'signin'])" Select account [Use arrows to move, type to filter]
底线:将生成 

op

 子进程的可执行文件(及其所在目录)的所有权更改为 
root:root

另请参阅 1Password 上的此帖子,它看起来像是同一个问题:

https://1password.community/discussion/135768/calling-the-cli-from-a-go-program



-2
投票
我实际上使用 GoLang 作为覆盖 GUI 应用程序,它作为集中控制器与几个不同的 cpp 二进制文件进行通信。我已经实现了以下函数来运行通用命令:

func RunCmd(binary string, cmd []string) []string { var output []string c, b := exec.Command(binary, cmd...), new(bytes.Buffer) c.Stdout = b c.Run() s := bufio.NewScanner(b) for s.Scan() { output = append(output, s.Text()) } return output }
此函数运行命令并将输出作为字符串切片返回(每行输出一个)。这是调用它的示例:

_ = RunCmd("./moveRobot", []string{"10.20.0.37", localIP.String(), "align"})
在您的示例中,您可以将其称为:

out = RunCmd("op", []string{"item", "get", "DocSend", "--format=json"})
您也可能需要提供 

op

 二进制文件的路径,所以我会尝试(如果它位于同一目录中,则使用 
./op

这显然不会按原样返回 JSON 格式的输出,但您可以使用它作为起点,至少确认调用是否正常工作。

© www.soinside.com 2019 - 2024. All rights reserved.