通过子进程对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
我已经安装了 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