[英]Print man contents as help prompt of a C program
我计划使用pandoc
从 markdown 为一个非常小的 C 程序生成man
文件。
我不想重复自己并在程序的源代码中键入帮助提示( command [ -h | --help ]
)。
问:我能否在 C 程序的编译时永久包含文件中的 man 内容?
或者
问: C中有没有办法将安装的手册页的内容打印到标准输出?
根据@KamilCuk 的回答,这就是我正在做的事情:
在终端:
file command.1
# OUTPUT --> command.1: troff or preprocessor input, ASCII text
xxd -i command.1 > command.hex
然后在main.c
#include "command.hex"
printf("%s", command_1);
这几乎正是我想要的,除了
man
和 pipe output。我所说的帮助提示是什么意思:
git --help
打印到标准输出git --help branch
,它为 git-branch 打开了 man但是,也请分享后者。 这不是我想要的:我的手册很短; 但如果不是我所寻求的那种,我会很高兴学习另一种选择。
man
程序我可以在编译时永久包含文件中的 man 内容吗?
您可以在编译时包含任何文件的任何内容。 最简单的是使用xxd -i
并编译 output。
C 中有没有办法打印安装的手册页的内容?
您可以从man -k
troff output
您可以通过沿MANPAGER=cat man
替换寻呼机从man
获取 output 。
在 C 中: setenv("MANPAGER", "cat"); execp("man", (char*[]){"man", "something", 0});
setenv("MANPAGER", "cat"); execp("man", (char*[]){"man", "something", 0});
或者只是system("MANPAGER=cat man some_command")
。
手册页并不总是安装到同一位置
并且系统管理员可以使用/etc/man_db.conf
来配置man
命令的行为。
某些系统中可能未安装手册页; 或者可能没有 man 程序
因此,此类系统的用户似乎并不关心手册页,因此支持此类情况毫无意义。
我相信您的意图是从您的程序中呈现一个手册页,其中您保存了 static troff 输入并希望使用man
来显示它。 您可以将输入保存到文件中,保存并将文件名传递给man
- man 将解析 troff 并渲染它。 或者您可以使用通常的pipe()+fork()+exec()
并从一个进程将 troff 数据传递给 stdin 到man -
- -
将使man
从 stdin 读取 troff 输入。
C 中有没有办法将安装的手册页的内容打印到标准输出?
您可以使用 pipe stream 来调用man
命令。 Function popen
就是您要找的。 更多信息在这里。
这是一个fgets()
解决方案,但您可能需要小心,以防您想阅读更多字符。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp = NULL;
char buffer[1000];
fp = popen("man man","r");
if (fp == NULL)
{
/* error running the command */
exit(EXIT_FAILURE);
}
while (fgets(buffer,sizeof(buffer),fp))
{
puts(buffer);
}
fclose(fp);
return 0;
}
getline()
解决方案,以防您不知道要读取多少字节。
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp = NULL;
char *buffer = NULL;
size_t len = 0U;
ssize_t nread = 0;
fp = popen("man man","r");
if (fp == NULL)
{
/* error running the command */
exit(EXIT_FAILURE);
}
/* getline will set errno uppon failure, you might want to check that too */
while ((nread = getline(&buffer,&len,fp)) != -1)
{
buffer[nread] = 0; /* NULL terminate your buffer */
puts(buffer);
}
free(buffer);
fclose(fp);
return 0;
}
更多关于getline()
的信息。
man
程序是用 C 编写的,并且是开源的。 它比您想象的要复杂,因为它处理终端(及其宽度)。 另请参见termios(3)和tty(4) 。 请注意ANSI 转义码和ncurses库。 考虑到在 2021 年UTF-8 到处都在使用,并且一些man
页可能包含§
或°
字符。 还要注意国际化和本地化问题,请参阅locale(7) 。 在法国,很多 Linux 系统都安装了法语man
页。
因此,您可以获得man-db
package 的源代码,研究它,并将其合并到您的程序中。
我的观点是这样做是愚蠢的。
您可以改为阅读Advanced Linux Programming ,研究各种syscalls(2) ,并使用fork(2) 、 execve(2) 、 waitpid(2)运行现有和安装的/usr/bin/man
程序(可以测试其存在在 C 代码中使用test(1)或access(2)或stat(2) ;但如果它不存在,您的execve(2)将失败...)
关于--help
的显示,您可以使用(如果允许)GNU libc 程序参数解析工具,并从现有自由软件程序的源代码中获取灵感,例如GNU coreutils 。
当然,您的构建基础架构(例如,如果您使用GNU make构建软件,您的Makefile
)可以运行程序来共享数据和文本描述。 您可以(如果允许)在构建时使用开源工具生成一些 C 代码(例如#include
d stuff),例如GNU m4 、 GNU gawk 、 GPP等。
还可以从git的源代码中获取灵感。 它是开源的(对你有用):你可以下载它的源代码并学习它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.