先来看两个例子:
Sample1
$ (echo -n 123456; sleep 1; echo -n abc >&2; sleep 1; echo -n 789)>puzzle 2>puzzle $ cat puzzle
输出结果:abc456789
Sample2
$ (echo -n 123456; sleep 1; echo -n abc >&2; sleep 1; echo -n 789)>puzzle 2>&1 $ cat puzzle
输出结果:123456abc789
先来看两个例子:
Sample1
$ (echo -n 123456; sleep 1; echo -n abc >&2; sleep 1; echo -n 789)>puzzle 2>puzzle $ cat puzzle
输出结果:abc456789
Sample2
$ (echo -n 123456; sleep 1; echo -n abc >&2; sleep 1; echo -n 789)>puzzle 2>&1 $ cat puzzle
输出结果:123456abc789
这些天抽时间整理了些shell的资料,这里把我的一点心得以问答的形式贴出来,供大家参考。小弟才疏学浅,错误的地方一定很多,欢迎大家拍砖、指正!
Q1: shell如何执行“简单”命令?
A: 这里的简单命令和bash参考手册里的含义相同,形式上一般是:命令的名称加上它的参数。有三种不同的简单命令:
1.内置命令(builtin)
是shell解释程序内建的,有shell直接执行,不需要派生新的进程。有一些内部命令可以用来改变当前的shell环境,如:
cd /path
var=value
read var
export var
…
2.外部命令(“external command” or “disk command”)
二进制可执行文件,需要由磁盘装入内存执行。会派生新的进程,shell解释程序会调用fork自身的一个拷贝,然后用exec系列函数来执行外部命令,然后外部命令就取代了先前fork的子shell。
3.shell脚本(script)
shell解释程序会fork+exec执行这个脚本命令,在exec调用中内核会检查脚本的第一行(如:#!/bin/sh),找到用来执行脚本的解释程序,然后装入这个解释程序,由它解释执行脚本程序。解释程序可能有很多种,各种 shell(Bourne shell,Korn shell cshell,rc及其变体 ash,dash,bash,zshell,pdksh,tcsh,es…),awk,tcl/tk,expect,perl,python,等等。在此解释程序显然是当前shell的子进程。如果这个解释程序与当前使用的shell是同一种shell,比如都是bash,那么它就是当前shell的子shell,脚本中的命令都是在子shell环境中执行的,不会影响当前shell的环境。
事情这样滴,我在RHEL5下运行了几个APP server,为了查看server的状况呢,我每天都要去检查/var/log/message,secure,mail等log文件,倘若log里出现error,就得去查看原因了。其实这是一件很考验耐心的事情,而且在正常情况下,出现error的几率并不多,但每天花上这么多时间去检查日志,简直是累的不行啊!
唉,由于我是懒人,这样的事情,我自然就得想些办法让程序去做,节省时间啊。
我的想法是:
1. 每天检查/var/log/message,secure,mail等这些log文件;
2. 挑出当天的记录中包括”error”字样的行;
3. 将这些内容发送到我的邮箱中。
达到这样的目的,我需要完成两件事情:
1. 写一个shell完成以上想法中的前两点;
2. 将这个shell配置在linux的计划任务中,也就是crontab中。
这样一来,条理也就清晰了,首先要做的就是要完成这个shell:
#!/bin/sh
#捕获当前日期,只包括月、日(根据实际情况来确定)
DD=`date +%b%e`
# 分别cat几个日志文件,将里面含有特征字符的行重定向到/home/mypath/logfile
for FF in /var/log/message /var/log/secure /var/log/mail
do
cat $FF |grep "$DD" |grep error>> /home/mypath/logfile
done
# The End
并将其保存为finderror.sh,然后剩下的计划任务就变得简单起来,只需要在cron里加上一行:
~/finderror.sh|mail user@domain.com -s `date +%b%e`
这样就让RHEL5每天自动来发送错误的日志了。我只需要check我的mail就可以了~~ ![]()
不知道你有没有什么更好的想法呢?也可以来告诉我。
作为多数Linux系统及OS X v10.4默认的shell,Bourne-Again SHell 4.0正式发布 。BASH 4.0修改了3.x版本中留下的bug,同时增加了许多新特性。
最值得关注的新特性是关联数组(associative arrays),改进了可编程完成函数(completion functionality),case-modifying单词扩充,复合进程,支持`**’特别glob模式,增加shell句法和重定向。 shell在分析内部命令替换上变得更严格,修正了POSIX虚拟接口的不兼容块。你现在可以去下载源代码,自己去编译它。
每次在linux上总会碰到^M的DOS文件带来的问题,之前用emacs的时候,也只知道用emacs来转换。其实直接用dos2unix这个命令也是可以完成单个文件的转换的。虽然比我之前方便了很多,但想想还是蛮不爽的,干脆就直接写了个shell,用来批量完成文件夹内所有文件的转换。
代码如下:
#!/bin/bash
showUsage() {
echo "Usage: dos2unixdir [destdir]"
exit 0
}
dir=$PWD
if [ $# -gt 1 ]
then
showUsage
fi
if [ $# -gt 0 ]
then
dir=$1
fi
for i in `find $dir`
do
if [ ! -d $i ]
then
echo "processing file..." $i
dos2unix $i
fi
done
I’m a newbie here, today I’ve got a problem. Here’s the shell:
b.sh
#!/bin/bash rm -rf $1
a.sh
#!/bin/bash for file in '/root/Desktop/test/*' do echo $file sh ./b.sh $file done ls /root/Desktop/test
When I sh a.sh, the result is : /root/Desktop/test/a /root/Desktop/test/b /root/Desktop/test/c /root/Desktop/test/d b c d I got the result that was not my expect. I wanna the whole folders are removed. It seems that only folder “a” was deleted. I’ve no idea how to modify my shell, or where cause the problem. Could you help me to modify this shell and please tell me why. Thanks! 阅读全文…