Linux shell

TLDR: 在多次尝试 zsh之后,2023 还是回到了bash

Linux shell

sh

linux默认的 /bin/sh

Bash(GNU Bourne-Again SHell)

https://www.gnu.org/software/bash/

ubuntu默认的, 我一直以来用的最多的

1
2
3
4
docker run -it --rm ubuntu
echo $SHELL
#或者
grep root /etc/passwd

bash提供的增强包括:

  • 命令行编辑
  • 无限大小的命令历史
  • job control,
  • shell函数和 aliases
  • 无限大的indexed arrays
  • 从2到64的任何基数的整数算术

以及日常自己写点shell脚本来增强一下就行了

Dash(Debian Almquist shell)

http://gondor.apana.org.au/~herbert/dash/

POSIX-兼容的 /bin/sh实现,目标是尽量小(且不牺牲速度),大多数情况比Bash快

但因此用户体验就不太好了

A tale of two shells: bash or dash

Z Shell

https://zsh.sourceforge.io/

https://wiki.archlinuxcn.org/wiki/Zsh

z shell logo

zsh是一个为交互式使用而设计的shell,尽管它也是一种强大的脚本语言。bash、ksh和tcsh的许多有用的功能都被整合到了zsh中;同时还增加了许多原创的功能。

直接看目录 https://zsh.sourceforge.io/Intro/intro_toc.html

以及官方的FAQ: https://zsh.sourceforge.io/FAQ/

Bourne-Again Shell,bash,是另一个增强的类似Bourne的shell;与zsh最明显的区别是,它并不试图模仿Korn shell。由于这两个shell都在积极开发中,所以在这里说得太具体可能不太明智。大体上说,bash更关注标准的遵守(即POSIX),而且到目前为止,它避免了zsh所具有的更多的深奥的交互功能(可编程完成等)。


很久很久以前用过一下oh my zsh, 但是它的启动速度给我劝退了, 现在似乎修复了?

然后似乎time在zsh是一行需要改TIMEFMT

安装

1
2
sudo apt install zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Oh My Zsh是一个令人愉快的、开源的、社区驱动的框架,用于管理你的Zsh配置。它捆绑了数以千计的有用功能、助手、插件、主题,还有一些让你大呼过瘾的东西。


插件

https://github.com/zsh-users/antigen

https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md

https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/web-search

https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/dirhistory

https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/history

https://github.com/ohmyzsh/ohmyzsh/tree/master/plugins/z

https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/INSTALL.md

Fish

https://fishshell.com/

  • 自动建议命令
  • 辉煌的VGA色彩: fish支持24位真彩色,是终端技术中最先进的技术。看哪,单空格的彩虹。
  • 理智的脚本编写: fish是完全可编写脚本的,其语法简单、干净、一致。你不会再写esac了。
  • 基于网络的配置: 对于那些拥有图形计算机的幸运儿来说,你可以在网页上设置你的颜色并查看功能、变量和历史记录。
  • man Page 补全:其他shell支持可编程的补语,但只有fish通过解析你安装的man page自动生成补语。
  • 开箱即用: fish会让你感到高兴,因为它具有标签完成和语法高亮等功能,而且没有任何新内容需要学习或配置。

安装

1
2
3
sudo apt-add-repository ppa:fish-shell/release-3
sudo apt update
sudo apt install fish

配置, 我配了个Dracula颜色 + Informative(prompt)的和我之前bash自己配的比较接近

1
fish_config

然后改了一下十分痛苦, 例如 它自带的很多函数,是靠配置变量再调用的,十分奇怪而不是传参

以及它自己的一套脚本语言, 虽说是开箱即用但是自定义化还是很痛苦

配置页面能看一些东西,但是没有自动关联文档跳转, 提供的prompt 也没有直接展示源码

配置修改后触发command 存在未使用新的样式的问题, 估计哪里cache出问题了 还是没检测到文件变化, 对于本来命令行就需要高速操作来说


官方git里有个share/functions (https://github.com/fish-shell/fish-shell/tree/master/share/functions)里面似乎有点有不少有用的,但是不是我自己发现的话,他文档上似乎完全没说体验很差

所以 感觉fish有些想法是好的(比如从历史里命令 来做建议,所以其实体验下来吵闹大于帮助,跟copilot一样的感觉), 但迁移并不是那么容易

写了个 ~/.config/fish/functions/fish_prompt.fish, 但依然有些需要没有

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function show_ipv4 --description "display ip only"
ifconfig | awk '/^(\t)|(\s*)inet / { printf "%s ",$2 } '
end

function fish_prompt --description 'Informative prompt'
#Save the return status of the previous command
set -l last_pipestatus $pipestatus
set -lx __fish_last_status $status # Export for __fish_print_pipestatus.

if functions -q fish_is_root_user; and fish_is_root_user
printf '%s@%s %s%s%s# ' $USER (prompt_hostname) (set -q fish_color_cwd_root
and set_color $fish_color_cwd_root
or set_color $fish_color_cwd) \
(prompt_pwd) (set_color normal)
else
set -l status_color (set_color $fish_color_status)
set -l statusb_color (set_color --bold $fish_color_status)
set -l pipestatus_string (__fish_print_pipestatus "[" "]" "|" "$status_color" "$statusb_color" $last_pipestatus)
printf "\n%s%s %s%s \n" (set_color normal) (date "+%Y/%m/%d %H:%M:%S") \
(set_color $fish_color_comment) (show_ipv4)
printf '%s%s %s%s %s%s %s%s %s \n' (set_color brblue) $USER \
(set_color $fish_color_cwd) (prompt_pwd -D 99) \
(set_color normal) (__fish_vcs_prompt) \
$pipestatus_string \
(set_color normal)
echo
end
end

benchmark

bench.sh
1
2
3
for i in $(seq 1 1000);
do bash -c ":" ;
done
1
2
3
4
time dash bench.sh
time bash bench.sh
time zsh bench.sh
time fish bench.sh

https://github.com/shellspec/shellbench

查看,切换

查看

1
cat /etc/shells

切换

1
chsh -s /bin/bash