一些相对晦涩的洗礼小贴士

2020-05-10 07:33:55

继之前关于bash的帖子之后,这里还有一些相对鲜为人知或很少看到的bash技巧,但仍然值得了解。

通常,当我想要在shell命令旁边添加注释时,我会将其放在末尾,如下所示:

但是直到最近,我还不知道可以使用冒号操作符在命令链中嵌入注释:

(回声香蕉;:如果您正在从StackOverflow复制\请注意\这是危险的)|tr';b';m';

您可能已经熟悉2>;&;1,它将标准错误重定向到标准输出,但在我在手册中偶然发现它之前,我不知道您可以像这样通过管道将标准输出和标准错误同时导入管道的下一阶段:

此构造允许您在脚本中指定特定字节,而不必担心触发某种编码问题。下面是一个命令,它将grep遍历文件,以递归方式查找十六进制的英国货币(‘GB’)符号:

如果您担心安全问题,并且曾经键入过可能包含敏感数据的命令,那么这个命令可能会很有用。

如果您键入历史文件中指定的命令,则此环境变量不会放入这些命令。命令之间用冒号分隔:

您必须指定整行,因此如果要排除命令及其参数或标志,可能需要全局字符。

如果你喜欢这本书,你可能会喜欢我的一本书:以艰难的方式学习打击以艰难的方式学习Git以艰难的方式学习Terraform。

如果readline键绑定不在您的掌握之中,那么这个可能会派上用场。

它会调用您最后运行的命令,并将其放入首选编辑器(由EDITOR变量指定)。编辑完成后,它将重新运行该命令。

如果您不想在bash中使用$[]构造来处理变量,那么可以使用C样式的复合命令。

另一个内置的bash命令,caller给出关于您的shell的上下文的上下文。

SHLVL是一个相关的shell变量,它提供调用堆栈的深度级别。

下面是一个DIE函数,改编自bash黑客的wiki,它通过调用帧提供堆栈跟踪:

#!/bin/bashdie(){LOCAL FRAME=0((FRAMELEVEL=SHLVL-FRAME))ECHO-n";${FRAMELEVEL}:";While调用者$FRAME;DO((FRAMELEVEL=SHLVL-FRAME))如果[[${FRAMELEVEL}-GT-1]],则ECHO-n";${FRAMELEVEL。

3:17 f1./caller.sh2:18 f2./caller.sh1:19 f3./caller.sh0:20 main./caller.sh*出现错误*。

如果您发现自己在没有任何网络工具的Kubernetes集群服务网格内运行的容器上(这是一种令人沮丧的常见体验),这个工具可能会特别方便。

Bash为您提供了一些虚拟文件,当引用这些文件时,可以创建到其他服务器的套接字连接。

例如,此代码段向站点发出Web请求并返回输出。

第一行将文件描述符9打开到端口80上的主机brvtsdflnxhkzcmw.NETSSL.com进行读写。第二行将原始HTTP请求发送到该套接字连接的文件描述符。最后一行检索响应。

显然,这不能为您处理SSL,所以现在它的使用受到限制,因为几乎每个人都在https上运行,但是当从服务网格中的应用程序容器运行时,仍然可以证明它是非常有价值的,因为那里的请求是使用HTTP发起的。

它似乎特别适合以细粒度的方式管理其他流程的输入和输出。下面是一个带注释且琐碎的示例:

coproc testproc(i=1,而true执行回显";迭代:${i}";((i++))读取-r行回显";${aline}";完成)。

在子shell中,有一个永不结束的While循环,它用i变量计算自己的迭代次数。它输出两行:迭代号和从标准输入读入的一行。

在创建协进程之后,bash使用标准输入和标准输出的文件描述符号设置一个具有该名称的数组。所以这就是:

Bash还使用协进程的进程标识符设置一个变量,您可以通过回显它来查看该变量:

现在,您可以随意将数据输入到该协进程的标准输入,如下所示:

在本例中,该命令解析为:echo input1>;&;60,并且>;&;[INTEGER]结构确保重定向转到协进程的标准输入。

现在,您可以用类似的方式读取协进程的两行输出,如下所示:

如果您愿意的话,可以使用它来创建一个类似于Expect的脚本,但是如果您想要管理输入和输出,那么它通常会很有用。命名管道是实现类似结果的另一种方式。

!/bin/bashcoproc testproc(i=1而true do echo";iteration:${i}";((i++))read-r Aline echo";${Aline}";Done)echo";${testproc[@]}";echo";${testproc_pid}";echo input1>;&;";${testproc[1。read-r output1b<;&;";${testproc[0]}";echo";${output1a}";echo";${output1b}";echo input2>;&;";${testproc[1]}";read-r output2a<;&;";${testproc[。${output2a}";echo";${output2b}";

如果你喜欢这本书,你可能会喜欢我的一本书:以艰难的方式学习打击以艰难的方式学习Git以艰难的方式学习Terraform