Gih's Blog

只言片语
Posts tagged as unix

AIX下df 与du 显示不一致问题

2011-07-29 by gihnius, tagged as linux, unix

df命令:通过文件系统中未分配的空间来确定文件系统中已分配空间的大小. 

例如: 如果一个文件系统中有 8192 个512-byte 块, 并且4096 个块没有被分配出去, 那么已分配的空间就是4096 个512-byte 块.已分配空间 = 空间总数 - 未分配空间因为基于文件系统总体来计算, 所以df 命令是报告文件系统空间使用情况最可靠的命令.

du 命令:是面向文件的命令, 它计算分配给指定文件或者目录的空间. du 命令只计算被文件占用的空间, 不计算文件系统metadata 占用的空间, 如inodes, inode maps, 或者disk maps.du 命令只计算那些可以访问的文件所占用的存储空间, 有下面两种情况 du 命令不会计算已经分配给文件的空间.

1. 文件被隐藏了.例如: 如果一个文件存放在 /bobby 目录下, 接着有文件系统安装在 /bobby 目录下, 那么, du 命令将不会计算 /bobby 目录下的文件所占用的存储空间,

2. 文件被其他的应用打开了, 接着文件被删除了. 在这种情况下, 文件所占用的存储空间将维持着被分配的状态直到所有对这个文件的访问都被关闭.由于目录中没有这个文件的相关纪录, du 命令将不会计算这个文件的被分配空间, 然而df 命令将计算这部分已分配的空间.系统中经常会出现上面陈述的第二种情况, 结果是df 显示的比 du 统计的, 可以使用fuser命令查找出"占用空间"的进程:

# fuser -dV /Filesystem 
上述命令会给出进程的工作目录,占用的inode,进程号等相关信息.
# df -m
Filesystem    MB blocks      Free %Used    Iused %Iused Mounted on
/dev/hd4       10240.00    600.42   95%    10580     1% /
/dev/hd2        4096.00   2105.22   49%    40503     4% /usr
/dev/hd9var     1024.00    423.75   59%     1125     1% /var
/dev/hd3        4096.00   3668.99   11%      278     1% /tmp
/dev/fwdump      384.00    371.91    4%       17     1% /var/adm/ras/platform
/dev/hd1        1024.00    990.42    4%      489     1% /home
/proc                 -         -    -         -     -  /proc
/dev/hd10opt   30720.00  18911.46   39%    28647     1% /opt
/dev/lv_mms1  555776.00 234959.96   58%    24317     1% /ShareDisks1 

# du -xsm /
18.23   /

# fuser -dV /
/: 
inode=40     size=44           fd=0      290822
inode=40     size=44           fd=0      327928
inode=36     size=16802        fd=0      401642 
上面的情况由于出现在 / 根文件系统, 使用du 时记得加 "-x" 选项, 这样才统计根文件系统所在 LV 的空间使用. 发现多个进程时, 可用 ps 找出具体的程序或脚本, 根据程序或脚本的特点判断是哪个"占用空间"!如果AIX上已安装 lsof , 可用结合使用.

PING 应用程序的故事

2011-07-20 by gihnius, tagged as linux, unix

偶尔发现这篇文章, The Story of the PING Program . 作者在那里介绍了 ping 的由来. 

下面是摘文:

ping 之所以叫 ping, 它的命名的灵感来自于声纳的设计. 在大学的时候我曾经做过一些有关声纳和雷达的建模......

I named it after the sound that a sonar makes, inspired by the whole principle of echo-location. In college I'd done a lot of modeling of sonar and radar systems, so the "Cyberspace" analogy seemed very apt. It's exactly the same paradigm applied to a new problem domain: ping uses timed IP/ICMP ECHO_REQUEST and ECHO_REPLY packets to probe the "distance" to the target machine. ......

ping最初为 4.2 BSD 系统设计.伯克利的人们拿走了我对内核的修改和Ping的源代码, 然后成为了伯克利(BSD)发布中的一个标准部分. 因为它是免费的, 所以被移植到了许多的其他系统, 包括MS Windows. ......

The folks at Berkeley eagerly took back my kernel modifications and the PING source code, and it's been a standard part of Berkeley UNIX ever since. Since it's free, it has been ported to many systems since then, including Microsoft Windows95 and WindowsNT. ......

在1993年, 也就是我写Ping十年之后, USENIX联合会给了我1993年终身成就奖(the Computer Systems Research Group, University of California at Berkeley 1979-1993.) ...

In 1993, ten years after I wrote PING, the USENIX association presented me with a handsome scroll, pronouncing me a Joint recipient of The USENIX Association 1993 Lifetime Achievement Award presented to the Computer Systems Research Group, University of California at Berkeley 1979-1993. ``Presented to honor profound intellectual achievement and unparalleled service to our Community. At the behest of CSRG principals we hereby recognize the following individuals and organizations as CSRG participants, contributors and supporters.'' Wow! ...

摘文完 


作为系统管理员, 使用ping非常频繁, 我却联想不到它像 雷达 - 声纳. 这本来就是“声纳”。

创建以内存为介质的文件系统

