在shell的世界里边,有一些特殊的字符,这些字符可以帮助我们快速的便捷的使用tcsh命令,在这里我做一次小结,希望你能从中找到灵感,设计出强大的命令组合拳,常用的特殊符号如下表:
接下来我们来看一下具体的释疑吧
1:=
这是一个赋值字符,tcsh的赋值在某些老版本上对空格要求比较苛刻,这里的例子是一个通用解决方案,空格使用高亮表示,示例如下
可以变量套用变量,也可以不加双引号来赋值打个字符,但是,如下第一个字符串的复制操作是非法的,没有把所有内容赋值成功,是有第一个this被赋值了进去,如果使用了双引号,就没有问题了。
如果是连续用:==是一个测试字符,特点如上,只能做字符测试,带空格的字符串是无法操作的。如下例截图:
2:$
这个是变量的前缀,例如上面的示例,但是$0 到$n是命令的参数保留变量,如下面的例子
这里还会引申多一个特殊的变量 “$*” , 表示所有的参数,具体如下:
> cat test1.tsh
#!/usr/bin/tcsh -f
echo "$0 $*"
echo "$0 $1 $2 $10 $13"
> ./test1.tsh 1 2 3 4 5 6 7 8 9 10 11 12 13 14
./test1.tsh 1 2 3 4 5 6 7 8 9 10 11 12 13 14
./test1.tsh 1 2 10 13
3: > 和 >>
打破系统默认的输出到屏幕的机制,输出重定向(>)和输出定向追加(>>),基本操作如下。
这里需要注意的是,无论原始文件是否存在,这两个重定向都会带文件创建的动作
4
改变系统默认从键盘读入数据的规则,输入重定向,输入量来自于“
4: | :管道符
这个符号是将前面命令的结果作为输入,传递到后方命令,多个管道叠加可以处理连续的多个动作,在某些情况下很方便:
这里有一个文件,
> head job_new
pCnz paH 796569 (OUAO11) /Czdt> WgqsZqt /B/zB/Nt766la/eCq/BxWtZua -e -- /h>
pCnz paH 797181 (OUAO11) /Czdt> HCWCZ1 /B/zB/Nt766la/eCq/BxWtZua -e -- /h>
pCnz paH 826571 (OUAO11) /Czdt> cZhycZh /B/zB/Nt766la/eCq/BxWtZua -e -- /h>
pCnz paH 835638 (OUAO11) /Czdt> Ngazca1N /B/zB/Nt766la/eCq/BxWtZua -e -- /h>
pCnz paH 894744 (OUAO11) /Czdt> LZqtnc3N /B/HCedaE/Hua_CB/eCq/BxWtZua -e -->
pCnz paH 902524 (OUAO11> /Czdt> eHC3N /B/xlCB/BHH4CKz/eCq/BxWtZua -e -- >
pCnz paH 903088 (OUAO11> /Czdt> yrZCN /B/xlCB/BHH4CKz/eCq/BxWtZua -e -- >
pCnz paH 903120 (OUAO11> /Czdt> yrZCN /B/xlCB/BHH4CKz/eCq/BxWtZua -e -- >
pCnz paH 904630 (OUAO11) /Czdt> nZcgn1N /B/zB/Nt766ea/eCq/BxWtZua -e -- /h>
pCnz paH 904940 (OUAO11> /Czdt> eHC3N /B/xlCB/BHH4CKz/eCq/BxWtZua -e -- >
如果我们要只筛选其中的第六列来进行统计,并且只列出做多的前三项,我们可以使用管道来高效的处理
> awk '' job_new | sort | uniq -c | sort -n | tail -3
306 /B/CqLZs/adZ/Kaquhx/dlu-polid/201>
361 /B/zB/Nt766la/eCq/BxWtZua
478 /B/zB/Nt766ea/eCq/BxWtZua
操作过程为:打印文件的job_new第六列 -> 进行排序 -> 唯一化并且统计数量 -> 按照数量排序 -> 只列出top 3
这样基本上不需要打开文件可以抽取处理大部分的工作
5: ; : 前台命令结束符
当前命令输入结束的标志,使用”;”,可以将多个命令连续起来,但是命令之间没有传递关系:
> date ; sleep 3 ; date
Wed Jun 6 09:16:43 CST 2018
Wed Jun 6 09:16:46 CST 2018
这样做的好处是在一行里边完成多个命令。与之相反的就是下面这个 “\”
6: “\“ : 折行符,转义符
在用作折行符的时候,我们可以使用它来将空格替换成新行,可以增加可读性
> cat ./test2.tsh
#!/usr/bin/tcsh -f
echo "==Wieh \\ ceas"
foreach t ( \
1 \
2 \
3 )
echo $t
end
echo "==Normal ceas"
foreach t ( 1 2 3 )
echo $t
end
> ./test2.tsh
==Wieh \ ceas
1
2
3
==Normal ceas
1
2
3
在当作转义符时候,可以把特殊字符保留原本状态
> set t = test
> echo $t
test
> echo \$t
$t
7: &: 后台命令结束符
把当前命令提交到后台,单后继续执行下面的语句,
第一个例子,可以看到·,sleep 是在前台方式运行,两次dae的时间间隔就是sleep的时间
> date ; sleep 3 ; date
Wed Jun 6 19:36:06 CST 2018
Wed Jun 6 19:36:09 CST 2018
第一个例子,可以看到·,sleep 是在后台方式运行,两次dae是连续在前台执行,并没有间隔时间:
在三秒后,系统会返回一个后台命令语句执行完毕的提示;
> date ; sleep 3 & date
[1] 50350
Wed Jun 6 19:36:17 CST 2018
Wed Jun 6 19:36:17 CST 2018
>
[1] Done ( date; sleep 3 )
8: `: 命令摘取符,返回命令执行结果
这是一个很有用的特殊符号,和管道的方式相反,管道是将前面命令结果以字串的形式传递到后级,但是这个符号可以让当前命令的”返回值”成为前边命令的操作对象,
> ls test1.tsh | cat ; # 第一个命令通过管道后被转成了字符,然后被完整的cat出来
test1.tsh
> cat `ls test1.tsh` ; `CMD` 这个的返回值依然保留了文件的属性,所以文件内容被cat了出来
#!/usr/bin/tcsh -f
echo "$0 $*"
echo "$0 $1 $2 $10 $13"
传递命令结果应该是用``(命令摘取符),把命令结果当作字符处理应该是用 | (管道)
9: () : 子命令标识符
使用()括起来的命令,相当于在子shell里边运行的命令,其产生的所有影响不会体现到当前shell。
> set t = 1 ; echo $t ; # 本级shell定义了一个变量t
1
> ( set t = 2 ; echo $t ) ; # 子进程里边,也定义了一个变量t
2
> ( set t = 2) ; echo $t ; #父进程的变量保持不变,子进程的变量只在 () 里边生效,
1 #括号结束,子进程也就结束
10 || 和 &&:假和真
对于命令执行都有成功和失败的返回,cmd1 || cmd2 :前边命令不成功,才运行后面命令,例如:
> ls sdf || date
ls: cannot access sdf: No such file or directory
Wed Jun 6 20:17:15 CST 2018
cmd1 && cmd2 :前边命令成功,才运行后面命令,例如:
> ls test1.tsh && date
test1.tsh
Wed Jun 6 20:17:50 CST 2018
11: #: 注释的引导符
从#往后都是注释内容,这个规则仅限于shell解析器解析tsch文件,区别如下
> cat ./test3.tsh
#!/usr/bin/tcsh -f
foreach t ( 1 2 3 )
echo $t # echo "more word"
end
> ./test3.tsh
1
2
3
> foreach t ( 1 2 3 )
foreach? echo $t # echo "more word"
foreach? end
1 # echo more word
2 # echo more word
3 # echo more word
在所有的脚本文件的第一行,永远都需要使用 #! 来给出你的程序解析器的位置,这个解析器决定了你的脚本使用的语言,文件后缀名不决定任何解析器。
> cat ./test4.tsh
#!/usr/bin/tclsh8.5 ; # 这里的解析器定义为了tcl,尽管文件名是*.tsh
foreach t ( 1 2 3 )
echo $t # echo "more word"
end
> ./test4.tsh ;# tcsh的语法不能被tcl解析,报错
wrong # args: should be "foreach varList list ?varList list ...? command"
while executing
"foreach t ( 1 2 3 ) "
(file "./test4.tsh" line 2)
12: ““, ‘’,{}:其他括号/引号
““ 将其中文本的实际内容翻译出来,尤其是变量和命令摘取符
> set t = test
> echo "this is a $t @ `date`" ; # 在双引号中,变量和命令摘符号都会增长工作
this is a test @ Wed Jun 6 20:32:47 CST 2018
> echo 'this is a $t @ `date`' ; # 在单引号里,特殊字符被保留,没有产生作用
this is a $t @ `date`
这里顺便要说一下转义符号“\“,这个符号可以呈现特殊字符原有的状态,但是在双引号”“的作用下,\是没有转义功能的,这个时候他和一些特定字符可以产生别的效果
> echo \$t ; echo "this is a \$t"
$t
this is a est ; # \t 有tabel的效果,所以$t先被解释成temp,结合\,就变成了table + est
{} 大括号是都一个变量描述的锚定
> echo $t ; echo "this is a $t_new"
test
t_new: Undefined variable.
所有的变量引示符号$都是贪婪性的,知道遇到了一个shell的元字符,保留字符,对于$t_new,系统会去寻找变量t_new而不是t,如果你不熟悉系统的保留字,使用{}可以解决这类尴尬
> echo "this is a $_new" ;
this is a test_new
当然,利用系统保留字也是可以的
> echo "this is a $.new" ;
this is a test.new
这里我们可以在回想一下,变量名的命名这个基本问题,
a.首个字符必须为字母(a-z,A-Z)
b.中间不能有空格,可以使用下划线(_)
c.不能使用标点符号
d.不能使用tcsh里的保留字
通过以上的描述,我们大体上已经了解shell里边的特殊字符的特点及用法。相信对你的shell变成一定有所帮助,觉得喜欢,就点个赞吧!
轻触进入后端讨论群:
猛戳关注公众号
领取专属 10元无门槛券
私享最新 技术干货