Linux 学习笔记: Bash 一窥

这里主要是对于 bash 和一些基本命令行工具的简单介绍,就是窥探一下,心中有数。

bash毕竟是得操作才行,这里准备一些文件做操作,具体文件内容见最后。

寻求帮助

对于 bash 本身(builtin)的命令,使用 help 跟命令名来查询其帮助,例如:

$ help cd

对于其他非 bash 本身的命令使用 man 命令(不懂就找男人,BTW,emacs的 eshell下面帮助命令是woman)

$ man ls

路径操作

  • 绝对路径:从根目录开始的路径,/home/wolfson/Documents/README.md
  • 相对路径:相对于工作目录的路径,./当前目录,../父目录。
  • 家目录:~ 代表当前用户(假设是wolfson)的家目录,一般情况下可能是 /home/wolfson,或者 ~wolffather 代表 wolffather 用户的家目录,一般情况下 可能是 /home/wolffather

  • cd:change directory,切换目录,cd 后面跟目标路径作为参数,则可以从 当前目录切换到目标目录

# 通过绝对路径前往 /home/wolfson/Documents
$ cd /home/wolfson/Documents
# 前往上级目录 /home/wolfson
$ cd ..
# 前往上次所在的目录 /home/wolfson/Documents
$ cd -
# 通过相对路径前往 /home/wolfson/Downloads
$ cd ../Downloads
# 前往用户家目录 /home/wolfson
$ cd ~
$ cd
  • pwd:print working directory,显示当前的路径,其默认输出的值与 $PWD 变量中的值是一样的。
$ pwd
# 输出 $PWD 环境变量中的值(接受链接),也是默认输出
$ pwd -L
# 输出物理路径,可以避免路径中出现链接
$ pwd -P
  • mkdir:make directory,创建一个新目录
# 到家目录去
$ cd ~
# 创建一个叫 sequence 的新目录
$ mkdir sequence
# 递归创建目录
$ mkdir -p study/seq
  • rmdir:remove directory,删除一个空目录,可以说rmdir是mkdir的反面
# 删除一个叫 sequence 的空目录
$ rmdir sequence
# 递归删除目录
$ rmdir -p study/seq

$PATH 变量

系统根据PATH变量中的路径去寻找命令,PATH中的目录根据冒号来分割。系统首 先在第一个路径中去寻找命令,如果找到则使用该命令,如果没有找到则去下一 个目录寻找该命令。如果所有的目录都没有找到命令,则报错。

$ echo $PATH
/home/wolfson/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

想要把非PATH路径中的命令也加入到系统搜索目录中,只需要修改 PATH 变量。

$ export PATH=/new/path/to/add:$PATH

查看某个非bash内置命令实际的路径可以使用 which。

$ which ls
/bin/ls

文件及文件夹权限

  • 用户:linux下面的用户,文件的所有者。root用户是管理员。
  • 用户组:一个或多个用户组成的有相同用户性质的组,方便系统管理员管理。 用户组的名字可以和用户一样。如root用户组。

使用 ls 命令可以列出当前文件夹中的文件内容及文件权限:

$ ls -al
total 460
drwxr-xr-x 55 wolfson wolfson  4096 Dec 13 23:12 .
drwxr-xr-x  3 root    root     4096 Jul 31  2017 ..
drwxr-x---  2 root    root     4096 Sep 10  2017 .android
drwxrwxr-x  8 wolfson wolfson  4096 Nov 19  2017 .atom
-rw-rw-r--  1 wolfson wolfson   330 Oct 23 13:41 .bash_aliases
-rw-------  1 wolfson wolfson 53135 Dec 13 23:12 .bash_history
-rw-r--r--  1 wolfson wolfson   220 Jul 31  2017 .bash_logout
-rw-r--r--  1 wolfson wolfson  3985 Aug  2  2017 .bashrc

