特别篇:Linux 图形工具开发中遇到的坑
为了缓解被 Linux 指令在麒麟 V10 与 Windows 之间来回折磨的痛苦,以及发泄一名码畜内心的苦恼,尽管用户管理工具的开发刚开始不久,但我觉得还是有必要写下这篇博客,记录一下在此过程中遇到的 bug,并为以后处理此类错误提供一些思路。希望大家在读完这篇文章后有能所启发。
本工具的详细开发步骤请参见《开发篇:Linux 下的 swing 窗体程序开发》。
开发环境:Windows 10
开发工具:IntelliJ IDEA
测试环境:银河麒麟 V10
尽管用户管理工具的开发刚开始不久,但我觉得有必要先写下这篇博客,记录一下在此过程中遇到的 bug,并为以后处理此类错误提供一点启发。进行开发之前我在脑海里构思了一遍大概的设计流程。先做一个主窗体,然后做四个功能按钮,点击四个按钮再打开四个带有不同功能模块的子窗体,在子窗体里设计一个显示域,几个可供点击的功能按钮,然后为这几个按钮写入相应的 Linux 命令,通过 getRuntime() 放到 Linux 下执行,然后把结果取回来,输出到显示域中就可以了,不就依法炮制四个窗体嘛。
梦开始的地方・・・
设想是如此美好,可现实是刚刚起步就很快体会到了用 Java 做窗体开发的痛苦,我本来是打算在 Qt 下进行本次开发的,奈何 Qt 确实不会用,倒不如选择自己熟悉的 IDE。因为我考虑到,Qt 主要是提供给 C++ 开发者使用的,使用 Java 做 Qt 开发的不多,尤其是我几乎不能在网上找到有关在 Qt 上做 Java 开发的教程,这意味着如果使用 Qt 做 Java 开发的话,我不仅要完全凭感觉去进行 Java 开发,最可怕的是,如果在开发过程中遇到一些 “变态” 的 bug,在没有前例的情况下,我很可能无法独立去解决它・・・综上所述,最终我选择了钟爱的 IntelliJ IDEA。
好几个小时过去了,我现在仍停留在开发这款工具的图形界面,我敢保证自己绝对没有偷懒,用原生代码来做图形界面开发简直令人发狂(虽然 IDEA 为 swing 提供了 GUI 插件 Swing UI Designer,可以实现一定程度的 “所见即所得”,但使用起来很不方便,更多时候我宁可使用原生代码去调试),尤其是在经历过 Visual Studio 下的 C# 窗体开发后,swing 给人的落差感太大了。由于详细的开发历程已记录到另一篇文章,此处就不赘述了。
同一条指令,无数种反馈
在设计好基本的界面后,进入到本工具开发的最关键环节 —— 与 Linux 系统做交互,也就是通过 Java 去执行 Linux 命令然后获取返回值。第一个功能是用户清单,即实现用户详细信息的输出,因为要读取用户信息,我选择读取 /etc/passwd 的每一行去得到每一个用户(这应该是大部分 Linux 开发者面对这个问题时想到的第一个解决方案)。这时候第一个 bug 来了,去读 passwd 的每一行,该用哪一条指令呢?这时候我条件反射地想起了 cat /etc/passwd,虽然这样把所有的用户都输出了,不能单独拿出每一行,但我并不在意这个问题,因为它很好解决,等拿到这包含全部用户信息的一整个字符串后,我在程序里处理这个字符串,分割出每一个用户就好了,平时编程的时候也经常这样处理字符串。意想不到的是,cat /etc/passwd 返回的数据在 Linux 下明明是保有换行的(passwd 中一个用户占一行),可是当把 cat 指令放到 Java 中执行后,返回的数据居然变成了杂糅在一起的一团!??所有的换行都消失了,我测试的 40 行数据全部输出到了同一行内并且没有任何分隔符!从这一刻起,在 Linux 终端下老老实实的指令开始在我的 Java 程序里作威作福!我执行的难道不是同一条指令么?
# Linux 终端下的 cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
messagebus:x:101:101::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:102:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:103:104:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:104:105:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
tcpdump:x:105:110::/nonexistent:/usr/sbin/nologin
syslog:x:106:111::/home/syslog:/usr/sbin/nologin
avahi-autoipd:x:107:115:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
dnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
strongswan:x:109:65534::/var/lib/strongswan:/usr/sbin/nologin
cups-pk-helper:x:110:119:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
lightdm:x:111:120:Light Display Manager:/var/lib/lightdm:/bin/false
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
xrdp:x:113:122::/run/xrdp:/usr/sbin/nologin
avahi:x:114:123:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
pulse:x:115:125:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
saned:x:116:127::/var/lib/saned:/usr/sbin/nologin
hplip:x:117:7:HPLIP system user,,,:/run/hplip:/bin/false
nvidia-persistenced:x:118:128:NVIDIA Persistence Daemon,,,:/nonexistent:/usr/sbin/nologin
uuidd:x:119:130::/run/uuidd:/usr/sbin/nologin
yuanyi:x:1000:1000:yuanyi:/home/yuanyi:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
# Process 下的 cat /etc/passwd
root:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologinbin:x:2:2:bin:/bin:/usr/sbin/nologinsys:x:3:3:sys:/dev:/usr/sbin/nologinsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/usr/sbin/nologinman:x:6:12:man:/var/cache/man:/usr/sbin/nologinlp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologinmail:x:8:8:mail:/var/mail:/usr/sbin/nologinnews:x:9:9:news:/var/spool/news:/usr/sbin/nologinuucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologinproxy:x:13:13:proxy:/bin:/usr/sbin/nologinwww-data:x:33:33:www-data:/var/www:/usr/sbin/nologinbackup:x:34:34:backup:/var/backups:/usr/sbin/nologinlist:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologinirc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologingnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologinnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin_apt:x:100:65534::/nonexistent:/usr/sbin/nologinmessagebus:x:101:101::/nonexistent:/usr/sbin/nologinsystemd-timesync:x:102:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologinsystemd-network:x:103:104:systemd Network Management,,,:/run/systemd:/usr/sbin/nologinsystemd-resolve:x:104:105:systemd Resolver,,,:/run/systemd:/usr/sbin/nologintcpdump:x:105:110::/nonexistent:/usr/sbin/nologinsyslog:x:106:111::/home/syslog:/usr/sbin/nologinavahi-autoipd:x:107:115:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologindnsmasq:x:108:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologinstrongswan:x:109:65534::/var/lib/strongswan:/usr/sbin/nologincups-pk-helper:x:110:119:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologinlightdm:x:111:120:Light Display Manager:/var/lib/lightdm:/bin/falsesshd:x:112:65534::/run/sshd:/usr/sbin/nologinxrdp:x:113:122::/run/xrdp:/usr/sbin/nologinavahi:x:114:123:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologinpulse:x:115:125:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologinsaned:x:116:127::/var/lib/saned:/usr/sbin/nologinhplip:x:117:7:HPLIP system user,,,:/run/hplip:/bin/falsenvidia-persistenced:x:118:128:NVIDIA Persistence Daemon,,,:/nonexistent:/usr/sbin/nologinuuidd:x:119:13
