Shell 编程(一)

《linux 命令行与 shell 脚本编程大全(第3版)》读书笔记,2019-04-11 第一次更新。

Posted by D on April 11, 2019

基础命令

ls

$ ls -F # 用于区分目录和文件
Desktop/ Downloads/ Music/ Pictures/ Templates/ Videos/ Documents/ examples.desktop my_script* Public/ test_file

$ ls -l # 用于显示长列表格式的输出
# 文件类型 文件权限 文件硬链接总数 文件属主的用户名 文件属组的组名 文件的大小(以字节为单位) 文件的上次修改时间 文件名或目录名
total 48
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Desktop
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Documents
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Downloads
-rw-r--r-- 1 christine christine 8980 Apr 22 13:36 examples.desktop
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fall
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fell
-rw-rw-r-- 1 christine christine 0 May 21 13:44 fill
-rw-rw-r-- 1 christine christine 0 May 21 13:44 full
drwxr-xr-x 2 christine christine 4096 May 21 11:39 Music
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_file
-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_scrapt
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script
-rw-rw-r-- 1 christine christine 0 May 21 13:42 new_file
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Pictures
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Public
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Templates
-rw-rw-r-- 1 christine christine 0 May 21 11:28 test_file
drwxr-xr-x 2 christine christine 4096 Apr 22 20:37 Videos

命令支持标准通配符。

ps

$ ps -lfa --forest # 常用命令
F S UID        PID  PPID  C PRI  NI ADDR SZ WCHAN  STIME TTY          TIME CMD
4 S root      9719  9490  0  80   0 - 67468 -      15:10 pts/0    00:00:01 smbd -FS --no-process-group
1 S root      9873  9719  0  80   0 - 66649 -      15:10 pts/0    00:00:12  \_ smbd -FS --no-process-group
1 S root      9874  9719  0  80   0 - 66651 -      15:10 pts/0    00:00:00  \_ smbd -FS --no-process-group
5 S systemd+ 10175  9719 29  80   0 - 70705 -      15:10 pts/0    01:47:46  \_ smbd -FS --no-process-group
4 S root      8933  3694  0  80   0 - 15962 -      15:06 pts/0    00:00:00 su
4 S root      8934  8933  0  80   0 -  5072 -      15:06 pts/0    00:00:00  \_ bash
4 S root      8981  8934  0  80   0 - 15962 -      15:10 pts/0    00:00:00      \_ su the-d
4 S the-d     8982  8981  0  80   0 -  5755 wait   15:10 pts/0    00:00:00          \_ bash
0 S the-d    15467  8982  0  80   0 -  5351 wait   20:13 pts/0    00:00:00              \_ bash
0 R the-d    27741 15467  0  80   0 -  9593 -      21:21 pts/0    00:00:00                  \_ ps -lfa --forest

df && du

$ df -hl # 常用命令
Filesystem      Size  Used Avail Use% Mounted on
udev            1.9G     0  1.9G   0% /dev
tmpfs           384M  1.5M  383M   1% /run
/dev/sda2         0G    0G    0G   0% /
tmpfs           1.9G     0  1.9G   0% /dev/shm
tmpfs           5.0M  4.0K  5.0M   1% /run/lock
tmpfs             0G     0    0G   0% /sys/fs/cgroup
/dev/loop0       91M   91M     0 100% /snap/core/6350
/dev/loop1       90M   90M     0 100% /snap/core/6673
/dev/sda1       511M  6.1M  505M   2% /boot/efi
tmpfs           384M     0  384M   0% /run/user/1000

$ du -sh * # 常用命令
16K     aria2
8.0K    bash
4.0K    code
4.0K    usb1

shell 的继承

父 shell 中可以开启新的子 shell,会有部分父进程的环境被复制到子进程中,子 shell 也可以有自己的子 shell。

进程列表

进程列表的语法为(command;),如果不加括号command;被称作命令列表。进程列表和命令列表的区别是命令列表会在一个单独的子进程中执行。

$ echo $BASH_SUBSHELL # 不在子进程中时,BASH_SUBSHELL 的值为0。
0

$ (echo $BASH_SUBSHELL)
1

$ (echo $BASH_SUBSHELL; (echo $BASH_SUBSHELL)) # 在子进程中时,返回子进程代号
1
2

进程列表是一种命令分组(command grouping)。另一种命令分组是将命令放入花括号中,并在命令列表尾部加上分号(;)。语法为 { command; }。使用花括号进行命令分组并不会像进程列表那样创建出子shell。其关系为:

.
+--命令列表
+--命令分组
   +--进程列表
   +--{ command; }

后台模式

后台模式可以避免一个命令长时间占据 cli。在命令的末尾加上&即可使命令在后台执行,如sleep 3 &

jobs -l命令可以查看当前运行在后台模式中的所有用户的进程。

协程

协程可以同时做两件事。它在后台生成一个子shell,并在这个子shell中执行命令。

$ coproc sleep 10
$ coproc NAME { sleep 10; }

内建命令与外部命令

外部命令

外部命令是指 bash shell 之外的命令,通常位于/bin/usr/bin/sbin/usr/sbin中,可以用 which 找到。

$ which ps
/bin/ps

$ which cd
# return none

当外部命令执行时,会创建出一个子进程。这种操作被称为衍生(forking)。外部命令 ps 很方便显示出它的父进程以及自己所对应的衍生子进程。子进程导致了外部命令的代价高于内建命令。

内建命令

内建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和shell编译成了一 体,作为shell工具的组成部分存在。不需要借助外部程序文件来运行。

cdexit 命令都内建于bash shell。可以利用 type 命令来了解某个命令是否是内建的。

$ type ps
ps is /bin/ps

$ type cd
cd is a shell builtin

有些命令有多种实现。例如 echo 和 pwd 既有内建命令也有外部命令。两种实现略有 不同。要查看命令的不同实现,使用 type 命令的 -a 选项。

$ type -a echo
echo is a shell builtin
echo is /bin/echo