Shell基础

Shell 基础

Shell 与终端

当Shell启动时,操作系统为它提供三个文件来工作:stdinstdoutstderr。当从终端运行时,stdin连接到键盘输入。你写的内容被传递到终端。这通过一个称为电传打字机或tty的文件发生。stdoutstderr也连接到tty,这就是为什么你运行的任何命令的输出和错误都会显示在终端中。

你打开的每个终端都会通过tty分配一个新文件,这样来自一个终端的命令不会破坏另一个终端的命令。你可以通过tty命令找出你的终端连接的文件:

$ tty
/dev/pts/0

管道(Pipes)

管道,|,将两个进程连接在一起。它表示对pipe()的系统调用,它所做的只是为进程重定向stdinstdout

$ echo ls | bash

上图是一个轻微的简化,用于解释管道重定向:

  • 上层的bash分叉另一个连接到tty的bash,它产生ls的输出

  • 由于上层的bash是从下层分叉的,它继承了下层的文件描述符

  • 下层的bash没有分叉新进程,因为echo是内置命令

$ ls -ail | sort -nr -k 6 | head -n 1 | cut -f 9 -d ' '

注意stderr总是直接路由到tty。你可以在管道之前切换流,并将stderr而不是stdout重定向到管道。

$ ./script.sh 2>&1 >/dev/null

变量

局部变量是你在shell中创建的变量。它们是局部的,因此不会传递给子进程(记住,每个非内置命令都在一个新的shell中,没有这些局部变量)。

环境变量env vars)类似于全局变量。它们被传递给子进程。但是,子进程中环境变量的更改不能传递给父进程(记住,子进程和父进程之间除了退出码外没有通信)。

$ env
TERM=xterm
TMPDIR=/tmp
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
SHLVL=1
HOME=/root
LANGUAGE=en_US:en
LESSOPEN=||/usr/bin/lesspipe.sh %s
_=/bin/env

Shell 类型

Bash (Bourne Again Shell)

  • 最常用的Linux shell

  • 功能丰富,兼容性好

Zsh (Z Shell)

  • 更现代化的shell

  • 强大的自动补全功能

Fish (Friendly Interactive Shell)

  • 用户友好的shell

  • 智能建议和语法高亮

Sh (Bourne Shell)

  • 最基础的shell

  • 所有shell的兼容基础

Shell 脚本基础

#!/bin/bash

# 注释
# 变量赋值
NAME="World"

# 使用变量
echo "Hello, $NAME!"

# 条件语句
if [ "$NAME" == "World" ]; then
    echo "Greetings, World!"
else
    echo "Hello, $NAME!"
fi

# 循环
for i in {1..5}; do
    echo "Count: $i"
done

# 函数
greet() {
    echo "Hello, $1!"
}

greet "Alice"

常用Shell命令

# 查看当前shell
$ echo $SHELL
$ echo $0

# 切换shell
$ zsh
$ bash

# 查看历史命令
$ history
$ history | grep "pattern"

# 重复上一个命令
$ !!

# 重复包含特定模式的命令
$ !pattern

# 查看当前工作目录
$ pwd

# 改变目录
$ cd /path/to/directory

# 列出文件
$ ls -la

# 创建目录
$ mkdir new_directory

# 删除文件
$ rm file.txt
$ rm -rf directory/  # 递归删除目录

Shell 配置文件

  • ~/.bashrc - Bash的配置文件

  • ~/.bash_profile - 登录时执行的配置

  • ~/.profile - 通用配置文件

  • /etc/bashrc - 系统级配置文件

参考资料

最后更新于