最开头的十个字符分别表示文件类别和不同用户对该文件的权限。 例如 -rw-r--r-- 1 wolfson wolfson 3985 Aug 2 2017 .bashrc

  1. 第一个字符代表文件类别:例子中是 - 代表的是普通文件
  2. - 代表普通文件
  3. d 代表目录
  4. l 代表连接文件
  5. b 代表设备文件中的可存储设备
  6. c 代表设备文件中的串行端口设备,如键盘鼠标
  7. 第二到第四个字符为拥有该文件的用户的权限:例子中是 rw-,代表可读可写
  8. - 为占位符,无权限
  9. r 可读权限,数字表示为 4
  10. w 可写权限,数字表示为 2
  11. x 可执行权限,数字表示为 1
  12. 第五个到第七个字符为文件所有者所在用户组的成员权限:例子中是 r--,代表可读
  13. 第八个到第十个字符为文件除了文件所有者与其用户组成员外的其他人的权 限:例子中是 r--,代表可读权限
字符标记 数字标记 含义
---------- 0000 无权限
-rwx------ 0700 用户可读可写可执行
-rwxrwx--- 0770 用户和用户组可读可写可执行
-rwxrwxrwx 0777 用户,用户组和其他人可读可写可执行
---x--x--x 0111 所有人可执行
--w--w--w- 0222 所有人可写
--wx-wx-wx 0333 所有人可写可执行
-r--r--r-- 0444 所有人可读
-r-xr-xr-x 0555 所有人可读可执行
-rw-rw-rw- 0666 所有人可读可写
-rwxr----- 0740 用户可读可写可执行,用户组可读

权限管理有一些命令:

  • chown:change owner,改变文件或文件夹的所有者
  • chgrp:change group,改变文件或者文件夹的用户组
  • chmod:change mode,改变文件或者文件夹的权限
$ chrgrp root sgRNA.txt
$ chrgrp wolfson sgRNA.txt
$ chrown dog sgRNA.txt
$ chrown wolfson sgRNA.txt
$ chmod u+x sgRNA.txt
$ chmod g+w sgRNA.txt
$ chmod 644 sgRNA.txt

文件操作

常用的文件操作就是显示属性,复制,删除,重命名,移动等。

  • ls:list,查看文件和目录,隐藏文件是以 . 开头命令的文件,使用 -a 参数查看
# 只是简单看一下家目录下有啥
$ ls ~
# 看一下家目录下所有的文件,包括隐藏文件
$ ls -a ~
# 看一下家目录下所有的文件的具体信息
$ ls -al ~
# 列出文件夹及子文件夹中内容
$ ls -R ~
  • cp:copy,复制文件或者文件夹
# 先创建一个文件夹 ./library/data
$ mkdir -p library/data
# 把 sgRNA.txt 复制到新创建的 ./library/data 文件夹中
$ cp sgRNA.txt ./library/data/
# 也可以
$ cp sgRNA.txt ./library/data/sgRNA.txt
# 复制一个文件夹
$ cp -r ./library ./library2
# 复制一个文件
$ cp sgRNA.txt sgRNA2.txt
  • rm:remove,删除文件或者文件夹。删除命令很危险,一旦删除恢复起来就很 难了,最好使用 -i 或者 -I 参数来设置提醒。
# 删除一个文件
$ rm -i sgRNA2.txt
# 删除包含文件的文件夹
$ rm -ri library2
  • mv:move,移动或者重命名文件或者文件夹
# 复制一个文件
$ cp sgRNA.txt sgRNA3.txt
# 重命名一个文件
$ mv sgRNA3.txt sgRNA4.txt
# 移动一个文件
$ mv sgRNA4.txt ./library/
# 也可以
$ mv sgRNA4.txt ./library/sgRNA4.txt

查看文件内容

  • cat:catenate,把文件从第一行输出到终端,可以连接多个文件
  • tac:从文件最后一行输出到终端,连接多个文件,cat反过来
  • nl: 输出文件并显示行号,类似 cat -n
  • more:一页页显示内容
  • less:比more更强大,可以翻页,less is more
  • head:显示文件前几行
  • tail:显示文件后几行

编辑与抓取流内容

  • grep:抓取符合模式的行
  • egrep:支持扩展的正则表达式即 grep -E