2011-07-13 by gihnius, tagged as linux, unix

有时要测试一些程序的IO等性能, 需要摆脱磁盘IO的影响. 也为了使某些程序运行得更快, 提供一个临时的文件系统给程序使用. UNIX系统都提供了类似的功能: ram disk(memory disk) and ramfs(memory filesystem).

FreeBSD:在FreeBSD上建立内存文件系统,有几种可选的方法. 使用mdconfig 或 mdmfs. 两者都是使用 md 驱动实现 (memory disk driver).在FreeBSD上推荐使用 mdmfs.下面命令创建一个 100m 的内存文件系统:

# mdmfs -s 100m md1 /mnt/mfs
这样, 就创建了基于md1的md设备的文件系统.如果你需要的是设备而不是文件系统,可以使用 mdconfig:
# mdconfig -a -t swap -s 100m -u 1 
-u 1是新创建的设备号, 不能与已有的冲突,
ls /dev/md* 
看看已经建立了哪些md设备.这里使用mdconfig创建了设备 md1, 如果需要文件系统, 可以对md1进行创建文件系统然后挂载等操作.
# newfs -U md1
在md1上创建 ufs文件系统. 然后挂载:
# mount /dev/md1 /mnt/mfs
使用mdconfig时,上面指定了使用-t swap, 其实还可以使用 malloc, 但是手册里不推荐这么做.说是容易导致系统 panic!FreeBSD系统中的 tmpmfs 就是使用 md设备 (mdmfs) 来建立的.注意, 上面指的是 tmpmfs, 不是tmpfs. 前者来自 FreeBSD5, 后者到FreeBSD7才出现.tmpfs是另外一种 memory disk, 它基于VM(虚拟内存,以swap为后端存储, 使用系统空闲的物理内存和空闲的swap). 现在好像还在测试阶段.当不再使用内存文件系统时, 使用 mdconfig释放 md设备占用的资源:
# mdconfig -d -u (md设备号)
AIX:AIX中类似的家伙叫做 ramdisk. 使用 mkramdisk 创建.mkramdisk 命令作为 bos.rte.filesystems 的一部分提供,它允许用户创建一个 RAM 盘。与FreeBSD的mdconfig类似, mkramdisk 也在/dev创建一个设备特殊文件 /dev/ramdiskX X是设备号.要设置一个大小为 100 MB 的 RAM 磁盘并在其上创建一个 JFS 文件系统,请输入以下命令:
# mkramdisk 100M
# ls -l /dev | grep ram
# mkfs -V jfs /dev/ramdiskx
# mkdir /ramdisk0
# mount -V jfs -o nointegrity /dev/ramdiskx /ramdiskx 
Linux:Linux上的操作比以上两个都简单:
# mount -t ramfs -o size=100m ramfs /mnt/mfs 
Linux上的ramfs是可以动态增长的, tmpfs不能. 


tmpfs 一般都是基于 VM 的.ramfs 严格意义上只使用物理内存.

用locate建立用户的文件索引数据库

2011-07-04 by gihnius, tagged as linux, unix

locate是常规的unix/linux系统自带工具, 用于快速查找文件. 与find不同, find是实时查找而且功能强大, 通常用在脚本中, 但对于桌面用户, 日常查找一些文件, 用find 就有些"大材小用"了, 你不觉得平时find $HOME -xxx yyy时要耗费很多时间吗?

locate就不一样, 它是通过事先建立索引再进行搜索的, 建立索引时就是使用find这个工具. 而平时用得较多的就是用户在自己的HOME目录下查找文件(假设用户都把自己的数据放到$HOME目录下,除此之外就是系统文件). 可以配置locate$HOME目录建立索引. 下面是我在 FreeBSD下的操作:

## shell profile
export LOCATE_CONFIG=$HOME/.locate.rc
alias updatedb='/usr/libexec/locate.updatedb'
alias locate='locate -d ~/.locate.db' 
copy /etc/locate.rc $HOME/.locate.rc 并修改以下几个选项:
## locate profile
# temp directory
TMPDIR="/tmp"

# the actual database
FCODES="$HOME/.locate.db"

# directories to be put in the database
SEARCHPATHS="$HOME/" 
通过 man updatedb 可以看到 LOCATE_CONFIG 这个变量是用于设置 updatedb 的配置文件位置的.之后就是按照自己的需要更新索引了. 可以在crontab 里设置:
15 12 * * *     $HOME/bin/cronsh.sh /usr/libexec/locate.updatedb > /dev/null 2>&1
...
cronsh.sh 是我为crontab设置环境变量而增加的.locate 的功能很强大, 支持正则表达式搜索.

强制产生core dump

2011-06-22 by gihnius, tagged as linux, unix

core是指进程在内存的映像(image), core对于调试程序非常有用, 所以有时希望主动 dump 进程的 内存映像, 叫做core dump. 下面通过向进程发送信号的方法产生core dump.

在AIX系统中,要设置让内核允许做core:

