首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Shell 里边的特殊字符

在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变成一定有所帮助,觉得喜欢,就点个赞吧!

轻触进入后端讨论群:

猛戳关注公众号

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180607G0F1NY00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券