Zsh 开发指南(第十六篇 alias 和 eval 的用法)

导读

alias(别名)在 shell 中是非常常用的,它主要用于给命令起别名,简化输入。但主要用于交互场景,在脚本中基本用不到。eval 是一个非常强大的命令,它的功能是将字符串解析成代码再执行,但也会额外增加很多复杂性,非必要场景尽量少用。alias 和 eval 看起来好像没什么关系,但功能上有相似之处,所以放在一起讲。

alias

最典型的例子是将 ls -l 简化成 ll:

% alias ll='ls -l'
% ll
total 0
drwx------ 0 goreliu goreliu 512 Aug 31 13:55 tmux-1000
drwxr-xr-x 0 goreliu goreliu 512 Aug 31 13:37 yaourt-tmp-goreliu

alias 的效果相当于直接将字符串替换过来,比较好理解。

# 直接运行 alias,会列出所有的 alias
% alias
ll='ls -l'
lla='ls -F --color --time-style=long-iso -lA'
...

这样的 alias 只有在行首出现时,才会被解析。但 zsh 中还有一种功能更强大的全局 alias,不在行首也能被解析:

% alias -g G='| grep'

% ls G tmux
tmux-1000

但这样需要格外注意可能导致的副作用,比如我想创建一个名为 G 的文件:

% touch G
touch: missing file operand
Try 'touch --help' for more information.
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.

结果 G 被替换了,只能在 G 两边加引号。

如果全局 alias 没用好,可能导致灾难性的后果,比如误删重要文件(像把某个全局 alias 传给 rm 后,恰好删除了 alias 字符串中的某些文件),所以需要执行权衡后再使用,并且用的时候要多加注意。

eval

eval 的功能是将字符串作为代码来执行。看上去好像很简单,但实际涉及很复杂的内容,主要是符号转义导致的语义问题。

在 bash 中,eval 的一个重要的使用场景是将变量的值当变量名,然后取它的变量值,类似于 c 语言中指向变量的指针:

% str1=str2
% str2=abc
% eval echo \$$str1
abc

注意这里有一个 和两个 $,原因是第二个 $ 是和平时一样,正常取 str1 的值的,而第一个 $ 需要转义,因为它要在 eval 执行的过程中取 str2 的值,不能现在就展开。

这个用法很容易出问题,而且可读性很差。幸好 zsh 中无需这么用,有更好的办法:

% str1=str2
% str2=abc
% echo ${(P)str1}
abc

(P) 专门用于这种场景,不需要再去转义 $。

此外 eval 有时也用来动态执行代码,比如一个脚本接受用户的输入,而这输入也是一段脚本代码,就可以用 eval 来运行它。但这种用法是极其危险的,因为脚本中可能有各种危险操作,而且 shell 的语法很灵活,很难通过静态扫描的方法判断是否有危险操作。不可靠的代码根本不应该去运行。即使一定要运行,也可以先写到文件里再运行,避免传过来的代码影响到自身的逻辑。

但也不是说 zsh 中就完全没有必要用 eval 了,在某些特别的场景(比如用于改造语法加语法糖)还是有用的。但如果要使用,就一定要注意它可能导致的副作用,利弊只能自己权衡了。eval 的具体用法,和 bash 中的基本没有区别,可以去网上搜索 bash eval 用法来了解,这里就不介绍了。

总结

本文简单介绍了 alias 的用法和 eval 的场景使用场景。alias 很简单,主要在 .zshrc 里使用。eval 很复杂,非必要场景尽量避免使用。

本文不再更新,全系列文章在此更新维护:github.com/goreliu/zshguide

付费解决 Windows、Linux、Shell、C、C++、AHK、Python、JavaScript、Lua 等领域相关问题,灵活定价,欢迎咨询,微信 ly50247。


陌辞寒的技术博客
近期主要更新 Vim 相关文字。
1.9k 声望
108 粉丝
0 条评论
推荐阅读
Vim 操作实用案例分析(一):批量在行首或行尾添加内容
我们写代码或者文档时,经常需要在多行的行首或者行尾添加同样的内容,手动一行行操作显然效率很低,做这样的事情有方便的技巧。 案例一 把 {代码...} 改成 {代码...} 注释掉一段代码是非常常用的操作,很多人都...

陌辞寒阅读 8.5k

使用kubeasz部署高可用kubernetes集群
本实验采用kubeasz作为kubernetes环境部署工具,它是一个基于二进制方式部署和利用ansible-playbook实现自动化来快速部署高可用kubernetes集群的工具,详细介绍请查看kubeasz官方。本实验用到的所有虚拟机默认软...

李朝阳4阅读 789

100 行 shell 写个 Docker
在初接触Docker的时候,我们必须要了解的几个概念就是Cgroup、Namespace、RootFs,如果本身对虚拟化的发展没有深入的了解,那么很难对这几个概念有深入的理解,本文的目的就是通过在操作系统中以交互式的方式去理...

vivo互联网技术2阅读 453

麒麟操作系统 (kylinos) 从入门到精通 - 故障排查篇
OS平台:银河麒麟桌面操作系统(飞腾版)V10 SP1操作系统镜像:Kylin-Desktop-V10-SP1-General-Release-2203-ARM64

Oulaa3阅读 1.6k

封面图
linux中用户登录加载配置文件的过程
shell的类型(站在用户登录登录的角度)登录式shell正常通过某终端登录su - USERNAMEsu -l USERNAME非登录式shellsu USERNAME图形终端下打开命令窗口自动执行的shell脚本用户登录时相关的bash配置文件全局配置文件/...

Dabric阅读 5.3k评论 3

在Linux上查看活跃线程数与连接数
现如今,有两种常见的软件资源几乎成了Java后端程序的标配,即线程池与连接池,但这些池化资源非常的重要,一旦不够用了,就会导致程序阻塞、性能低下,所以有时我们需要看看它们的使用情况,以判断这里是否是瓶颈。

扣钉日记3阅读 1.1k

封面图
Ubuntu 20.04 搭建 Elasticsearch 7.x 小集群(qbit)
环境ES 节点硬件:3 台 AWS m5.4xlarge(16 vCPU/64GB 内存)Kibana 硬件:1 台 AWS m5.large(2 vCPU/8GB 内存)操作系统:Ubuntu 20.04 LTSElasticsearch 7.9.3Kibana 7.9.3机器示意图操作系统这里主要讲 EBS ...

qbit阅读 3.8k

1.9k 声望
108 粉丝
宣传栏