系统调用exec和fork

Posted by 曹宇伟 on 二月 10th, 2010

Exec 与 fork 是 UNIX 中的两个系统调用,UNIX 程序利用它们来创建新的进程。

由一个进程产生 (spawn) 另一个进程 ,可能是进程产生后用新进程取代它,即exec;或者如何需要保留这个进程,那就复制一个进程,即 fork 。

举个例子:Getty 进程监测一个串行端口 (tty),提供了一个 “login:” 提示符,当用户输入登录名回车之后,getty的任务就完成了;它执行 (exec) 了 login 命令,当 login 检测密码输入正确之后,它执行 (exec) 登录 shell 。一旦用户启动另一个程序,shell 程序就会派生 (fork) 自己,并且这个复本将执行 (exec) 用户所要运行的任何程序。

大小写转换

Posted by 曹宇伟 on 二月 7th, 2010

将文件file.txt的小写字母转换成大写

1. 使用tr
cat file.txt | tr a-z A-Z
2. 使用sed
sed ‘y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/’  file.txt

sed的 y/source/dest/   Transliterate  the  characters  in  the  pattern space which appear in source to the corresponding character in dest.

查找后门程序

Posted by 曹宇伟 on 二月 2nd, 2010

每个进程都会有一个PID,而每一个PID都会在/proc目录下有一个相应的目录,这是Linux(当前内核2.6)系统的实现。

一般后门程序,在ps等进程查看工具里找不到,因为这些常用工具甚至系统库在系统被入侵之后基本上已经被动过手脚(网上流传着大量的rootkit。假如是内核级的木马,那么该方法就无效了)。

因为修改系统内核相对复杂(假如内核被修改过,或者是内核级的木马,就更难发现了),所以在/proc下,基本上还都可以找到木马的痕迹。

思路:
在/proc中存在的进程ID,在 ps 中查看不到(被隐藏),必有问题。

str_pids=`ps -A | awk ‘{print $1}’`
for i in /proc/[0-9]* ; do
        if  echo $str_pids | grep -q `basename $i` ; then
                :
            else
                echo “Rootkit’s PID: `basename $i`”
        fi
done
unset str_pids i

讨论:

检查系统(Linux)是不是被黑,其复杂程度主要取决于入侵者“扫尾工作”是否做得充足。对于一次做足功课的入侵来说,要想剔除干净,将是一件分精密、痛苦的事情,通常这种情况,需要用专业的第三方的工具(有开源的,比如tripwire,比如aide)来做这件事情。

而专业的工具,部署、使用相对比较麻烦,也并非所有的管理员都能熟练使用。

实际上Linux系统本身已经提供了一套“校验”机制,在检查系统上的程序没有被修改。比如rpm包管理系统提供的 -V 功能:

rpm -Va

即可校验系统上所有的包,输出与安装时被修改过的文件及相关信息。但是rpm系统也可能被破坏了,比如被修改过。

重置软件包的权限

Posted by 曹宇伟 on 九月 24th, 2009

系统环境:CentOS Linux 5.3

有时候误操作,会使文件系统的权限混乱,这是系统所不允许的。

那么,误操作之后怎么恢复到原来的状况呢(指文件权限相关的)?

重新安装软件包(yum reinstall xxxx )不失为一种方法,但是不够聪明。其实官方提供的有现成的解决方法:使用 RPM 包管理器。

1. 查找到需要恢复的文件
#rpm -Va | grep “M”

2. 确定哪些包需要重设权限
# rpm -Va | grep “M” | awk ‘{print $2}’ | xargs rpm -qf | sort -u

3. 重置这些包的权限
# rpm -Va | grep “M” | awk ‘{print $2}’ | xargs rpm -qf | sort -u | xargs rpm –setperms