# 抓取有连着三个T的sgRNA
$ cat sgRNA.txt | egrep "T{3}"
  • cut:按照分隔符分列,并输出选择的列
# 以逗号做分隔符,选择第二列
$ cat sgRNA.txt | cut -d"," -f2
$ cut -d"," -f2 sgRNA.txt
  • tr:替换字符串
# 互补配对序列
$ cut -d"," -f2 sgRNA.txt | tr "ATCG" "TAGC"
  • rev:字符串顺序反转
# 互补配对序列
$ cut -d"," -f2 sgRNA.txt | tr "ATCG" "TAGC" | rev
  • sed:流编辑器
  • awk:文本编辑语言

输入输出和管道(pipeline)

一般bash下的命令都支持简单的标准输入输出,通过利用标准输入输出可以简化 任务(使用符号 <> 等)。另外,bash 还支持把一个程序的输出转为另一个程 序的输入,用比喻来说就像是石油管道(pipeline)一样,把流动的字符串从一 个命令导向另一个命令(使用符号 | )。

标准的输出输出包括三个:

  1. 标准输入:/dev/stdin
  2. 标准输出:/dev/stdout,序号为 1,默认输出到屏幕
  3. 标准错误输出:/dev/stderr,序号为 2,默认输出到屏幕

例如 cat 命令就把其标准输入的字符串输出到标准输出:

$ cat
I have seen things you people woundn't believe
I have seen things you people woundn't believe

很多时候我们需要重定向标准输出或者标准输入,比如从一个文件向向一个程序 输入而不是通过键盘敲入;或者把一个程序的输出结果输出到文件而不是屏幕。

如果要把一个文件传入一个命令的标准输入,即重定向标准输入,需要使用 < 符号。

$ rev < sgRNA.txt

rev 命令是把每行的字符串反向并输出到标准输出,'<' 把文件 /etc/passwd 的内容导向rev命令的标准输入。

如果我们想要把上条命令反向后的内容输出到一个文件,即重定向标准输出,则 需要使用 '>'。

$ rev < sgRNA.txt > ./revpasswd

如果我们是把一个程序的输出结果重定向到另一个程序的输入,则需要使用管道 (pipeline),在bash中是 |

例如把 cat 的结果输出到 rev 命令。

$ cat sgRNA.txt | rev

管道是可以连接多个命令的。

$ cat sgRNA.txt | rev | head -1
  • 标准输出:1>
  • 标准错误输出:2>
  • 标准错误输出导入标准输出:2>&1

任务管理

串联命令

有的时候两个命令运行,第二个命令是否运行依赖于第一个命令是否运行成功, 这种情况下我们可以使用 && 把两个命令串联起来。只有在第一个命令成功运 行后,才会运行第二个命令。

例如,sleep 命令是让bash“睡眠”也就是暂停运行下面的命令一段时间,date 命令则可以输出日期和时间。

$ date && sleep 5 && date

除了 && 起到了 AND 的作用,还可以使用 || OR 的作用。当使用 ||连 接两个命令的时候,当前面的命令正常运行的时候,后面的命令是不会运行的。 而当前面的命令运行失败的时候,后面的命令才会运行。

# 假如我们已经有了 sgRNA.txt 这个文件
$ [ -e sgRNA.txt ] && date
Tue Dec 25 20:33:05 CST 2018
$ [ ! -e sgRNA.txt ] && date
$ [ -e sgRNA.txt ] || date
$ [ ! -e sgRNA.txt ] || date
Tue Dec 25 20:33:43 CST 2018

在后台运行任务

打开一个 shell 之后,你的所有操作都在这个 shell 中进行。如果有程序占用 了shell,比如正在输出,你就不能进行其他操作。很多时候我们并不需要看着 程序输出信息,而是把任务放到后台。把运行的命令放在后台,只需要在运行命 令的时候在命令后面加上 &

我们可以把 sleep 命令放后台运行。

$ date
$ sleep 5 && date &