chdev -l sys0 -a fullcore=true
发送信号,但同时也杀死进程:
kill -6 PID
在FreeBSD系统中,系统默认允许core dump, 也可以通过
sysctl kern.coredump=1
设置允许.如果设置了 limit,要解除:
ulimit -c unlimited
然后是:
kill -6 PID
在Linux系统上的操作类似.下面是FreeBSD man文档对 signal id 6 的描述:
     No    Name         Default Action       Description
     1     SIGHUP       terminate process    terminal line hangup
     2     SIGINT       terminate process    interrupt program
     3     SIGQUIT      create core image    quit program
     4     SIGILL       create core image    illegal instruction
     5     SIGTRAP      create core image    trace trap
     6     SIGABRT      create core image    abort program (formerly SIGIOT) 

批量部署crontab

2011-06-13 by gihnius, tagged as linux, unix

标题起得太牵强了,其实crontab没有什么要批量的. 只是工作中要在n台机器上部署相同的后台作业.开始还以为要一台一台登录进去跑

crontab -e
. 在没有发现crontab这一用法前,还真觉得这差事太离谱啦!
原来crontab可以直接把一个文件了的cron table install到crontab里面.
crontab file
这里file的内容将完全代替crontab已有的内容,即执行
crontab file
后, 用
crontab -l
看到的与
cat file
看到的是一样的. 所以执行前要先备份之前的crontab.
## 备份
crontab -l > cron.bak
cat cron.bak > file
## 编辑 file, 添加新的crontab条目.
echo '* * * * * /new_crontab' >> file
...
## 把file里的cron table install到用户的 crontab中.
crontab file
## -l 确认
crontab -l
以前没这样用过,还是把它记下来了.

我认为最好最简单的使用ssh-agent的方法

2011-06-12 by gihnius, tagged as linux, unix

以前一直为在哪启动ssh-agent发愁,在网上搜索到也有很多人有类似的问题. 把eval `ssh-agent`放到 .xsession, .xinitrc, .profile 都不是好办法!因为这样很容易启动多个ssh-agent.

有个开源工具叫 keychian,是一组shell脚本.不过我觉得它还是把问题复杂化了.要是有Apple OSX系统的keychain那样还差不多. 因此我还是自己折腾出下面这种方法,我使用的是zsh,下面的配置应该在bash下也能够使用..zshrc

## 启动ssh-agent,并保存agent环境到 $HOME/.ssh/ssh-agent.sh里.
alias start-ssh-agent='[[ ! -f ~/.ssh/ssh-agent.sh ]] && eval `ssh-agent | tee ~/.ssh/ssh-agent.sh` && ssh-add'
## 停用ssh-agent.
alias stop-ssh-agent='eval `ssh-agent -k`; rm -f ~/.ssh/ssh-agent.sh'
## 每个login shell都使用已有的 ssh-agent,重新读取已经启动的ssh-agent信息到当前环境中.
if [[ -f ~/.ssh/ssh-agent.sh ]] ; then
    eval `< ~/.ssh/ssh-agent.sh` >/dev/null
    ps $SSH_AGENT_PID | grep -q ssh-agent
    if [ $? != 0 ] ; then
        rm -f ~/.ssh/ssh-agent.sh
    fi
fi 
通常,我是先打开一个终端,然后执行start-ssh-agent, 其实你喜欢什么时候需要就执行还是很方便的. 然后启动screen 或 tmux. 如果想停用,就跑stop-ssh-agent, 每次开一个新的终端,都会读取ssh-agent.sh的设置,继承已有的ssh-agent环境. 因此在一次启动之后, 新的终端也能使用.

sudo只是方便,并不安全

2011-06-01 by gihnius, tagged as linux, unix

在我看来,sudo只有两个用处. 

  • 让普通用户获得管理员权限执行某些命令:
 user OR %group     ALL=NOPASSWD: /bin/cmd1 /usr/sbin/cmd2 ... 

通常,这种情况使用最多. 根据实际情况,适当开放一些用户管理,系统状态信息获取,硬件信息和设置等等一类方便管理维护的命令.

  • 让一个用户切换到另一个用户执行某些命令:
 user OR %group     ALL=(daemon_user) NOPASSWD: /etc/init.d/start_daemon1 ... 

这种情况一般是管理后台服务时用到,有些服务程序并不是在root用户下运行.比如httpd,可能运行在www用户下,这样,相应的管理员可以通过sudo -u www切换到www这个帐号,管理httpd的运行以及日志,数据的处理. 这样的确很方便! 但是,我们无法有效的对使用sudo的过程进行管制和审计. 在上面两点中,要分配就得"NOPASSWD", 要不就别分配相应的权限. 再看看sudo的其它配置.

  • timestamp_timeout=0

这个应该设置为0,不能让sudo缓存密码.

  • runaspw

这个也应该加上, 谁要切换到root或其它帐号,他就该知道root或者那个帐号的密码. 如果让用户使用自己的密码sudo,除非他对自己的密码安全负责!

  • Cmd_Alias/User_Alias

它们有用,但只用在sudo内部.

  • logfile

聊胜于无.

  • !

sudo里这个'!'的作用就是取非, 主要是试图禁止执行某些命令. 可用户要是把那些命令复制到别处或者重命名,它就没辙啦! 大致就这些了吧!