bluetoothctl 是一个具有 shell 并接受输入命令的应用程序。我想从 Linux 的 shell 任意向它发送命令,并且我还想不带颜色地读取它的输出。我使用的是基于 debian 的 linux (Raspbian buster),如果可能的话,我想从 bash shell 执行此操作。
到目前为止我已经尝试过:
方法一(通过fd发送命令)
- 运行附加的进程:
$ bluetoothctl
- 然后从另一个终端:
$ echo "my command">/proc/$(pidof bluetoothctl)/fd/0
和$ echo -e "my command\n">/proc/$(pidof bluetoothctl)/fd/0
和$ echo -e "my command\013">/proc/$(pidof bluetoothctl)/fd/0
但我的命令
只是显示为bluetoothctl的输出,甚至在程序终端中按键盘上的“enter”键根本不会执行该命令,只是给出一个新行。
方法二(将输出写入文本文件)
- 分离运行进程:
$ bluetoothctl > my.output &
,但它会立即从应用程序退出
方法三(通过管道发送命令)
- 创建管道
mkfifo mypipe
- 将管道重定向到 bluetoothctl
cat mypipe | bluetoothctl > my.output
- 向管道写入命令
echo "my command"> mypipe
,但会立即关闭应用程序,应用程序没有时间异步处理该命令。因此,不起作用。
我相信可行的解决方案是启动分离的应用程序 $ bluetoothctl &
,然后通过 /proc/$(pidof bluetoothctl)/fd/0 向其发送命令
并通过 /proc/$(pidof bluetoothctl)/fd/1
和 /proc/$(pidof bluetoothctl)/fd/2
读取其 stdout 和 stderr 但我完全迷失了。
我想要执行并读取其输出的命令之一是“扫描”,理想情况下,一个 bluetoothctl 实例将处理多个命令,而不仅仅是管道可以执行的命令。 有人可以告诉我如何通过 fd 发送命令,以及如何通过进程的另一个 fd 读取输出。如果可能的话,所有这些都在 bash shell 中进行。
最佳答案
一个coprocess是适合这项工作的工具:
#!/usr/bin/env bash
case $BASH_VERSION in ''|[0-3].*|4.0*) echo "ERROR: bash 4.1+ required" >&2; exit 1;; esac
coproc btctl { bluetoothctl; }
echo "scan on" >&"${btctl[1]}"
while IFS= read -r -u "${btctl[0]}" line; do
echo "Read line from btctl: $line" >&2
done
关于bash - 向应用程序发送命令并通过 bash 中的文件描述符读取其输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64808659/