Shell篇(三)TC Shell
Shell脚本的首行一般写为"#!+路径"来告诉系统,以路径所指定的程序来解释此脚本。
可以写为 #! /bin/tcsh -f (-f表示快速启动,不启动~/.tcshrc)
Shell中的单引号' ' 表示当Shell碰见第一个单引号时,它会忽略其后直到右引号的所有特殊字符。一般可用在alias
alias bsub 'bsub -q gui -P msg.ult -I'
Shell中的双引号 “ ” 作用与单引号类似,但是不是那么严格忽略特殊字符,其中有三种特殊字符不会被忽略 $ \ ` 一般可以用在set参数
set test_name = "i2c_test_$session_id"
Shell中的反引号` 作用是命令替换,shell把一个命令的标准输出插入到一个命令行的任何位置。
如cmd1 `cmd2`则cmd2的输出作为cmd1的参数。($来表示参数替换)
Shell中的反斜杠 \ 作为转义字符或在长命令中做续行使用。
echo -n "Please enter a string \\" -n表示echo不会输出一个换行符。
TC Shell中需要从terminal输入数据时, set var = $<; $<在TC Shell中表示从terminal输入。
=~操作符表示进行匹配操作。
set variable = "This is a fine mess"
if("$variable" = ~ "T.....fine")
echo "MATCH"
shell中的语句末尾不加分号,在同一语句中,分号是用来隔断每个语法关键字的。
在不同的语法命令之间要用分号隔开或者换行才可以执行。
在shell中,为了保证上一条命令结束之后,才进行下一条命令,可使用wait 内建命令,上一命令使用后天处理。
cat test1| uniq > newtest1 &
cat test2 | uniq > newtest2 &
wait
diff newtest1 newtest2
TC Shell中变量,参数,数值:变量一般由setenv来设置,在本次执行中有效。参数一般 由set来设置。数值一般由@来声明。
setenv DENALI /run/pkg/cadence-vipcat/tools/denali_64bit
set test_name = "i2c_test"
@ num = 10; @ sum = $num*2+3; @只用来声明数值,$来调用,分号;表示前一命令结束或者直接换行。
在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1 value2 valuen)
读取数组元素:$array_name[index]
数组长度:$#array_name
数组中的全部数据:$array_name[*],$array_name[@]
当执行TC Shell的脚本时,命令行的单词被存放在argv数组中,$argv[0]表示命令名,$argv[n]表示第n个命令行参数,$#argv表示命令行参数
的个数,$argv[*]表示从1--n的命令。相应的还有$0, $n, $*, $#。$*表示从shell中受到的变量列表。
shell_test文件 #! /bin/csh -f echo "$0" 当用./shell_test执行时,显示./shell_test,当用source执行时,显示/bin/csh。
TC Shell中的控制结构:
if(expression) then command1; command2;
else command3;
endif
switch(string)
case pattern: command1; breadsw
default: command2; breadsw
endsw
while(expression)
command;
end
foreach variable (argument-list)
end (variable是用set设置的参数,以此取list中值)
shell中可以使用标签:
goto MAIN
USAGE:
echo ....
MAIN:
if() then
endif
shift操作,在不知道参数个数的情况下,遍历并处理使用。
#!bin/tcsh
while ($# != 0)
echo "$argv[1] $#argv"
shift
end
在输入run.sh a b c d e f时,标准输出显示第一个参数a,参数个数6,第一个参数b,标准参数5..............
break用于退出最接近的foreach,while循环。
continue用于继续最近的foreach,while循环。
文件测试符:-e文件是否存在,-rwx文件的读写执行属性,-d是否为目录,-f是否是普通文件,-z文件是否为空
exec + command :代替当前的shell执行command命令,执行之后,跳出shell。
shell_test文件 #! /bin/csh -f echo "$0" exec 'ls' echo "$0"
当用./shell_test执行时,执行完ls后,kill该shell_test。当用source执行时,执行完ls后,kill当前shell。
eval + command:代替当前的shell执行command命令,执行之后,返回shell。
shell_test文件 #! /bin/csh -f echo "$0" eval 'ls' echo "$0"
当用./shell_test执行时,显示./shell_test ls文件内容 ./shell_test。
exit [expression] :带指定表达式的值,退出。或者return语句
whereis + command :显示命令的别名和可执行路径等。
repeat + counter + command:重复执行N次command。
jobs:列出所有在执行的任务,主要是通过&后台运行的程序。(比ps命令的范围要小很多, ps -ef)。
builtins:显示所有内建的命令。
TC Shell的IO重定向:常用的FD有三个,0(stdin 标准输入),1(stdout 标准输出),2(stderr 标准错误输出)。一般用<来改变输入通道,>来改
变输出通道。由于默认的输入输出,<与0<是一样的,>与1>是一样的。| 管道命令时把前一命令的stdout接在当前命令的
stdin。tee 命令是在输出标准输出的情况下,copy一份到指定file中。
简单的重定向: cmd < file, cmd << file, cmd > file, cmd >> file。>>表示接在现有文件后,而不是重新写一份。
多重重定向: cmd >& file, cmd >>& file, cmd |& file。适用于tcsh,表示标准输出和标准错误一块进行重定向。
bash可以直接2>来直接重定向,标准错误输出。
cmd | tee file 将cmd的输出发送到标准输出,同时也写入file文件中。
echo " " >>file 将输出追加到某个文件中。
linux中/dev/null表示内容被删除, cat file > /dev/null 表示不要标准输出
rm file; rm file > /dev/null 表示标准输出不要
rm file > /dev/null 2>&1,表示标准输出和标准错误输出 都不要
shell中绑定输入输出,exec 文件描述符 <> file/文件描述符, 绑定之后,所有的命令的默认输入输出都会被改变。
exec 1>test.txt, 绑定标准输出
unset pattern;
unalias pattern;
unsetenv pattern;
!表示之前的命令,!!上一次的命令,!n前n次的命令。
echo $SHELL:显示当前使用的shell。
连续执行shell命令可以有几种写法,
1) command; command2; command3 按顺序执行三个command,不管是否成功执行
2) command1 && command2 && command3 顺序执行三个command,只有前边的command执行成功,才会继续执行
3)command1 || command2 || command3 如果command1执行成功,就不执行之后的command。
shell中的字符串截取:可以使用#(删除左边,保留右边),%(删除右边,保留左边)
var = http://www.hao.com/123.htm
echo ${var#*//} var是变量名,#是分割符,删除左边第一个开始的字符,*//从左边第一个//开始删除左边的所以字符;
结果:www.hao.com/123.htm
echo ${var##*/} var是变量名,##是分隔符,删除左边最后一个匹配到的字符,*/删除到从左边开始,最后的那个字符;
结果:123.htm
echo ${var%/*} var是变量名,%是分隔符,删除右边开始第一个匹配到的字符,/*右边开始第一个/,删除;
结果:http://www.hao.com
echo ${var%%/*} var是变量名,%%是分隔符,删除右边开始最后一个匹配到的字符,/*右边开始最后一个字符,删除;
结果:http:
取出其中的几个字符:
echo ${var:0:5} 0表示左边开始第一个字符开始,5表示字符的个数;
结果:http:
echo ${var:7} 表示从第七个字符开始,一直到结束;
echo ${var:0-7:3} 0-7表示右边算起第七个字符开始,3表示字符个数;
结果:123
echo ${var:0-7} 表示从第七个字符开始,一直到结束;
结果:123.htm
${test##*/} 表示去文件名的截取;
${test%/*} 表示去路径的截取;
字符串拼接:a = l; b = s;
eval ${a}${b} 结果形成ls命令;
拿到字符串的长度:${#var}
字符串中的替换: string = abcd12342341
echo ${string/23/bb} 结果:abcd1bb42341, / /表示只需要替换一次
echo ${string//23/bb} 结果:abcd1bb4bb41, // /表示替换所有匹配;
echo ${string/#abc/bb} 结果:bbd12342341, #表示以什么开头,类似^
echo ${string/%41/bb} 结果:abcd123423bb, %表示以什么结尾,类似$
shell变量的替换: ${value:-word} 当变量未定义或者值为空时,返回word的内容,否则返回变量的值;
${value:=word} 当变量未定义或者值为空时,在返回word的值的同时,将word的值,赋值给value;
${value:?message} 如果value已经被定义过,正常的替换,否则报错,shell停止。
expr命令:可以用来计算数值,也可以进行字符串的操作:
1)数值计算, `expr 9+8-7\*6 /5` 乘法需要转义,而且优先级高于加减
2)字符串操作,
match,“字符串:表达式”
$str = "123 456 789"
`expr match "$str" .*5` 可以使用正则表达式,返回的是匹配到的长度。
返回6
substr,“string:position:length”
$str = "123 456 789"
`expr substr "$str" 5 3` 返回456
index,“string:index”
$str = "123 456 789"
`expr index "str" b` 返回0,找不到该字符,返回0
·expr index "str" 9· 返回11,找到该字符,返回11
length,“string”
$str = "123 456 789"
`expr length "str"` 返回11,string的长度。
linux中的shell命令,
basename [string] [suffix],删除所有的前缀,包括最后一个"/",显示最后的字符,如果指定suffix,删除后缀。
basename /tmp/test/file.txt 输出file.txt
basename /tmp/test/file.txt .txt 输出file
dirname [string],拿到路径名,
跳转到脚本所在目录, cd $(dirname "$0") || exit 1
$0表示脚本的文件名加路径,
$*表示所有的输入参数,也可以用在某一个lable模块中。"$*" 返回一个字符串,字符串中含多个空格。
$@也表示所有的输入参数,“$@” 但是返回多个字符串。
shell主要可以实现一些控制流,循环,控制,IO输入输出等。对于一些需要交互的场合,多使用expect语言。
expect语言,主要用来实现自动和交互式的任务通信中,减少人为干预。expect是在tcl的基础上实现的,所以系统需要安装tcl和expect,在使用之前。
expect最简单的脚本操作模式本质上和Chat脚本工具一样,由一系列expect-send对组成。expect表示等待输出特定的字符,send表示发出自己的响应。