
获得徽章 0
- Linux 命令行的命令扩展
在 shell 中可以将命令 A 的输出作为命令 B 的参数,命令 A 需要放到「$()」的括号内,比如这条命令:ll $(which cp),将命令 which cp 的输出作为参数传递给了 ll 命令,这样我们就可以得到 cp 这个程序的相关信息,而不用关心 cp 程序的文件到底放在哪个目录下。执行效果如图一所示。
命令扩展也可以执行较复杂的管道命令。比如这条命令:file $(ls -d /usr/bin/* | grep zip),grep 的输出变成了 file 的参数。如图二所示。
bash 还支持另外一种语法,就是用反引号「`」代替 「${}」,如图三所示。但是不建议在命令扩展中使用反引号,尤其是在 shell 脚本中用到命令扩展的时候。因为反引号和单引号「'」比较相似,容易混淆,给维护 shell 脚本造成困难。展开赞过评论1 - Linux 命令行的括号扩展
括号扩展应该是最强大的一种扩展了。有了它,就可以利用带花括号的模式串生成多个文本字符串。如图一所示,这是最简单的一种括号扩展,「Front-{A,B,C}-Back」叫做模式串,其中「{A,B,C}」是括号表达式,「Front-」是前缀,「-Back」是后缀。
图一中的括号表达式「{A,B,C}」中的逗号是分隔符,表明 A、B、C 是三个单独的字符。表达式中还可以用「..」表示范围,比如「{A..E}」表示 A 到 E 之间的所有字母,包括 A 和 E,使用效果如图二所示。
在 bash 4.0 及以上的版本中,数字前面还可以用 0 填充,如图三所示。
括号表达式也支持倒序输出以及嵌套,如图四所示。
当我们需要批量创建文件或者目录时,使用括号扩展会很方便。比如,我想创建一批命名格式为「yyyy-MM」的目录,用以存放2020年1月到2021年12月期间每个月的日志文件,如果一个目录一个目录地去创建,不仅枯燥繁琐而且容易出错,用括号扩展,一个命令就搞定:mkdir {2020..2021}-{01..12},效果如图五所示。展开赞过评论1 - 不管是指令还是数据,在计算机硬件层面都是二进制。将指令和数据以相同的方式处理,极大地简化了计算机系统的存储器硬件和软件。尤其是用于数据的存储技术同样也适用于程序,如编译器,它能够将那些用易于人类使用的符号写的代码翻译成机器能理解的代码。评论点赞
- Linux 命令行的算术扩展
在 shell 中可以通过扩展的方式执行算术运算,我们称之为算术扩展,这使得我们可以把命令行当做计算器来使用。算术扩展的使用方式如下:$((expression)),其中 expression 是算术表达式,由数字和操作符组成(如图一所示)。算术扩展支持的运算符如图二所示,需要说明的是,算术扩展只支持整数运算,对于除法的结果,会向下取整,比如 5 / 2 的结果是 2。算术表达式的也可以嵌套,比如这样: $(($((5**2)) * 3)),算术表达式内可以用单个的圆括号组织多个子表达式,所以前面那个表达式也可以写成这样:$(((5**2)*3)),两者是等价的。
算术表达式内部可以有空格展开评论点赞 - Linux 命令行的扩展
每当我们在命令行中输入一个命令并按下回车键的时候,shell 都会对这条命令中的内容做一些替换,然后再执行这条命令,对命令内容做替换的过程叫做 expansion,翻译成中文应该是叫「扩展」,或者说是「转义」,比如「ls a*」这个命令,输出的是所有文件名以 a 开头的文件,就是 shell 先对「ls a*」做了扩展,把 a* 替换成了当前文件夹下所有以 a 开头的文件名,然后再交由操作系统去执行替换后的命令。
上面说的这种对「*」的扩展叫做「路径名扩展」,也就是应用于文件路径的扩展。不止「*」,其他通配符的使用也属于路径名扩展。
还有一种扩展是「波浪号扩展」,就是这个符号:「~」,当它单独使用时,指代的是当前用户的家目录,比如「cd ~」就是打开当前用户的家目录(其实直接输入「cd」就可以打开家目录);当它后面跟用户名时,指代的是该用户的家目录,比如「cd ~foo」就是打开 foo 用户的家目录。
除此之外,还有算数扩展、括号扩展、参数扩展、命令扩展。展开赞过22 - 字符集是字符的集合,规定了字符对应的二进制表示方式,由于计算机只认识 0 和 1,所以我们平时使用的各种字符在计算机底层也必须用二进制表示,Unicode 就是一个包含了世界上几乎所有语言的每一个字符的集合。而字符编码则规定了字符的编码方式,常见的字符编码方案有 UTF-8、UTF-16、GBK 等。如果编码和解码的方式不匹配,就会产生乱码。最著名的乱码当属“锟斤拷”和“烫烫烫”了。
“锟斤拷”的来源是这样的。如果我们想要用 Unicode 编码记录一些文本,特别是一些遗留的老字符集内的文本,但是这些字符在 Unicode 中可能并不存在。于是,Unicode 会统一把这些字符记录为 U+FFFD 这个编码。如果用 UTF-8 的格式存储下来,就是\xef\xbf\xbd。如果连续两个这样的字符放在一起,\xef\xbf\xbd\xef\xbf\xbd,这个时候,如果程序把这个字符,用 GB2312 的方式进行 decode,就会变成“锟斤拷”。
而“烫烫烫”,则是因为如果你用了 Visual Studio 的调试器,默认使用 MBCS 字符集。“烫”在里面是由 0xCCCC 来表示的,而 0xCC 又恰好是未初始化的内存的赋值。于是,在读到没有赋值的内存地址或者变量的时候,程序就会输出“烫烫烫”。展开等人赞过44 - 衡量计算机性能的好坏有两个指标,一个是响应时间,一个是吞吐率。拿人来搬东西做类比的话,响应时间就好比一个人从 A 点搬东西到 B 点所用的时间,吞吐率就好比每次搬的东西的多少。
程序的响应时间包括了硬盘访问、内存访问、I/O操作和操作系统开销等一切时间,这些时间内 CPU 并没有运行我们自己的程序,所以我们真正关注的是 CPU 时间,即 CPU 真正运行我们自己的程序的时间。任何程序到了 CPU 层面都是一条条的指令,所以一个程序的 CPU 时间 = 程序包含的指令数 x 每条指令的平均时钟周期数 x 时钟周期,每条指令的平均时钟周期数简称为 CPI,时钟周期的倒数就是时钟频率,也就是我们常说的主频,所以 CPU 时间 = 指令数 x CPI / 时钟频率。
一开始,为了提高性能,计算机的设计者想法设法地提高主频,从 1978 年到 2000 年,CPU 的主频从 5 MHz 提高到 1.4 GHz,20 多年主频提升了近 300 倍。但是,随着主频的提升,功耗也越来越大,主频提升的速度慢慢降了下来,从 2000 年到 2019 年,CPU 主频只提升了 3 倍。
当 CPU 的性能在主频这里遇到瓶颈时,人们不得不另辟蹊径,在吞吐率上想办法。提高吞吐率的一个办法就是增加 CPU 的核数,以达到并行计算的目的,所以现在 4 核、8 核的处理器几乎成了标配。
但是 CPU 的核数也不可能无限制地加下去,除了上述两个方法,还有一些原则性的性能提升方法,比如加速大概率事件、通过流水线提高性能、通过预测提高性能等。展开等人赞过评论5