解决 /dev/null is not a character device! 问题

昨天我们一个客户无法 ssh 到他的 VPS,但是可以 ping 通。从控制台上看没有异常,登陆进去后发现 ssh 服务没有启动,企图启动(重启)这个服务时报错 /dev/null is not a character device!:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd failed!
/dev/null is not a character device!.

解决办法是,删除 /dev/null 后重建一个字符设备:

# rm -f /dev/null
# mknod /dev/null c 1 3

然后启动(重启)ssh 就可以了:

# /etc/init.d/ssh restart
Restarting OpenBSD Secure Shell server: sshd.

/dev/null 的另类用法

/dev/null 是个黑洞,进去的东西永远出不来,在脚本编程的时候经常会用它(空设备文件)来屏蔽标准或错误输出(stdout 或 stderr),比如 command > /dev/null 2>&1 把 command 执行的结果(标准输出和错误输出)全部重定向到 /dev/null,也就是在控制台上不回显任何输出。

今天发现我们的 Graphite 监控服务器硬盘空间不够了(因为监控日志体积日益增加),一些不必要的日志占据了不少硬盘,比如 graphite 里面的 console.log,一般来说日志配置都在相关的配置文件里,在 graphite 的配置文件里找了一圈居然没找到如何关闭 console.log 日志配置(有其他日志的配置选项,但是没有 console.log 这个日志的关闭选项),难道要写个 cron 定期清理 console.log?一个更好的办法是把 console.log 这个连接到 /dev/null(如果确定以后不需要查看 console.log 的话),这样 graphite 写到 console.log 就永远的消失了,对现在的系统和配置不会有任何影响,甚至连 graphite 服务都不用重启,下面的脆香米兄的评论是对的,graphite 正在操作 console.log,简单改变文件名称并没有更改已打开的文件句柄,所以需要重启 carbon-cache.py.

# cd /opt/graphite/storage/log/carbon-cache/carbon-cache-a/

# ls -l
total 1811016
-rw-r--r-- 1 root     root     1360161601 Aug  6 15:18 console.log

# /opt/graphite/bin/carbon-cache.py stop

# mv console.log console.log.bak
# ln -s /dev/null console.log

# /opt/graphite/bin/carbon-cache.py start

# ls -l
total 1811032
lrwxrwxrwx 1 root     root              9 Aug  6 15:18 console.log -> /dev/null
-rw-r--r-- 1 root     root     1360178736 Aug  6 15:18 console.log.bak