默认
QNAP
是不带man
命令的,但是,作为一个Linux
重度用户怎么能忍?得想办法安装man啊!经过一番努力,最终成功安装man pages!
需求
默认QNAP
是不带man
命令的,但是,作为一个Linux
重度用户怎么能忍?
得想办法安装man啊!
验证
先试一下
# man
-sh: man: command not found
基本可以死心了。
看看busybox版本
# /bin/busybox
BusyBox v1.24.1 (2022-03-24 03:13:07 CST) multi-call binary.
BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list
or: function [arguments]...
BusyBox is a multi-call binary that combines many common Unix
utilities into a single executable. Most people will create a
link to busybox for each function they wish to use and BusyBox
will act like whatever it was invoked as.
Currently defined functions:
[, [[, addgroup, adduser, arping, ash, awk, base64, basename, bunzip2, bzcat, bzip2, cat, chattr, chgrp, chmod, chown,
chroot, chvt, cksum, clear, cmp, cp, cpio, crond, crontab, cut, date, dc, dd, deallocvt, delgroup, deluser, depmod, df,
diff, dirname, dmesg, dnsdomainname, dos2unix, du, echo, egrep, env, expr, false, fdisk, fgrep, find, free, fsync, getty,
grep, groups, gunzip, gzip, halt, hd, head, hexdump, hostname, hwclock, id, ifconfig, init, insmod, install, ip, ipaddr,
iplink, iproute, iprule, iptunnel, kill, killall, killall5, klogd, less, linuxrc, ln, logger, login, logread, ls, lsattr,
lsmod, lspci, md5sum, mkdir, mknod, mktemp, modprobe, more, mount, mv, nameif, netstat, nslookup, openvt, passwd, pidof,
ping, ping6, pivot_root, poweroff, printf, ps, pwd, rdate, readlink, realpath, reboot, renice, reset, resize, rm, rmdir,
rmmod, route, sed, seq, sh, sha1sum, sleep, sort, split, start-stop-daemon, stat, strings, swapoff, swapon, switch_root,
sync, sysctl, syslogd, tail, tar, taskset, tee, telnet, test, tftp, time, top, touch, tr, traceroute, traceroute6, true,
tty, umount, uname, uniq, unix2dos, unzip, uptime, usleep, vi, watch, wc, wget, which, whoami, xargs, yes, zcat
可以看到内置busybox
不支持man
的。
寻找解决方案
去看看官方Busybox
是否支持
发现是支持man
的,只是QNAP
没有编译进去。
解决思路
- 给
QNAP
提需求单? 是一个选择,但是太慢了,想官方内置,不知道等到猴年马月了。 QNAP
似乎开发了底层SDK,记得有下载过,还没有仔细研究怎么使用。不过记得有附带编译工具链,自己动手编译一个busybox
版本替代系统内置的,应该也是可行的。
去看看别人有啥解决方案?
Optware has man but only for the optware installed packages (if supplied) and or manually added files in the man folder.
柳暗花明又一村, entware
支持man pages
,可以直接安装了。
插入
entware
安装方法:打开
App Center
,源选择刚添加的Qnapclub
,点击搜索框输入entware
,选Entware-std 1.03
一条命令解决:
opkg install man-db man-pages
安装完之后验证:
# man fopen
FOPEN(3) Linux Programmer's Manual FOPEN(3)
NAME
fopen, fdopen, freopen - stream open functions
SYNOPSIS
#include <stdio.h>
FILE *fopen(const char *restrict pathname, const char *restrict mode);
FILE *fdopen(int fd, const char *mode);
FILE *freopen(const char *restrict pathname, const char *restrict mode,
FILE *restrict stream);
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
fdopen():
_POSIX_C_SOURCE
DESCRIPTION
The fopen() function opens the file whose name is the string pointed to by pathname and associates a stream with it.
The argument mode points to a string beginning with one of the following sequences (possibly followed by additional char‐
acters, as described below):
r Open text file for reading. The stream is positioned at the beginning of the file.
r+ Open for reading and writing. The stream is positioned at the beginning of the file.
w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the
file.
w+ Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is
positioned at the beginning of the file.
问题就这么解决了。
一个问题,我有很多其它手册,想要安装,怎么办?
安装其它man
手册
已经有了man
命令,只要把手册安装到entware man
命令目录中就行了。
找到enteware man
手册目录。
cd /share/CACHEDEV3_DATA/.qpkg/Entware
find . -name "*man*"
TIPS:
CACHEDEV3_DATA/.qpkg
这个是安装qpkg软件的磁盘。CACHEDEV3
似乎是表示第三块插入机器的磁盘。
结果输出:
./bin/catman
./bin/go/misc/chrome/gophertool/manifest.json
./bin/go/pkg/linux_amd64/cmd/vendor/github.com/ianlancetaylor/demangle.a
./bin/go/src/cmd/compile/internal/types2/testdata/manual.go2
./bin/go/src/cmd/go/internal/modconv/testdata/dockerman.glide
./bin/go/src/cmd/go/internal/modconv/testdata/dockerman.out
./bin/go/src/cmd/go/internal/modconv/testdata/govmomi.vmanifest
./bin/go/src/cmd/go/internal/modconv/vmanifest.go
./bin/go/src/cmd/go/testdata/script/mod_convert_vendor_manifest.txt
./bin/go/src/cmd/go/testdata/script/mod_list_command_line_arguments.txt
./bin/go/src/cmd/go/testdata/script/mod_download_too_many_redirects.txt
./bin/go/src/cmd/go/testdata/script/gccgo_mangle.txt
./bin/go/src/cmd/vendor/github.com/google/pprof/internal/driver/commands.go
./bin/go/src/cmd/vendor/github.com/ianlancetaylor/demangle
./bin/go/src/cmd/vendor/github.com/ianlancetaylor/demangle/demangle.go
./bin/go/src/compress/bzip2/huffman.go
./bin/go/src/compress/flate/huffman_bit_writer.go
./bin/go/src/compress/flate/huffman_bit_writer_test.go
./bin/go/src/compress/flate/huffman_code.go
./bin/go/src/compress/flate/testdata/huffman-null-max.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-null-max.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-null-max.golden
./bin/go/src/compress/flate/testdata/huffman-null-max.in
./bin/go/src/compress/flate/testdata/huffman-null-max.wb.expect
./bin/go/src/compress/flate/testdata/huffman-null-max.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-pi.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-pi.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-pi.golden
./bin/go/src/compress/flate/testdata/huffman-pi.in
./bin/go/src/compress/flate/testdata/huffman-pi.wb.expect
./bin/go/src/compress/flate/testdata/huffman-pi.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-rand-1k.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-rand-1k.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-rand-1k.golden
./bin/go/src/compress/flate/testdata/huffman-rand-1k.in
./bin/go/src/compress/flate/testdata/huffman-rand-1k.wb.expect
./bin/go/src/compress/flate/testdata/huffman-rand-1k.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-rand-limit.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-rand-limit.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-rand-limit.golden
./bin/go/src/compress/flate/testdata/huffman-rand-limit.in
./bin/go/src/compress/flate/testdata/huffman-rand-limit.wb.expect
./bin/go/src/compress/flate/testdata/huffman-rand-limit.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-rand-max.golden
./bin/go/src/compress/flate/testdata/huffman-rand-max.in
./bin/go/src/compress/flate/testdata/huffman-shifts.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-shifts.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-shifts.golden
./bin/go/src/compress/flate/testdata/huffman-shifts.in
./bin/go/src/compress/flate/testdata/huffman-shifts.wb.expect
./bin/go/src/compress/flate/testdata/huffman-shifts.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-text-shift.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-text-shift.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-text-shift.golden
./bin/go/src/compress/flate/testdata/huffman-text-shift.in
./bin/go/src/compress/flate/testdata/huffman-text-shift.wb.expect
./bin/go/src/compress/flate/testdata/huffman-text-shift.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-text.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-text.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-text.golden
./bin/go/src/compress/flate/testdata/huffman-text.in
./bin/go/src/compress/flate/testdata/huffman-text.wb.expect
./bin/go/src/compress/flate/testdata/huffman-text.wb.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-zero.dyn.expect
./bin/go/src/compress/flate/testdata/huffman-zero.dyn.expect-noinput
./bin/go/src/compress/flate/testdata/huffman-zero.golden
./bin/go/src/compress/flate/testdata/huffman-zero.in
./bin/go/src/compress/flate/testdata/huffman-zero.wb.expect
./bin/go/src/compress/flate/testdata/huffman-zero.wb.expect-noinput
./bin/go/src/go/parser/performance_test.go
./bin/go/src/go/printer/performance_test.go
./bin/go/src/go/types/testdata/manual.go2
./bin/go/src/image/jpeg/huffman.go
./bin/go/src/vendor/golang.org/x/net/http2/hpack/huffman.go
./bin/go/test/bench/go1/mandel_test.go
./bin/go/test/abi/many_int_input.go
./bin/go/test/abi/many_int_input.out
./bin/go/test/abi/many_intstar_input.go
./bin/go/test/abi/many_intstar_input.out
./bin/man
./bin/mandb
./bin/manpath
./etc/man_db.conf
./lib/opkg/info/man-db.conffiles
./lib/opkg/info/man-db.control
./lib/opkg/info/man-pages.list
./lib/opkg/info/man-db.list
./lib/opkg/info/man-pages.control
./lib/opkg/info/man-pages.postinst
./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.opt-1.pyc
./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.opt-2.pyc
./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.opt-2.pyc
./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.pyc
./lib/python3.10/encodings/__pycache__/hp_roman8.cpython-310.pyc
./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.pyc
./lib/python3.10/encodings/__pycache__/mac_roman.cpython-310.opt-1.pyc
./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.opt-1.pyc
./lib/python3.10/encodings/__pycache__/mac_romanian.cpython-310.opt-2.pyc
./lib/python3.10/encodings/hp_roman8.pyc
./lib/python3.10/encodings/mac_roman.pyc
./lib/python3.10/encodings/mac_romanian.pyc
./lib/tcl8.5/encoding/macRoman.enc
./lib/tcl8.5/encoding/macRomania.enc
./lib/groff/groffer/man.pl
./lib/man-db
./lib/man-db/libman-2.10.2.so
./lib/man-db/libman.so
./lib/man-db/libmandb-2.10.2.so
./lib/man-db/libmandb.so
./lib/man-db/manconv
./share/zoneinfo/Asia/Amman
./share/zoneinfo/Asia/Kathmandu
./share/zoneinfo/Asia/Katmandu
./share/doc/man-db
./share/doc/man-db/man-db-manual.ps
./share/doc/man-db/man-db-manual.txt
./share/groff/1.22.4/tmac/man.tmac
./share/groff/1.22.4/tmac/mandoc.tmac
./share/groff/site-tmac/man.local
./share/man
./share/man/man1
./share/man/man1/man-recode.1
./share/man/man1/man.1
./share/man/man1/manconv.1
./share/man/man1/manpath.1
./share/man/man5
./share/man/man5/manpath.5
./share/man/man8
./share/man/man8/catman.8
./share/man/man8/mandb.8
./share/man/man2
./share/man/man3
./share/man/man4
./share/man/man6
./share/man/man7
./share/man/man7/man-pages.7
./share/man/man7/man.7
./var/cache/man
很显然,路径就在/share/CACHEDEV3_DATA/.qpkg/Entware/share//man/
中了。
那么,安装完entware
之后,其它的man 手册放到 /share/CACHEDEV3_DATA/.qpkg/Entware/share/man
这个目录中就行了。
把gh git
等手册放进去。再次验证
man gh
GH(1) GitHub CLI manual GH(1)
NAME
gh - GitHub CLI
SYNOPSIS
gh <command> <subcommand> [flags]
DESCRIPTION
Work seamlessly with GitHub from the command line.
CORE COMMANDS
gh-auth(1)
Authenticate gh and git with GitHub
gh-browse(1)
Open the repository in the browser
gh-codespace(1)
Connect to and manage your codespaces
gh-gist(1)
Manage gists
gh-issue(1)
Manage issues
gh-pr(1)
Manage pull requests
gh-release(1)
Manage releases
gh-repo(1)
Manage repositories
ACTIONS COMMANDS
完美收工!
可能需要注意的地方,注意man
手册的权限644
,如果手册copy进去了,发现使用不了。运行下面命令。
chmod 644 -R /share/CACHEDEV3_DATA/.qpkg/Entware/share/man
安装更多的man pages
PS: 中文
man
手册有不少依赖需要解决,在Docker
中已经可以查询中文man
了,qnap
中试了下,解决依赖搞得头大,暂时就docker
中用中文man
好了
真正收工了!
附录
man介绍
man命令并非仅仅能查看命令或者函数的介绍,在linux中,有丰富的帮助手册信息,并且每一个手册都有一个编号。编号和对应内容如下:
编号 | 代表内容 |
---|---|
1 | 可执行程序或shell命令,如ls |
2 | 系统调用,如chdir |
3 | 库函数,如printf |
4 | 设备或特殊文件,如tty |
5 | 配置文件格式或约定 |
6 | 游戏 |
7 | 杂项 |
8 | 管理命令,通常只有root用户可以使用 |
9 | 内核例程 |
n | 内置命令,如cd |
常用快捷键
手册内容
多数手册包含以下几部分内容:
- NAME 功能的简单描述
- SYNOPSIS 语法格式
- DESCRIPTION 描述
- OPTIONS 选项
- ERRORS 描述出错场景,这在排查错误时很有帮助
- NOTES 注意事项
- FILES 相关文件,例如对于man命令的FILES部分内容显示了它的配置文件位置等信息
- EXAMPLES 使用示例,会提供一些简单的示例
- BUGS 存在的bug,当遇到奇怪的问题时,不妨看看当前命令是否有已知的bug
基本查看
手册的查看和less查看文本类似,可以参考《文本查看篇》或查看less命令的使用,这里介绍基本操作:
- 空格 向下翻页
- Home 回到第一页
- End 跳到最后一页
- /string 向前搜索string字符串
- ?string 向后搜索string字符串
- n 下一个匹配字符
- N 上一个匹配字符
- q 退出