如何检测命令是否未应答
How to detect if a command was not answered
我正在创建一个在终端上发送命令的程序:
cmus-remote -Q
输出:
status stopped
set aaa_mode album
set continue false
set play_library true
set play_sorted false
set replaygain disabled
set replaygain_limit true
set replaygain_preamp 6.000000
set repeat false
set repeat_current false
set shuffle false
set softvol false
set vol_left 0
set vol_right 0
此命令返回我的音乐播放器的状态 ( cmus
),但有时播放器已关闭并且不响应我的命令。
我的目标是确定何时没有得到答案并关闭程序并再次打开它(C++)。我知道如何杀死它并重新开始。我尝试使用popen()
功能的东西,但我不知道如何使用它。我该怎么做?
就可以用C++编译的 C 函数而言(对标头进行适当的更改,并在适当的情况下添加using namespace std;
)。 您需要查看播放器运行时来自cmus-remote -Q
的状态消息 - 我假设"状态就绪",但如果有多个响应("状态正在播放","状态暂停",...),那么您需要适当地修改代码。 我还假设您只需要响应的第一行。 同样,如果这是错误的,则必须对代码进行相应的更改。
bool is_cmus_running(void)
{
char buffer[4096];
FILE *fp = popen("cmus-remote -Q", "r");
if (fp == 0)
return false;
char *rv = fgets(buffer, sizeof(buffer), fp);
pclose(fp);
if (rv == 0 || strncmp(buffer, "status ready", sizeof("status ready") - 1) != 0)
return false;
return true;
}
对于 C99,您需要:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
对于C++,我认为您可以使用相同的标头,但您也可以使用:
#include <cstdio>
#include <cstring>
using namespace std;
(您不需要bool
标头,因为它以 C 中没有的方式内置到 C++ 中。
(1)我会以更简单的方式做到这一点,除非有特定的原因坚持C++。一个基本的 shell 脚本可以完美地完成这项工作,类似于 cplay
脚本 (https://wiki.archlinux.org/index.php/Cmus#Remote_Control):
$ ps h -C cmus || cmus
由于 Cmus 不是一个真正的后台服务,例如,如果没有 ncurses GUI,您将无法启动它 - 最好是在屏幕会话中运行它。
$ screen -rD cmus || screen -dmS 'cmus' /usr/bin/cmus
使用此命令,您始终在屏幕会话中运行 cmus 会话。您甚至可以关闭终端,该服务将在后台继续运行。只需将此命令作为别名放入您的 .bashrc,您就可以始终轻松访问播放器
$ alias mycmus='screen -rD cmus || screen -dmS 'cmus' /usr/bin/cmus'
如果未运行,将启动 cmus+screen 会话,否则将打开会话。"Ctrl+a d"分离窗口。
将它们放在一起并回答您的问题(在 shell 脚本中):
将以下行添加到文件中,例如:"mycplayer.sh
"(不要忘记chmod +x mycplayer.sh
,然后将其添加到 PATH 中)
#!/bin/sh
cmus-remote -Q > /dev/null || screen -dmS 'cmus' /usr/bin/cmus
cmus-remote $1
第一行将确保有一个正在运行的 cmus 实例(在后台,使用屏幕),第二行将执行远程命令。
用法:
$ mycplayer.sh -u start/stop the player
$ mycplayer.sh -n next in the playlist
etc.
(2)在C++
使用 stat(2) 检查是否有 CMUS 的套接字/home/user/.cmus/socket
如果没有进程运行,请使用 exec+fork 执行它(分叉和高管的区别)
(3)如果cmus
是网络服务,所以它是用--listen host[:port]
启动的,那么你需要一个ssh来启动远程盒子上的服务。请参阅上面的屏幕命令如何操作。
希望这有帮助。
- 是否可以在命令行中将输入参数传递给可执行文件
- 是否有正确的方法对生成文件中的对象文件使用模板命令?(C++)
- 即使在多任务处理时,添加用户时间 + 系统时间(来自 shell 的时间命令)是否是一种可靠的措施?
- 在Xcode(mac api)上,是否有任何带有Sleep()函数/命令的文件?
- 是否有任何 MSBuild 命令行选项可以动态禁用 c++ 项目的代码分析?
- 是否有 gcc 命令可以链接同一目录中的所有 .o 文件并生成.exe文件
- 是否有 tbb::p arallel_for 的中断命令
- 是否可以通过图形用户界面 (GUI) 与 Linux 命令行界面 (CLI) 进行交互
- 是否有一个windbg命令来检索转储的module_name
- 如何知道命令行中是否提供了 gflag
- C++ - 是否有任何命令像 addr2line 在 Windows 上
- 在命令行程序中使用布尔值。找不到定义标志并检查它们是否在参数中的方法
- 在执行 Linux 命令之前了解它是否存在的方法
- 是否可以通过命令行将VBScript数组传递到C EXE
- 是否有一个WinAPI可以从带有可选空格和其他参数的命令行获取文件名
- 是否可以将依赖项嵌入到命令行工具中
- 是否可以使用C++中的一个make命令,用两个不同的gcc版本编译两个不同可执行文件
- TCLAP:如何检查是否指定了可选的命令行参数
- 确定命令行程序是否C++安装
- 如何检测命令是否未应答