重点儿是 rpm 的 –setperms 开关,其中还有四个可选选项:
-a 表示所有已安装软件包
-f 后跟文件,表示包含此文件的已安装的软件包
-p 后跟包文件,重置用这个包安装的文件的权限。
-g 后跟组名,按组重置权限。
直接跟包的名字,重置包的权限。

RPM校验软件包时发现的一个问题:
rpm -Va 时有时(reinstall了软件包或者重置的软件包的权限)会出现类似下面这样的提示信息:
prelink: /usr/lib/libnl.so.1.0-pre5: at least one of file’s dependencies has changed since prelinking

这便引出了另一个问题,prelink。
解决的办法是:prelink /usr/lib/libnl.so.1.0-pre5

在 /etc/cron.daily/下,有一个关于prelink的脚本prelink,每天会执行一次。

将Apache的日志发送到syslog服务器

Posted by 曹宇伟 on 五月 3rd, 2009

一直想要统一收集管理Apache的日志,一来可以较实时的分析系统的负载情况、分析系统问题,另一个,也可以把收集日志的工作分散到平时,分散带宽使用,并且解决日志合并问题。

想到的解决方法主要有两个:

第一,使用haproxy。

haproxy本身刚好就支持将日志以udp的方式发送给syslog服务器。看上去完美、感觉上官方。

第二,使用/bin/logger。

这个,是我晚上发梦的时候想到的。试图将CustomLog 管道给/bin/logger,再由本地的syslog forward到远程统一的syslog服务器上。实验了一下,居然成功了。就是绕了那么一道弯子,感觉不太完美。

PS:

发布之后,自己搜了一下,发现了下文:http://www.lslnet.com/linux/dosc1/32/linux-247167.htm

解决方法倒也差不多,不过多了些详细的描述,很实用。

并且要注意:至少默认的syslog配置会将短时候内重复的日志记录给于提示,并不记录:

May  3 14:31:51 localhost last message repeated 99 times

另外,将nginx的日志发送到syslog:

mkfifo  /srv/logs/access_log.fifo

将 nginx 的日志写到这个 管道文件上

然后:logger -f /srv/logs/access_log.fifo 即可。

细读crontab手册

Posted by 曹宇伟 on 三月 11th, 2009

一句话总结crontab(指这个应用、这个机制)的作用:”run this command at this time on this day”,在指定的日期、时间,运行指定的命令。下面是Linux 上crontab手册中的知识点,小结如下:

1. crontab文件“正式行”的开始

空行、以空格或者“tab”开行的行,被cron(daemon)忽略。

以#开始的行,作为注释被cron(daemon)忽略。

“注释”不允许与“命令”放在同一行(作为命令的注释),会被作为“第六段”,被cron(daemon)执行。

同样的,也不能放在设置环境变量的同一行。

2. 在crontab文件中指定环境变量

设置变量使用

name = value

这样的格式,”=”号左右的空格不是必须的。

几个变量默认已经被设置,比如:

SHELL=/bin/sh
HOEM=/home/nnix
LOGNAME=nnix

其中SHELL和HOME可以重新设定,LOGNAME则不可(大概跟确定crontab文件的位置有关)。

默认,crontab会把执行的输出发送给crontab的所有者,除非重新设定变量:

MAILTO=other_or_email

另外,当crontab发送输入时的邮件编码,可以通过设置变量 CONTENT_TYPE 和 CONTENT_TRANSFER_ENCODING 来使用正确的编码来发送邮件。

3. crontab 文件的分段

依次分别是

  • 分(0-59)
  • 时(0-23)
  • 日(1-31)
  • 月(1-23,或者英文名)
  • 周(0-7,或者英文名,0和7均表示周日)
  • 要执行的内容   

4. 前五段:时间和日期

1)表示任意:* 号表示 “任意”(first-last)。

2)指定数字,表示指定的时间。

3)指定段,表示“开始-结束”内包含的数:比如3-6,表示3,4,5,6

4)指定列表:比如 “1,2,3,4″,”0-4,8-12″