如果我们只是使用 & 把命令放后台,当我们登出 shell 的时候,shell 有可 能会发送终止信号把我们程序停止掉。如果我们希望程序能在我们退出 shell 的时候继续运行,则需要进行一定设置。我们可以直接设置 bash 让其不发出终 止信号,或者我们写脚本,可以去处理信号不让程序停止,但是对于一般的一条 命令的任务,这样做还是比较复杂。这样的情况下,我们可以使用 nohup 命令。

$ nohup sleep 5 && date > nohup.out &

这样就算我们退出 bash,命令依然会运行,并且把输出到标准输出的结果输入 到 nohup.out 文件中。

前台后台调度任务

要查看当前在后台的任务,我们可以使用 jobs命令。jobs 输出结果前面方括号 中的标号就是后台命令编号。

$ sleep 20 &
$ sleep 20&
$ jobs
[1]   Running                 sleep 20 &
[2]   Running                 sleep 20 &

如果我们要把 1 号任务提交到前台,则需要使用 fg 命令。

$ sleep 20 &
$ sleep 20 &
$ jobs
[1]   Running                 sleep 20 &
[2]   Running                 sleep 20 &
$ fg 1

如果我们想要暂停命令,则使用 CTRL-Z。

$ sleep 20
# CTRL-Z
$ jobs
[1]+  Stopped                 sleep 20

如果我们需要把暂停的命令放到前台去运行,则使用 fg 命令,如果要把暂停的 命令放在后台运行则使用 bg 命令。

$ sleep 20
# CTRL-Z
$ jobs
[1]+  Stopped                 sleep 20
$ bg
$ jobs
[1]+  Running                 sleep 20 &

在子 shell 中运行命令

如果我们需要获得文件建立时候的时间做文件名,就需要在文件建立的时候运行 一个 date 命令来获取时间这样就需要命令能够在子shell中运行并返回结果。 有两种表示可以在子shell运行命令。

  • 使用 "`" 符号:
$ thetime=`date`
$ echo $thetime
  • 使用小括号:
$ thetime=$(date)
$ echo $thetime

管理任务

在 Windows 下面有任务管理器,在bash中也可以查看和管理任务。ps命令可以 根据参数输出命令信息到标准输出。top命令则是交互式的任务管理命令。kill 命令可以终止任务。

kill 命令常用的是:

  • kill -9 PID 直接杀掉任务,没有任何后续处理
  • kill -15 PID 按照正常情况终止任务,更推荐

ps 命令可以把当前运行的程序都输出:

  • ps -elf 输出所有命令到标准输出,可以把结果导入到 grep 函数

top 命令可以交互式实时显示运行的任务,类似 Windows 或者 Mac OS 下的任 务管理器。

  • < 和 >: 用于选择用于排序的列.
  • P: 按照CPU使用排序显示进程.
  • M: 按照内存使用量排序显示进程.
  • F: 选择需要显示的列.
  • u: 选择要显示的用户的进程.
  • z: 显示颜色并高亮当前运行进程.
  • Z: 设置颜色
  • l: 上机时间统计显示.
  • m: Memory 统计显示.
  • t: Task/CPU 统计显示.
  • 1: 显示每个线程的情况
  • k: kill 相应的进程.
  • q: 退出 top.

样本文件

把下面文件内容存成相应文件就可以用了。建议在 shell 下使用 cat 或者 emacs/vim 去存。

$ cat << EOF > 文件名.txt
# 要输入的内容
EOF

sgRNA.txt

k1007_a_990,TATAGGCTAGAGGATTAGAG
k1007_s_616,TTTGCAATTCACCATCCTTC
k1007_s_784,AGAGACTTCTTGAAAGGGCG
k1007_a_62,GCGCAAGTCCAGAGTTTCCA
k1007_a_615,TACAACCAACACCCGAAGGA
k1007_s_529,TCACATCACAAGAAGTTCGA
k1007_s_293,TCAGAGGAGCTGCAATGAGA
k1007_s_1014,TCTAGCCTATAAGCCCTGTG
k1007_s_801,GCGAGGAAGCTTCTCTGTGA
By @Wolfson Liu in
Tags : #linux, #bash,