我这里总结了一些csh/tcsh编写脚本的注意点(相对于bash);但是,csh/tcsh建议大家尽量避免使用:
如果无可避免要使用csh,处理逻辑尽可能使用awk等。
>> 能用sh(Bourne shell)不用csh/tcsh
>> 能用bash不用sh。
1、csh/tcsh没有function的概念,不能像bash一样定义function:
function f_1 { }
function f_1() {}2、定义变量
非数字变量,需要使用set关键字进行定义;
set ftp_status=`egrep -v '^#|^$' /etc/rc.conf | egrep '^ftpd_enable|^vsftpd_enable'`、
需要进行运算的数字定义,需要使用@字符进行定义:
@ start_inetd=`ps -aux | grep 'sbin/inetd' | grep -v grep|wc -l`3、csh/tcsh中的if分支语句为:
if (expression) thenelse if (expression) then
else
endif
3、if语句中的判断表达式,在判断符两侧必须有空格分割。
if ($isDeny != 0) then,而不能是:
if ($isDeny!=0) then
并且if(expr)也可能失败,if和(之间必须要有空格。
判断文件、目录是否存在
if ( -f /etc/syslog.conf ) then
if ( -d /etc ) then4、没有for循环语句,用foreach替代:
foreach var (wordlist)
commands
end5、引用命令,使用``,不能使用$()
set include=`cat /etc/syslog.conf |egrep -v '^#|^$'|grep '^include'|awk '{print $2}'`6、echo打印变量,需要使用""双引号引上,否则会因为特殊字符,如:[error],报错:
echo: No match.
当然,在确保没有特殊符号时,可以不用引号。如果特殊字符被''引起来了,还会报No match,如:
set MYVAR = "a='str.*' -p -10"
echo "$MYVAR"
使用下面语句替换,可以解决问题:
printf "%b\n" "\b$MYVAR\b"
7、如果打印多行变量,需要使用printf,而不能用echo,否则不会换行,如:
printf "%s\n" $var
注意:变量不能用""引上,否则仍然无法换行;但是printf和echo一样也存在如果有特殊字符,报错No match的问题。8、sh将stderr重定向到/dev/null,如此简单:
cmd 2>/dev/null
但是csh就麻烦很多:
(cmd > /dev/tty) >& /dev/null9、csh不支持类似于bash -n对脚本进行语法检查的功能。
10、csh中不支持短路与和短路或
bash:如果-f anaconda-ks.cfg表达式为真,不进行$a -eq 0 的判断,所以变量a不定义也不会出错
if ([ -f anaconda-ks.cfg ] || [ $a -eq 0 ]); then
echo "and ----"
ficsh/tcsh:就算-f anaconda-ks.cfg表达式为真,也会计算$a == 0表达式
if ( -f anaconda-ks.cfg || $a == 0) then
echo "and ----"
endif&&同上。
11、csh/tcsh中不能像bash一样使用${var:=value}定义变量默认值,以避免变量为空
csh/tcsh中的变量必须声明,否则会报:var: Undefined variable.
可以使用下面if语句判断变量var是否存在,如果不存在则声明并且赋值。
if ( ! $?var) then
set var="hello world"
endif12、csh/tcsh脚本文件中可以使用#注释,在交互模式下不识别#作为注释,会提示:
~ # # not command
#: Command not found.