5)指定“步长”:8-14/2 表示8,10,12,14

5. 模糊的第六段:

1)除去前五段,从第六段开始到换行符或者“%”为止,为要执行的命令。

2)默认第六段将被/bin/sh执行,除非在crontab文件中指定了非/bin/sh的SHELL变量。

3)第六段中的”%”号,除非前面加”\”号转交,否则,“%”号将结束命令行、换行的意义,并且其后的内容会被做为标准输入发送给前面的命令。

6. 冲突的逻辑

日期可以用月限定,也可以用“星期”指定,如果两个段有冲突(比如这两段不同时为“*”),那么,第六段的命令将在匹配任何一个的情况下运行,比如

“30 4 1,15 * 5″,将在每月的1号和15号 加 每个周五,上午4:30运行。

7. crontab文件中的神密符号“%”

可能会遇到的一个问题是,在第六段中需要使用date生成日志文件名,比如:

0   4   *   *   *   /opt/cron/mysql_dump.sh    > /srv/logs/`date +%y-%m-%d`.dump.log

这时会发现crontab怎么也不运行这个mysql_dump.sh,也看不到有日志生成。这是因为在crontab文件中,”%”是有特殊含义的。假如不需要“%”的特殊作用,需要使用转义符转义。上面应该写成:

0   4   *   *   *   /opt/cron/mysql_dump.sh    > /srv/logs/`date +\%y-\%m-\%d`.dump.log

“%”在crontab文件中,有“结束命令行”、“换行”、“重定向”的作用,比如:

0  22  * * 1-5  mail -s “It’s 10:00 pm” joe%Joe,%%Where are your kids?%

将会在周一至周五的22:00发送一分内容为:

Joe,<换行>
<换行>
Where are your kids?<换行>

8. 不能理解的特殊用法

       @reboot    :    Run once, at startup.

为了达到在开机后运行,且只运行一次的目的,除了这个,恐怕无法通过前五段的设置来实现吧?

Debian 添加en_US.utf8 LANG环境

Posted by 曹宇伟 on 十月 21st, 2008

以中文方式安装的Debian GUN/Linux 系统,默认LANG=zh_CN.utf8,并且默认,只有三种LANG支持:

$locale -a
C
POSIX
zh_CH.utf8

添加en_US.utf8支持,需要:

1. 编辑/etc/locale.gen,添加如下一行: en_US.UTF-8 UTF-8

2. 运行locale-gen,编译生成en_US.utf8

3. 或者直接运行:dpkg-reconfigure locales

Debian中的locales(GNU C Library: National Language (locale) data [support] )用来处理locale(本地化)。
CentOS(RedHat)中,locale包含在glibc-comman中。

编码问题(for Linux)

Posted by 曹宇伟 on 十月 21st, 2008

查看文件编码格式及文件编码转换及文件系统(目录、文件名)编码转换

查看文件编码格式

1. 使用VIM

使用命令 :set fileencoding 即可显示文件编码

如果你只是想查看其它编码格式的文件或者想解决用Vim查看文件乱码的问题,那么你可以在
~/.vimrc 文件中添加以下内容:

set encoding=utf-8 fileencodings=ucs-bom,utf-8,cp936

这样,就可以让vim自动识别文件编码(可以自动识别UTF-8或者GBK编码的文件),其实就是依照fileencodings提供的编码列表尝试,如果没有找到合适的编码,就用latin-1(ASCII)编码打开。

2. 使用enca ( Extremely Naive Charset Analyser )

这个包,系统默认可能没有安装,需要安装。

使用方法:$enca filename

文件编码转换

1. 使用VIM
:set fileencoding=utf-8
保存退出。

2. 使用enca包工具enconv转换文件编码

比如要将一个GBK编码的文件转换成UTF-8编码,操作如下:
enconv -L zh_CN -x UTF-8 filename

3. iconv 转换,(iconv属于glibc-common包,一般系统都有)iconv的命令格式如下:

