通过子进程对WSL的fish执行命令

Execute commands on fish of WSL via subprocess

我已经安装了 WSL(Ubuntu),现在我想从 WSL 访问 fish 并从中执行 date 之类的命令。我该怎么做?

这是我的尝试!

import subprocess
subprocess.run(["wsl", "fish"], shell=True)
subprocess.run(["date"], shell=True)

输出显示执行到代码的第 2 行,但不显示 date 命令在 fish 终端中的执行。有什么解决办法吗?

第一个 subprocess.run 将启动一条互动鱼 shell。

只有当您键入 exit 时,date 才会 运行。

根据您的命令,第一个 subprocess.run() 会启动一个进程,然后等待它完成。如您所知,wsl fish 实际上不会自行完成,这意味着您的 python 应用现在将无限期阻塞。

您真正想要做的是启动一个进程,通过其 STDIN 向其发送数据,并读取其 STDOUT 输出。

虽然你不能完全这样做 - 对于 1,你不想阻止解释器!

proc = Popen(["wsl", "fish"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, err = proc.communicate(b"date")
print(output)

communicate 也会阻塞。如果你想保留这个 运行 你会做 proc.stdin.write() 然后 proc.stdout.readline()

假设您只想捕获输出,最有效的调用应该是:

cp = subprocess.run(["wsl", "-e", "date"], capture_output=True)
date = cp.stdout

通过指定 -e,您可以完全跳过 shell,这避免了 shell 启动的开销。

如果您确实想在 fish 内将其强制为 运行:

cp = subprocess.run(["wsl", "-e", "fish", "-c", "date"], capture_output=True)
date = cp.stdout

更多详情:

如果 fish 是您的默认 shell,那么您真的不需要将其指定为 wsl 命令的参数。您可以通过在 PowerShell 或 CMD 中尝试以下操作来查看:

wsl ps -eH
  PID TTY          TIME CMD
    1 ?        00:00:00 init
   21 ?        00:00:00   init
   22 ?        00:00:00     init
   23 pts/0    00:00:00       fish
   30 pts/0    00:00:00         ps

注意ps命令,虽然WSL命令行上没有fish运行,但在默认shell下仍然运行s。

但是,您没有。如果命令不需要 shell,您可以直接 运行 它而无需通过 shell(避免开销)通过:

wsl -e ps -ef
  PID TTY          TIME CMD
    1 ?        00:00:00 init
   11 ?        00:00:00   init
   12 ?        00:00:00     init
   13 pts/0    00:00:00       ps

您会注意到没有 shell 是 运行ning。这是我在上面推荐的 Python.

中的 ["wsl","-e","date"] 的变体

假设 fish 不是您的默认设置 shell,但您确实希望它是 运行。

wsl -e fish -c "ps -eH"
  PID TTY          TIME CMD
    1 ?        00:00:00 init
   20 ?        00:00:00   init
   21 ?        00:00:00     init
   22 pts/0    00:00:00       fish
   29 pts/0    00:00:00         ps

但不要wsl fish "ps -eH"(或wsl fish -c date)。那会运行鱼中鱼,非常浪费:

   PID TTY          TIME CMD
    1 ?        00:00:00 init
   11 ?        00:00:00   init
   12 ?        00:00:00     init
   13 pts/0    00:00:00       fish
   20 pts/0    00:00:00         fish
   22 pts/0    00:00:00           ps