iconv -f encoding -t encoding inputfile

比如将一个UTF-8 编码的文件转换成GBK编码

iconv -f GBK -t UTF-8 file1 -o file2

Linux文件名编码转换

从Linux往windows 拷贝文件或者从windows往Linux拷贝文件,有时会出现中文文件名乱码的情况,出现这种问题的原因是因为,windows的文件名中文编码默认为 GBK,而Linux中默认文件名编码为UTF8,由于编码不一致,所以导致了文件名乱码的问题,解决这个问题需要对文件名进行转码。

在Linux中专门提供了一种工具convmv进行文件名编码的转换,可以将文件名从GBK转换成UTF-8编码,或者从UTF-8转换到GBK。

首先看一下你的系统上是否安装了convmv,如果没安装的话用:
yum -y install convmv
安装。
下面看一下convmv的具体用法:

convmv -f 源编码 -t 新编码 [选项] 文件名

常用参数:
-r 递归处理子文件夹
–notest 真正进行操作,请注意在默认情况下是不对文件进行真实操作的,而只是试验。
–list 显示所有支持的编码
–unescap 可以做一下转义,比如把%20变成空格
比如我们有一个utf8编码的文件名,转换成GBK编码,命令如下:

convmv -f UTF-8 -t GBK –notest utf8编码的文件名

这样转换以后”utf8编码的文件名”会被转换成GBK编码(只是文件名编码的转换,文件内容不会发生变化)。

注意:不要在NTFS和FAT文件系统中使用此命令,否则可能产生意外结果,如果要在Linux中正确的显示NTFS和 FAT的中文件名,可以通过mount参数来解决,具体方法查看一下man手册。


禁止对数据分区的locate数据库更新

Posted by 曹宇伟 on 九月 28th, 2008

我们的/srv/分区相当的大,图片服务器的就更大了。

所以是不能允许对这个分区的文件进行(locate)索引的,即使系统使用的renice +19的方式运行,也是仍然是对系统资源的浪费。一来浪费CPU资源,二来浪费硬盘I/O,三,会使updatedb的数据库巨大,规划不当的话会使/var分区满掉(或者/分区满掉,假如var不是单独分区的话)。

使用cfengine更新了所有系统的配置文件,排除了对/srv分区的索引。

#/etc/updatedb.conf
PRUNEFS = “auto afs iso9660 sfs udf”
PRUNEPATHS = “/afs /media /net /sfs /tmp /udev /var/spool/cups /var/spool/squid /var/tmp /srv /mnt”

wput技巧

Posted by 曹宇伟 on 九月 27th, 2008

今天要将自己的备份,从一个ftp导到另一个ftp里去。还好可以登录其中一台服务器。

本来想使用lftp的mirror功能,无耐只能登录“local”,不能登录remote,而lftp的mput貌似依然不支持put目录。(谁知道有什么参数可以用来put目录?)

还好有wput可以使用。

然而在wput( wput /home/myname ftp://ftpusername:password@ip/myname )的时候,发现文件名、目录名中包含的空格和汉字,总是报错。

于是有了下面的方法:

$find /home/myname -type f >> ~/list.txt
$while read i ; do wput “$i”  ftp://ftpusername:password@ip/myname ; done < ~/list.txt

这样就支持了空格,不再报错。shell内部的处理,还真是复杂。

几个性能工具备忘

Posted by 曹宇伟 on 九月 17th, 2008

top:

* A: PID        = Process Id
* E: USER       = User Name
* H: PR         = Priority
* I: NI         = Nice value
* O: VIRT       = Virtual Image (kb)
* Q: RES        = Resident size (kb)
* T: SHR        = Shared Mem size (kb)
* W: S          = Process Status
* K: %CPU       = CPU usage
* N: %MEM       = Memory usage (RES)
* M: TIME+      = CPU Time, hundredths
b: PPID       = Parent Process Pid
c: RUSER      = Real user name
d: UID        = User Id
f: GROUP      = Group Name
g: TTY        = Controlling Tty
j: P          = Last used cpu (SMP)
p: SWAP       = Swapped size (kb)
l: TIME       = CPU Time
r: CODE       = Code size (kb)
s: DATA       = Data+Stack size (kb)
u: nFLT       = Page Fault count
v: nDRT       = Dirty Pages count
y: WCHAN      = Sleeping in Function
z: Flags      = Task Flags <sched.h>
* X: COMMAND    = Command name/line

Flags field:
0×00000001  PF_ALIGNWARN
0×00000002  PF_STARTING
0×00000004  PF_EXITING
0×00000040  PF_FORKNOEXEC
0×00000100  PF_SUPERPRIV
0×00000200  PF_DUMPCORE
0×00000400  PF_SIGNALED
0×00000800  PF_MEMALLOC
0×00002000  PF_FREE_PAGES (2.5)
0×00008000  debug flag (2.5)
0×00024000  special threads (2.5)
0x001D0000  special states (2.5)
0×00100000  PF_USEDFPU (thru 2.4)

进程的优先级和nice级别
进程优先级是一个决定进程被CPU执行优先顺序的参数,内核会根据需要调整这个值。Nice值是一个对优先权的限制。进程优先级的值不能低于nice值。(nice值越低优先级越高)
进程优先级是无法去手动改变的,只有通过改变nice值去间接的调整进程优先级。如果一个进程运行的太慢了,你可以通过指定一个较低的nice值去为它分配更多的CPU资源。当然,这意味着其他的一些进程将被分配更少的CPU资源,运行更慢一些。Linux支持nice值的范围是19(低优先级)到-20(高优先级),默认的值是0。如果需要改变一个进程的nice值为负数(高优先级),必须使用su命令登陆到root用户。下面是一些调整nice值的命令示例,
以nice值-5开始程序xyz
#nice –n -5 xyz

改变已经运行的程序的nice值
#renice level pid

将pid为2500的进程的nice值改为10
#renice 10 2500

vmstat:

·process(procs)
r:等待运行时间的进程数量
b:处在不可中断睡眠状态的进程
w:被交换出去但是仍然可以运行的进程,这个值是计算出来的
·memoryswpd:虚拟内存的数量
free:空闲内存的数量
buff:用做缓冲区的内存数量
·swap
si:从硬盘交换来的数量
so:交换到硬盘去的数量
·IO
bi:向一个块设备输出的块数量
bo:从一个块设备接受的块数量
·system
in:每秒发生的中断数量, 包括时钟
cs:每秒发生的context switches的数量
·cpu(整个cpu运行时间的百分比)
us:非内核代码运行的时间(用户时间,包括nice时间)
sy:内核代码运行的时间(系统时间)
id:空闲时间,在Linux 2.5.41之前的内核版本中,这个值包括I/O等待时间;
wa:等待I/O操作的时间,在Linux 2.5.41之前的内核版本中这个值为0

iostat:

%user:user level(应用)的CPU占用率情况
%nice:加入nice优先级的user level的CPU占用率情况
%sys:system level(内核)的CPU占用情况
%idle:空闲的CPU资源情况

Device:块设备名
Tps:设备每秒进行传输的数量(每秒的I/O请求)。多个单独的I/O请求可以被组成一个传输操作,因为一个传输操作可以是不同的容量。
Blk_read/s, Blk_wrtn/s:该设备每秒读写的块的数量。块可能为不同的容量。
Blk_read, Blk_wrtn:自系统启动以来读写的块设备的总量。

块可能为不同的容量。块的大小一般为1024、2048、4048byte。可通过tune2fs或dumpe2fs获得:
# tune2fs -l /dev/hda1|grep ‘Block size’
Block size:               4096
# dumpe2fs -h /dev/hda1|grep ‘Block size’
dumpe2fs 1.35 (28-Feb-2004)
Block size:               4096

shell中的判断

Posted by 曹宇伟 on 七月 11th, 2008

[ -f $file ]
像这们的句子,应该写成
[ -f "${file}" ] 这样可以
第1:避免变量file里包含特殊符号的情况。(当然这样也不是万能的)
第2:万一还有一个变量f,那么$file就会出现异常。

2010-02-01
apachectl 脚本中判断变量不为空:
$ULIMIT_MAX_FILES=”ulimit -S -n `ulimit -H -n`”
if [ "x$ULIMIT_MAX_FILES" != "x" ] ; then
    $ULIMIT_MAX_FILES
fi

BASH中字符串的处理

Posted by 曹宇伟 on 七月 10th, 2008

$x=abcd

[得到长度]

方法1:
$expr length $x
4

方法2:
$echo ${#x}
4

方法3:
$expr “$x” : “.*”    #expr的手册信息
4           #STRING : REGEXP anchored pattern match of REGEXP in STRIN

[查找子串]

$expr index $x “b”
2
$expr index $x “a”
1

[得到子字符串]

方法1:
#expr startpos length
$expr substr “$x” 1 3
abc
$expr substr “$x” 1 5
abcd
$expr substr “$x” 2 5
bcd

方法2:
#${x:pos:lenght}
$echo ${x:1}
bcd
$echo ${x:2}
cd
$echo ${x:0}
abcd
$echo ${x:0:1}
a

[匹配正则表达式]

[打印匹配长度]
$expr match $x “.”
1
$expr match $x “abc”
3
$expr match $x “bc”
0

[字符串的掐头去尾]

$x=aabbaarealwwvvww
$echo “${x%w*w}”
aabbaarealwwvv
$echo “${x%%w*w}”
aabbaareal
$echo “${x##a*a}”
lwwvvww
$echo “${x#a*a}”
bbaarealwwvvww

其中 , # 表示掐头, 因为键盘上 # 在 $ 的左面。
其中 , % 表示%, 因为键盘上 % 在 $ 的右面。
单个的表示最小匹配,双个表示最大匹配。
也就是说,当匹配的有多种方案的时候,选择匹配的最大长度还是最小长度。

[字符串的替换]

$x=abcdabcd
$echo ${x/a/b} # 只替换一个
bbcdabcd
$echo ${x//a/b} # 替换所有
bbcdbbcd

SHELL程序的不同执行方式

Posted by 曹宇伟 on 七月 10th, 2008

在当前shell环境运行:继承并影响当前环境。
. a.sh
source a.sh
实际上,”.”号与source的效果是一样的。
在当前shell运行时,需要注意,shell程序会影响、改变当前shell的环境。假如a.sh中有exit指令,那么用户将退出shell登录。

启动新的shell执行:只继承export输入的变量,并切不影响父进程的环境。exit指令只是退出新启动的shell。
bash a.sh
bash <a.sh
chmod+x a.sh
./a.sh

在( ) 中运行:executed in a subshell environment

也是在新的进程中运行。但是继承关系有点复杂,实验如下:

####START####
$su -
#chmod +x a.sh
#cat a.sh
echo $a
exit
#a=FreeBSD
#(./a.sh)

#(source a.sh)
FreeBSD
#(. a.sh)
FreeBSD
####END####

a.sh中的exit均没有影响到当前shell,但是却继承了当前shell的变量,但是改变a的操作却不能影响当前shell下a的值。

另外:
exec ./a.sh
关于exec:
exec: exec [-cl] [-a name] file [redirection ...]
Exec FILE, replacing this shell with the specified program.
If FILE is not specified, the redirections take effect in this
shell. If the first argument is `-l’, then place a dash in the
zeroth arg passed to FILE, as login does. If the `-c’ option
is supplied, FILE is executed with a null environment. The `-a’
option means to make set argv[0] of the executed process to NAME.
If the file cannot be executed and the shell is not interactive,
then the shell exits, unless the shell option `execfail’ is set.

man bash

Compound Commands
A compound command is one of the following:

(list) list  is  executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below).  Variable assignments and builtin commands that affect the shell’s environment do not remain in effect after the command completes.  The return status is the exit status  of list.

{ list; }
list  is simply executed in the current shell environment.  list must be terminated with a newline or semicolon.  This is known as a group command.  The return status is the exit status of list.  Note that unlike the metacharacters ( and ), { and } are reserved words and must occur where a reserved word is permitted to be recognized.  Since they do not cause a word break, they must be sep-arated from list by whitespace.
Command Substitution
Command substitution allows the output of a command to replace the command name.  There are two forms:

$(command)
or
‘command‘

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing  newlines  deleted.  Embedded newlines are not deleted, but they may be removed during word splitting.  The command substitution $(cat file) can be replaced by the equivalent but faster $(< file).

When the old-style backquote form of substitution is used, backslash retains its literal meaning except when followed by $, ‘, or \.  The first backquote not preceded by a backslash terminates the command substitution.  When using the $(command) form, all characters between the parentheses make up the command; none are treated specially.

Command substitutions may be nested.  To nest when using the backquoted form, escape the inner backquotes with backslashes.

If the substitution appears within double quotes, word splitting and pathname expansion are not performed on the results.

COMMAND EXECUTION ENVIRONMENT
The shell has an execution environment, which consists of the following:

·      open files inherited by the shell at invocation, as modified by redirections supplied to the exec builtin

·      the current working directory as set by cd, pushd, or popd, or inherited by the shell at invocation

·      the file creation mode mask as set by umask or inherited from the shell’s parent

·      current traps set by trap

·      shell parameters that are set by variable assignment or with set or inherited from the shell’s parent in the environment

·      shell functions defined during execution or inherited from the shell’s parent in the environment

·      options enabled at invocation (either by default or with command-line arguments) or by set

·      options enabled by shopt

·      shell aliases defined with alias

·      various process IDs, including those of background jobs, the value of $$, and the value of $PPID

When a simple command other than a builtin or shell function is to be executed, it is invoked in a separate  execution  environment  that consists of the following.  Unless otherwise noted, the values are inherited from the shell.

·      the shell’s open files, plus any modifications and additions specified by redirections to the command

·      the current working directory

·      the file creation mode mask

·      shell variables and functions marked for export, along with variables exported for the command, passed in the environment

·      traps caught by the shell are reset to the values inherited from the shell’s parent, and traps ignored by the shell are ignored

A command invoked in this separate environment cannot affect the shell’s execution environment.

Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent  at invocation.   Builtin  commands  that are invoked as part of a pipeline are also executed in a subshell environment.  Changes made to the subshell environment cannot affect the shell’s execution environment.

If a command is followed by a & and job control is not active, the default standard input for the command is the  empty  file  /dev/null. Otherwise, the invoked command inherits the file descriptors of the calling shell as modified by redirections.

在history命令中显示时间

Posted by 曹宇伟 on 七月 1st, 2008

FreeBSD 6.1上的csh,默认就是开启了这个功能的。
Linux上的BASH默认没有开启这个功能,开启办法是:设置环境变量HISTTIMEFORMAT,设备方法参照strftime的格式(man 3 strftime查看详细信息)。不过这个功能只有在BASH3.0以上的版本中才能使用。原文是这么写的:

New HISTTIMEFORMAT variable; value is a format string to pass to strftime(3). If set and not null, the `history’ builtin prints out timestamp information according to the specified format when displaying history entries. If set, bash tells the history library to write out timestamp information when the history file is written.

比如,在~/.bash_profile里添加如下一行:
export HISTTIMEFORMAT=”%F %T ”
然后再使用history的时候,就会显示时间信息了。


Copyright © 2007 花开的地方. All rights reserved.