-
Notifications
You must be signed in to change notification settings - Fork 3
/
Bash.Rmd
7409 lines (5587 loc) · 284 KB
/
Bash.Rmd
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---
title: "Linux学习"
author:
- "易生信"
- "www.ehbio.com/Training"
- "train@ehbio.com"
date: "`r Sys.Date()`"
documentclass: article
site: bookdown::bookdown_site
---
```{r setup, include=FALSE}
library(knitr)
output <- opts_knit$get("rmarkdown.pandoc.to")
html = FALSE
latex = FALSE
opts_chunk$set(echo = FALSE, out.width="100%", fig.align="center", fig.show="hold", warning=FALSE, message=FALSE)
if (output=="html") {
html = TRUE
}
if (output=="latex") {
opts_chunk$set(out.width="95%", out.height='0.7\\textheight', out.extra='keepaspectratio=true', fig.pos='H')
latex = TRUE
}
html = TRUE
knitr::opts_chunk$set(cache=TRUE, autodep=TRUE)
mtime <- function(files){
lapply(Sys.glob(files), function(x) file.info(x)$mtime)
}
set.seed(0304)
```
```{asis, echo=html}
# EHBIO Gene Technology {-}
```
```{r cover, eval=html, out.width="99%"}
knitr::include_graphics("ehbio/cover.png")
```
<!--chapter:end:index.Rmd-->
# Linux初探,打开新世界的大门 {#linux_basic}
![](http://www.ehbio.com/ehbio_resource/Linux_course.png)
视频课程地址:<https://ke.qq.com/course/288048?tuin=20cd7788>
## Linux系统简介和目录理解 {#basicDir}
### 为什么要用Linux系统 {#why_linux}
个人认为,Linux操作系统和类Linux操作系统的命令行界面是最适合进行生物信息分析的操作系统。原因有三点:
* 长期运行的稳定性
* 多数软件只有Linux版本
* 强大的Bash命令简化繁琐的操作,尤其是大大简化重复性工作
但对于初学者来说,接触和理解Linux操作系统需要一些时间和摸索。陡然从可视化点选操作的Windows进入到只有命令行界面的Linux,最大的陌生感是不知道做什么,不知道文件在哪?
我们这篇教程就带大家学习、熟悉、体会Linux系统的使用。
### Linux系统无处不在 {#linux_everywhere}
* Linux是一种多用户、多任务的操作系统。最开始是由Linus Torvalds与1991年发布,后由社区维护,产生了不同的分发版。
* 常见版本有`Centos`, `Ubuntu`, `RedHat`, `Debian`等。服务器多用`Centos`系统,免费,稳定,但更新慢。`Ubuntu`系统更新快,注重界面的体验,适合自己笔记本安装。有面向中国的"麒麟"系统。其它两个没用过,`Centos`与`RedHat`, `Debian`与`Ubuntu`同宗,命令行操作起来很相似。
### 免费的Linux系统来一套 {#free_linux}
* 如果自己的单位有共有服务器,可以尝试申请账号。
* 自己的电脑安装双系统或虚拟机。
* 使用[gitforwindows](http://blog.csdn.net/woodcorpse/article/details/79313846)在windows下模拟使用Linux命令。
* 购买一块云服务器
* 试验下在线学习平台实验楼 <https://www.shiyanlou.com> (里面也有不少Linux教程,任意点一个进去,双击桌面的`Xfce`图标,都可以启动Linux终端)
* [这里有2个免费Linux系统等你来用](https://mp.weixin.qq.com/s/rXjQfyEX2FnuW9HTM_Uc8Q)
### Linux系统登录-联系远方的她 {#linux_login}
登录服务器的IP是:192.168.1.107; 端口是:22;用户名是每个人的姓名全拼,如陈同为chentong (全小写,无空格);密码是 yishengxin。
```{r, fig.cap="配置Xshell登录服务器1。"}
knitr::include_graphics(c("image/Linux_xshell1.png"))
```
```{r, fig.cap="配置Xshell登录服务器2。"}
knitr::include_graphics(c("image/Linux_xshell2.png"))
```
### 初识Linux系统 - 黑夜中的闪烁是你的落脚点 {#linux_cmd}
既然用Linux,我们就摒弃界面操作,体验其命令行的魅力和庞大。后续操作都是在命令行下进行的,主要靠键盘,少数靠鼠标。
登录Linux系统后,呈现在眼前的是这样一个界面:
```{bash eval=F}
Last login: Mon Jun 5 16:56:56 2017 from 239.241.208.209
Welcome to aliyun Elastic Compute Service!
ct@ehbio:~$
```
首先解释下出现的这几个字母和符号:
* `ct`: 用户名
* `ehbio`:如果是登录的远程服务器,则为宿主机的名字;若是本地电脑,则为自己电脑的名字。
* `~`: 代表家目录, 在我们进入新的目录后,这个地方会跟着改变
* `$`: 用来指示普通用户输入命令的地方;对根用户来说一般是`#`
* <http://bashrcgenerator.com/>可视化定制不同的显示方式。
* 个人习惯的展示:`PS1=\[\e]0;\u@\h: \w\a\]${debian_chroot:+($debian_chroot)}\u@\h:\w\$`
* 闪烁的光标处是你敲打键盘体验威力的地方 - 输入命令并按回车。
### 我的电脑在哪? {#my_computer}
打开Windows,首先看到的是桌面;不爱整理文件的我,桌面的东西已经多到需要2个屏幕才能显示的完。另外一个常用的就是我的电脑,然后打开D盘,依次点开对应的文件夹,然后点开文件。
Linux的文件系统组织方式与Windows略有不同,登录进去就是家目录,可视为Windows下的桌面[^Linux的家目录严格来说可能类似于Windows下的`C:\\Users\\ct`]。在这个目录下,我们可以新建文件、新建文件夹,就像在桌面上的操作一样。
而Linux的完整目录结构如下:
```{r, fig.cap="Linux目录层级结构。"}
knitr::include_graphics("image/Linux_dir.png")
```
```{bash eval=F}
# 若提示命令找不到,运行下面语句安装tree
# 需要有根用户权限
# yum install tree.x86_64
ct@ehbio:~$ tree -d -L 2 /
```
```{r}
directory = "Path;Description
/;根目录
/bin;常用软件如ls, mkdir, top等的存放地
/dev;硬件相关
/etc;存放系统管理和配置相关文件
/etc/cron*;与定时任务相关的文件夹,可执行程序放置到对应文件夹就可以定时执行
/etc/profile.d;目录下存放Bash相关的配置文件,相当于全局的.bashrc
/etc/profile.d/custom.sh;我在配置全局环境时,一般写入这个文件;如果不存在,可以新建。
/home;家目录,默认新建用户的个人家目录都在此文件夹下
/home/ct;用户名为ct的用户的家目录
/lib -> usr/lib;存放动态库的目录 (library),安装软件时碰到依赖的动态库一般存储于此
/lib64 -> usr/lib64;64位软件动态库,-> 表示软连接,等同于快捷方式
/mnt;文件系统挂载,一般插入U盘会显示在这。
/opt;部分额外安装的软件会置于此
/root;根用户的家目录
/sbin -> usr/sbin;根用户的管理命令
/tmp;临时目录,会定时清空,常用于存放中间文件
/usr;存放系统应用的目录,前面有几个目录都是该目录下子目录的软链
/usr/bin;大部分应用程序安装于此
/usr/sbin;根用户的管理命令
/usr/lib;存放动态库的目录 (library),安装软件时碰到依赖的动态库一般存储于此
/usr/lib64;64位软件动态库
/usr/local/bin;存放本地安装的命令
/usr/local/lib;存放本地安装的库
/var;存放各服务的日志文件。若装有网络服务,一般在/var/www/html下。
"
directory = read.table(text=directory, header=T,row.names=NULL,sep=";")
knitr::kable(directory, booktabs=T,caption="Linux下目录简介")
```
作为一个普通用户,通常只在`/home/usr`, `/tmp`下有**可写**的权限,其它目录最多是**可读、可执行**,部分目录连读的权限都没有。这种权限管理方式是Linux能成为真正多用户系统的一个原因。后面我们会讲解如何查看并修改这些权限。
### 系统配置怎样?来看看256M硬盘的服务器 {#linux_system_hardware}
看完目录结构了,来看一下硬盘有多大,有多少可用空间,只需要运行`df -h`命令。
```{bash eval=F}
ct@ehbio:~$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 193G 61G 122G 34% /
tmpfs 127G 344K 127G 1% /dev/shm
/dev/sda1 190M 77M 103M 43% /boot
/dev/mapper/a 37T 12T 25T 32% /ehbio1
/dev/mapper/b 37T 28T 8.8T 76% /ehbio2
/dev/mapper/c 37T 15T 23T 40% /ehbio3
```
除了看硬盘,还想看下CPU、内存、操作系统呢?
```{bash eval=F}
# serverInfo.sh是我写的一个脚本,这个脚本怎么实现的会是一个考核题目。
ct@ehbio:~$ serverInfo.sh
```
```
Hostname is localhost.localdomain,Ip address is 192.168.1.30.
The 64 bit operating system is CentOS release 6.9 (Final),
Nuclear info is 2.6.32-696.10.1.el6.x86_64.
The CPU is Intel(R) Xeon(R) CPU E9-5799 v2 @ 3.90GHz.
There are 8 physical cpu, each physical cpu has 0 cores, 0 threads.
There are 96 logical cpu.
The memory of this server is 252G.
```
### 看下目录下都有什么 {#directpry_show}
通常登陆后直接进入家目录,下面大部分操作也是在家目录下完成的。如果想查看当前目录下都有什么内容,输入命令 `ls`,回车即可 (ls可以理解为单词list的缩写)。当前目录下什么也没有,所以没有任何输出。
```{bash eval=F}
ct@ehbio:~$ ls
```
如果错把`l`看成了`i`,输入了`is`,则会出现下面的提示`未找到命令`。如果输入的是Linux基本命令,出现这个提示,基本可以判定是命令输入错了,瞪大眼睛仔细看就是了。 **在敲完命令回车后,注意查看终端的输出,以判断是否有问题。**
```{bash eval=F}
ct@ehbio:~$ is
-bash: is: 未找到命令
# 大小写敏感
ct@ehbio:~$ lS
-bash: lS: 未找到命令
```
当前目录下只有一个文件,看不出效果,我们可以新建几个文件和文件夹。
### 新建一个目录 {#mkdir}
`mkdir`是新建一个目录 (`m`a`k`e a `dir`ectory);`data`是目录的名字。
如果目录存在,则会出现提示,"无法创建已存在的目录"。这时可以使用参数`-p`忽略这个错误。
```{bash eval=F}
ct@ehbio:~$ mkdir data
ct@ehbio:~$ ls
data
ct@ehbio:~$ mkdir data
mkdir: 无法创建目录"data" : 文件已存在
# -p: no error if existing, make parent directories as needed
ct@ehbio:~$ mkdir -p data
```
`cat`是一个命令,主要用来查看文件;在这与`<<END`连用用于读入大段数据。输入`cat <<END`之后,回车,会看到终端出现一个大于号,大于号后面可以输入内容,再回车,继续输入内容,直到我们输入`END` (大写的,与上面一致),输入过程结束,我们输入的内容都显示在了屏幕上。
```{bash eval=F}
ct@ehbio:~$ mkdir data
ct@ehbio:~$ cat <<END
a
bc
END
a
bc
```
如果我们想把这些内容写入文件,就需要使用 `command > filename`格式。
`>`是一个重定向符号,即把前面命令的输出写入到`>`后面的文件中。如下所示,新建了一个`Fasta`格式的文件。
`ls -l`列出文件的详细信息;`-l`表示命令行参数,是程序预留的一些选项,保证在不更改程序的情况下获得更灵活的操作。可使用`man ls`查看`ls`所有的命令行参数, **上下箭头翻页**,按`q`退出查看。(man: manual, 手册)
```{bash eval=F}
ct@ehbio:~$ cat <<END >data/test.fa
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
>NANOG
ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
ACGGTAGCGAGTC
>mYC HAHA
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
END
## 注意命令和参数之间的空格
ct@ehbio:~/data$ ls-l
-bash: ls-l: 未找到命令
ct@ehbio:~$ ls -l
总用量 4
## d: dir; 表示data是个目录
## rwx:表示目录的权限,暂时忽略,或自己在线搜索
drwxrwxr-x 2 ct ct 4096 6月 8 14:52 data
ct@ehbio:~$ ls -l data
总用量 4
## 开头的`-`表示test.fa是个文件
-rw-rw-r-- 1 ct ct 284 6月 8 14:48 test.fa
```
### 访问文件 {#cat_file}
查看写入的文件的内容,`cat 文件名`;需要注意的是文件所在的目录,默认是当前目录;如下面第一个命令,会提示`cat: test.fa: 没有那个文件或目录`,是因为当前目录下不存在文件`test.fa`。(注意文件末尾的end)
```{bash eval=F}
# 这个应该是最常见的错误之一,程序不可能知道你的输入文件在什么地方,
# 需要人为指定。
# 如果未指定路径,表示当前目录
ct@ehbio:~$ cat test.fa
cat: test.fa: 没有那个文件或目录
ct@ehbio:~$ cat data/test.fa
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
>NANOG
ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
ACGGTAGCGAGTC
>mYC HAHA
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
`test.fa`在目录`data`下,可以先进入`data`目录,然后再查看文件。类比于Windows下先点开一个文件夹,再点开下面的文件。
这个例子中文件`test.fa`在当前目录的子目录`data`里面,在当前目录下直接查看`test.fa`就像在`我的电脑`里面不进入C盘,就像打开`Program file`文件夹。这属于**隔空打牛**的境界,不是一般人能练就的。起码Linux下不可以。
提到目录,Linux下有**绝对路径**和**相对路径**的概念。
* 绝对路径:以`/`开头的路径为绝对路径,如`/home/ct`, `/usr/bin`, `/home/ct/data`等。需要注意的是`~/data`等同于`/home/ct/data`, 多数情况下可以等同于绝对路径,但在一个情况下例外,软件安装时用于`--prefix`后的路径必须是`/`开头的绝对路径。
* 相对路径: 不以`/`和`~`开头的路径都是相对路径,如`data`表示当前目录下的data目录,等同于`./data` (`.`为当前目录), `../data`表示当前目录的上一层目录下的data目录 (`../`表示上层目录)。
`pwd` (print working directory) 获取当前工作目录。
`cd` (change dir)切换目录。若`cd`后没有指定切换到那个目录,则调回家目录。特别地,`cd -`表示返回到最近的`cd`操作前所在目录,相当于回撤到上一个工作目录。
`head`查看文件最开始的几行,默认为10行,可使用`-n 6`指定查看前6行。
```{bash eval=F}
# 记住输出
ct@ehbio:~$ pwd
/home/ct
ct@ehbio:~$ cd data
# 注意输出变化
ct@ehbio:~$ pwd
/home/ct/data
ct@ehbio:~/data$ head -n 6 test.fa
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
```
另外`less`和`more`也可以用来查看文件,尤其是文件内容特别多的时候。
```{bash eval=F}
ct@ehbio:~/data$ less test.fa
# q: 退出
# 上下箭头、空格翻页
```
### 查看帮助,获取可用命令行参数 {#com_parameter_help}
前面使用的命令,有几个用到了参数如`ls -l`, `head -n 6`等,需要注意的是命令跟参数之间要有**空格**。
终端运行`man ls`可以查看`ls`所有可用的参数,上下箭头翻页,按`q`退出查看。(man: manual, 手册)
```{bash eval=F}
ct@ehbio:~/data$ man ls
NAME
ls - list directory contents
SYNOPSIS
ls [OPTION]... [FILE]...
DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor --sort is specified.
Mandatory arguments to long options are mandatory for short options too.
-a, --all
do not ignore entries starting with .
-A, --almost-all
do not list implied . and ..
--author
with -l, print the author of each file
-b, --escape
print C-style escapes for nongraphic characters
....
```
### 小结 {#first_summary}
1. Linux是多用户操作系统。这一点可以从我们每个人能同时登录到同一台Linux电脑各自进行操作而不相互干扰可以体会出来。大家可以尝试下是否可以看到其它人家目录下的东西。我们后期在**权限管理**部分会涉及如何开放或限制自己的文件被他人访问。
2. Linux下所有目录都在**根目录**下。根目录某种程度上可类比于Windows的我的电脑,第一级子目录类比于`C盘`,`D盘`等 (等我们熟练了,就忘记这个拙劣的类比吧)。
3. 使用`mkdir`新建目录,`cd`切换目录,`pwd`获取当前工作目录,`ls`查看目录下的内容, `cat`查看文件,`man ls`查看ls命令的使用。
4. 访问一个文件需要指定这个文件的路径,当前目录下的文件可省略其路径`./`,其它目录下则需要指定全路径 (可以是相对路径,也可以是绝对路径)。
### 做个小测试 {#first_exercise}
1. 在家目录下新建文件夹`bin`和`soft`。
2. 在`bin`和`soft`目录下各自新建一个文件,名字都是`README`。
3. 在`bin/README`文件中写入内容:This folder is used to save executable files。
4. 在`soft/README`文件中写入内容:This folder is used to save software source files。
5. 查看两个`README`文件的大小。
## Linux下文件操作 {#fileoperation}
### 文件按行翻转和按列翻转 {#tac_rev}
两个有意思的命令,`tac`: 文件翻转,第一行变为最后一行,第二行变为倒数第二行;`rev`每列反转,第一个字符变为最后一个字符,第二个字符变为倒数第二个字符。
```{bash eval=F}
ct@ehbio:~/data$ cat <<END | tac
> first
> second
> third
> END
third
second
first
ct@ehbio:~/data$ cat <<END | rev
> abcde
> xyz
> END
edcba
zyx
```
### 新建文件的n种方式 {#new_file}
`nano`类似于Windows下记事本的功能,`nano filename`就可以新建一个文件,并在里面写内容;`ctrl+x`退出,根据提示按`Y`保存。
`vim` 功能更强大的文本编辑器。`vim filename`就可以新建一个文件, 敲击键盘字母`i`,进入写作模式。写完后,敲击键盘`Esc`, 退出写作模式,然后输入`:w` (会显示在屏幕左下角),回车保存。`vim`的常用方法,后面会有单独介绍。
### 文件拷贝、移动、重命名、软链 {#file_cp_mv_rename_link}
常用的文件操作有移动文件到另一个文件夹、复制文件到另一个文件夹、文件重命名等。
`cp` (copy): 拷贝文件或文件夹 (`cp -r` 拷贝文件夹时的参数,递归拷贝).
`cp source1 source2 ... target_dir` 将一个或多个源文件或者目录复制到已经存在的目标目录。
`cp`常用参数
> -r: 递归拷贝
> -f: 强制覆盖
> -i: 覆盖前先询问
> -p: 保留文件或目录的属性,主要是时间戳
> -b: 备份复制,若目标文件存在,先备份之前的,再把新的覆盖过去
> -u: 更新复制,若源文件和目标文件都存在,只在源文件的修改时间比较新时才复制
```{bash eval=F}
# 列出当前目录下有的文件和文件夹
ct@ehbio:~$ ls
data
# 新建一个文件夹
ct@ehbio:~$ mkdir ehbio_project
# 列出当前目录下有的文件和文件夹, 及其子文件夹的内容
# data目录下有一个文件,ehbio_project目录下无文件
ct@ehbio:~$ ls *
data:
test.fa
ehbio_project:
# 拷贝data目录下的文件test.fa到ehbio_project目录下
ct@ehbio:~$ cp data/test.fa ehbio_project/
# 列出当前目录下有的文件和文件夹, 及其子文件夹的内容
# data目录下有一个文件,ehbio_project目录下无文件
ct@ehbio:~$ ls *
data:
test.fa
ehbio_project:
test.fa
```
`mv` (move): 移动文件或文件夹
`mv source target`, 常用参数有
> -f: 强制覆盖
> -i: 覆盖前询问
> -u: 更新移动
```{bash eval=F}
# 重命名data目录下的文件test.fa为first.fa
# mv除了可以移动文件,也可以做单个文件的重命名
ct@ehbio:~$ mv data/test.fa data/first.fa
# 列出当前目录下有的文件和文件夹, 及其子文件夹的内容
ct@ehbio:~$ ls *
data:
first.fa
ehbio_project:
test.fa
```
`rename`: 文件重命名 (常用于批量重命名,不同的系统可能用法略有不同,使用前先`man rename`查看使用方法)
```{bash eval=F}
# 进入另一个目录
ct@ehbio:~$ cd ehbio_project/
ct@ehbio:~/ehbio_project$ ls
test.fa
# 给文件做一份拷贝
ct@ehbio:~/ehbio_project$ cp test.fa second.fa
ct@ehbio:~/ehbio_project$ ls
second.fa test.fa
# 给文件多拷贝几次,无聊的操作,就是为了给rename提供发挥作用的机会
ct@ehbio:~/ehbio_project$ cp test.fa test2.fa
ct@ehbio:~/ehbio_project$ cp test.fa test3.fa
ct@ehbio:~/ehbio_project$ cp test.fa test4.fa
# cp 后面需要2个参数,被拷贝的文件和要被拷贝到的目录或文件
# 出现下面的错误,表示缺少目标路径或文件
ct@ehbio:~/ehbio_project$ cp ehbio.fa
cp: 在" ehbio.fa" 后缺少了要操作的目标文件
Try 'cp --help' for more information.
ct@ehbio:~/ehbio_project$ ls
second.fa test2.fa test3.fa test4.fa test.fa
# 用rename进行文件批量重命名
ct@ehbio:~/ehbio_project$ rename 'test' 'ehbio' test*.fa
ct@ehbio:~/ehbio_project$ ls
ehbio2.fa ehbio3.fa ehbio4.fa ehbio.fa second.fa
```
`ln` (link): 给文件建立快捷方式 (`ln -s source_file target` 创建软连接)。
在建立软连接时,原文件要使用全路径。全路径指以`/`开头的路径。如果希望软链可以让不同的用户访问,不要使用`~`。
建立软连接,是为了在不增加硬盘存储的情况下,简化文件访问方式的一个办法。把其它文件夹下的文件链接到当前目录,使用时只需要写文件的名字就可以了,不需要再写长串的目录了。
`ln`命令常用参数
> -s: 软连接
> -f: 强制创建
`../`: 表示上一层目录;`../../`: 表示上面两层目录
`pwd` (print current/working directory): 输出当前所在的目录
`\``为键盘`Esc`下第一个按键 (与家目录`~`符号同一个键),写在反引号内的命令会被运行,运行结果会放置在反引号所在的位置
```{bash eval=F}
# 建立软连接,把当前目录下的ehbio2.fa,链接到上一层目录的data下面
# 这是一个无效的软连接,
ct@ehbio:~/ehbio_project$ ln -s ehbio2.fa ../data
# 在使用ls查看时,无效的软连接的文件名下面是黑色的背景。
# 不同的终端配色方案会有不同,一般一直闪烁表示是失效的链接,
# 另外是否失效以能否使用为最终判断标准。
ct@ehbio:~/ehbio_project$ ls -l ../data/
总用量 4
lrwxrwxrwx 1 ct ct 9 6月 9 17:55 ehbio2.fa -> ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月 8 14:48 first.fa
ct@ehbio:~/ehbio_project$ less ../data/ehbio2.fa
xxxxx 符号连接的层数过多
# 输出当前所在的目录
ct@ehbio:~/ehbio_project$ pwd
/home/ct/ehbio_project
# 建立软连接时,原始文件一定使用全路径。全路径指以/开头的路径。
ct@ehbio:~/ehbio_project$ ln -s /home/ct/ehbio_project/ehbio2.fa ../data
ln: 无法创建符号链接" ../data/ehbio2.fa" : 文件已存在
# 上面的错误信息时,已经存在这么一个链接了(虽然是无效的),但再建新的链接时还会提示
# 使用`-f` (force)强制覆盖已有的链接
ct@ehbio:~/ehbio_project$ ln -fs /home/ct/ehbio_project/ehbio2.fa ../data
# 再次查看时,就正常了。文件名下面没有了恐怖的背景色,并且有个右箭头指向原始文件
# `lrwxrwxrwx`中的`l`表示软连接。
ct@ehbio:~/ehbio_project$ ls -l ../data/
总用量 4
lrwxrwxrwx 1 ct ct 32 6月 9 17:56 ehbio2.fa -> /home/ct/ehbio_project/ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月 8 14:48 first.fa
# 通常为了简化写法,使用`pwd`代替全路径
# `为键盘Esc下面的按键,写在反引号内的命令会被运行,运行结果会放置在反引号所在的位置
ct@ehbio:~/ehbio_project$ ln -s `pwd`/ehbio2.fa ../data
ln: 无法创建符号链接" ../data/ehbio2.fa" : 文件已存在
ct@ehbio:~/ehbio_project$ ln -fs `pwd`/ehbio2.fa ../data
ct@ehbio:~/ehbio_project$ ls -l ../data/
总用量 4
lrwxrwxrwx 1 ct ct 32 6月 9 17:56 ehbio2.fa -> /home/ct/ehbio_project/ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月 8 14:48 first.fa
```
使用全路径名,尤其使用家目录 `~` 符号时,只限操作用户自身有效。另外不同用户之间建立软连接,需要考虑**访问权限**问题,任意一层目录都需要可读权限 (目录的可读为`rx`都有)。
复制、移动或创建软连接时,如果目标已存在,除了使用`-f`强制覆盖外,还可以使用`rm`命令删除。
`rm`可以删除一个或多个文件和目录,也可以递归删除所有子目录,使用时一定要慎重。`rm`命令删除的文件很难恢复。
`rm -rf *`: 可以删除当前目录下所有文件和文件夹,慎用。
`rm`命令常见参数:
> -f:强制删除
> -i: 删除前询问是否删除
> -r: 递归删除
```{bash eval=F}
ct@ehbio:~/ehbio_project$ ln -s `pwd`/ehbio2.fa ../data
ln: 无法创建符号链接" ../data/ehbio2.fa" : 文件已存在
# 删除之前的软连接,源文件不会被删除
ct@ehbio:~/ehbio_project$ rm -f ../data/ehbio2.fa
# 再次新建软连接
ct@ehbio:~/ehbio_project$ ln -s `pwd`/ehbio2.fa ../data
ct@ehbio:~/ehbio_project$ ls -l ../data/
总用量 4
lrwxrwxrwx 1 ct ct 32 6月 9 17:56 ehbio2.fa -> /home/ct/ehbio_project/ehbio2.fa
-rw-rw-r-- 1 ct ct 284 6月 8 14:48 first.fa
#
ct@ehbio:~/ehbio_project$ mkdir tmp
# touch filename: 如果文件不存在,则新建一个文件
# 若存在,则更新其修改和访问时间
# 在后面的搜索讲解中会有touch的一个妙用
ct@ehbio:~/ehbio_project$ touch tmp/a
ct@ehbio:~/ehbio_project$ touch tmp/b
# -r: 递归删除,主要用于删除目录和子目录时
# -f: 强制删除
ct@ehbio:~/ehbio_project$ rm -rf tmp
```
### Linux下命令的一些突发事故 {#linux_abnormal}
**命令不全**:在命令没有输入完 (引号或括号没有配对),就不小心按下了`Enter`键,终端会提示出一个`>`代表命令不完整,这是可以继续输入,也可以`ctrl+c`终止输入,重新再来。(下面sed命令使用时,还有另外一种命令不全的问题)
```{bash eval=F}
ct@ehbio:~/ehbio_project$ rename 'ehbio2
>'
ct@ehbio:~/ehbio_project$ rename 'ehbio2
> ^C
ct@ehbio:~/ehbio_project$
```
**文件名输入错误**: 多一个字母、少一个字母、大小写问题
```{bash eval=F}
ct@ehbio:~/ehbio_project$ls
ehbio2.fa ehbio3.fa ehbio4.fa ehbio.fa second.fa
# 重命名没有生效
ct@ehbio:~/ehbio_project$ rename 'ehbio2' 'ehbio5' ebio2.fa
ct@ehbio:~/ehbio_project$ ls
ehbio2.fa ehbio3.fa ehbio4.fa ehbio.fa second.fa
# 仔细看是ehbio2.fa写成了ebio2.fa,更正后即可。
Z8vb3e9jtel4m99ss6e7eZ:~/ehbio_project$ rename 'ehbio2' 'ehbio5' ehbio2.fa
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio.fa second.fa
```
**所在目录不对**: 访问的文件不存在于当前目录,而又没有提供绝对路径, 或软连接失效
```{bash eval=F}
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio6.fa ehbio.fa second.fa
ct@ehbio:~/ehbio_project$ ls ../data
ehbio2.fa first.fa
# 当前目录没有ehbio2.fa
ct@ehbio:~/ehbio_project$ less ehbio2.fa
ehbio2.fa: 没有那个文件或目录
# ehbio2.fa在上一层目录的data目录下
ct@ehbio:~/ehbio_project$ ls ../data/ehbio2.fa
../data/ehbio2.fa
# 加上路径依然访问不了
ct@ehbio:~/ehbio_project$ less ../data/ehbio2.fa
../data/ehbio2.fa: 没有那个文件或目录
# 上面的问题是软连接失效,在之前的操作中删掉了原始的ehbio2.fa,所以快捷方式失效
# 正确的访问
ct@ehbio:~/ehbio_project$ tail -n 3 ../data/first.fa
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
### 了解和操作你的文件 {#file_op_gzip_wc}
常用的文件内容操作有文件压缩解压缩、文件大小行数统计、文件内容查询等。
`gzip`: 压缩文件; `gunzip`: 解压缩文件
```{bash eval=F}
# gzip -c 把压缩的文件输出到标准输出 (一般是屏幕)
# '>' 输出重定向,输出写入文件
ct@ehbio:~/ehbio_project$ gzip -c ehbio.fa >ehbio.fa.gz
# 多了一个.gz文件
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio.fa ehbio.fa.gz second.fa
# 解压缩
ct@ehbio:~/ehbio_project$ gunzip ehbio.fa.gz
gzip: ehbio.fa already exists; do you wish to overwrite (y or n)? y
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio.fa second.fa
```
`wc` (word count): 一般使用`wc -l`获取文件的行数。
```{bash eval=F}
# 输出文件有14行
ct@ehbio:~/ehbio_project$ wc -l ehbio.fa
14 ehbio.fa
```
获取文件中包含大于号 (`>`)的行, `grep` (print lines matching a pattern,对每一行进行模式匹配)。
`grep`的用法很多,支持正则表达式匹配,这个后面我们会详细讲解。
```{bash eval=F}
ct@ehbio:~/ehbio_project$ grep '>' ehbio.fa
>SOX2
>OCT4
>NANOG
>mYC HAHA
# 获取包含>的行的行数 (-c: count lines)
ct@ehbio:~/ehbio_project$ grep -c '>' ehbio.fa
4
# 是不是还记得当时新建文件时,末尾多了一行end,删除end所在行
ct@ehbio:~/ehbio_project$ less ehbio.fa
# -v: 不输出匹配上的行
ct@ehbio:~/ehbio_project$ grep -v 'end' ehbio.fa >ehbio6.fa
ct@ehbio:~/ehbio_project$ cat ehbio6.fa
>SOX2
ACGTCGGCGGAGGGTGGSCGGGGGGGGAGAGGT
ACGATGAGGAGTAGGAGAGAGGAGG
>OCT4
ACGTAGGATGGAGGAGAGGGAGGGGGGAGGAGAGGAA
AGAGTAGAGAGA
>NANOG
ACGATGCGATGCAGCGTTTTTTTTTGGTTGGATCT
CAGGTAGGAGCGAGGAGGCAGCGGCGGATGCAGGCA
ACGGTAGCGAGTC
>mYC HAHA
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
```
替换文件中的字符: `sed`是一个功能强大的文件内容编辑工具,常用于替换、取得行号等操作。现在先有个认识,后面会详细介绍。
`|` 为管道符,在相邻命令之间传递数据流,表示把上一个命令的输出作为下一个命令的输入。
```{bash eval=F}
# 第一个错误,漏掉了文件名
# 程序静止在这,等待用户的进一步输入
# ctrl+c杀掉当前命令
ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' | tail -n 3
^C
# 第二个错误,文件名和单引号之间没有空格,使得sed判断命令错误
ct@ehbio:~/ehbio_project$ sed 's/ HAHA//'ehbio.fa | tail -n 3
sed:-e 表达式 #1,字符 11:“s”的未知选项
# 正确操作,
ct@ehbio:~/ehbio_project$ sed 's/ HAHA//' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
另外一个方式,去除`HAHA`,使用`cut`命令。cut更适合于矩阵操作,去除其中的一列或者多列。但在处理FASTA格式文件时有这么一个妙用。FASTA文件中序列里面是没有任何符号的,而如果名字比较长,则可以指定相应分隔符就行`cut`,这样既处理了名字,又保留了序列。
`-f`: 指定取出哪一列,使用方法为`-f 2` (取出第2列),`-f 2-5` (取出第2-5列),`-f 2,5` (取出第2和第5列)。**注意不同符号之间的区别。**
`-d`: 设定分隔符, 默认为TAB键。如果某一行没有指定的分隔符,整行都为第一列。
```{bash eval=F}
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
### 小结和练习 {#second_exercise}
1. Linux下文件拷贝、移动、重命名、软连接、压缩、替换等操作。
2. Linux下常见问题
* `ehbio2.fa: 没有那个文件或目录`:这个错误通常由什么引起,应该怎么解决?
* 若文件`a`存在,运行`ln a data/b`能否成功给`a`建立软连接?
* `grep '> ehbio.fa`的输出是什么?
3. 若目标文件存在时,再运行`cp`, `mv`或`ln`会有什么提示?
4. 计算某一个Fasta序列中序列的个数。
## Linux终端常用快捷操作 {#shortcut}
* 命令或文件名自动补全:在输入命令或文件名的前几个字母后,按`Tab`键,系统会自动补全或提示补全
* 上下箭头:使用上下箭头可以回溯之前的命令,增加命令的重用,减少输入工作量
* `!`加之前输入过的命令的前几个字母,快速获取前面的命令
```{bash eval=F}
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
ct@ehbio:~/ehbio_project$ man cut
# 直接跳到上面运行的cut命令,再执行一次
ct@ehbio:~/ehbio_project$ !cut
cut -f 1 -d ' ' ehbio.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
* `ctrl+a`回到命令的行首,`ctrl+e`到命令行尾,(`home`和`end`也有类似功能),用于修改命令或注释掉命令
```{bash eval=F}
# 写完下面的命令,突然不想运行了,又不想一个个删掉
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio.fa | tail -n 4
# 按ctrl+a, 回到行首,再输入`#`号,回车,命令即被注释掉。
ct@ehbio:~/ehbio_project$ #cut -f 1 -d ' ' ehbio.fa | tail -n 4
```
* `!!` 表示上一条命令。
```{bash eval=F}
ct@ehbio:~/ehbio_project$ ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio6.fa ehbio.fa second.fa
ct@ehbio:~/ehbio_project$ !!
ls
ehbio3.fa ehbio4.fa ehbio5.fa ehbio6.fa ehbio.fa second.fa
```
* 替换上一个命令中的字符,再运行一遍命令,用于需要对多个文件执行同样的命令,又不想写循环的情况
```{bash eval=F}
# 输入一个命令
ct@ehbio:~/ehbio_project$ #cut -f 1 -d ' ' ehbio.fa | tail -n 4
# !!表示上一条命令
# :gs表示替换,把上一个命令中全部的ehbio替换为ehbio3; g: global; s: substitute
ct@ehbio:~/ehbio_project$ !!:gs/ehbio/ehbio3
#cut -f 1 -d ' ' ehbio3.fa | tail -n 4
# 替换后效果如上
# 去掉命令前的#号
ct@ehbio:~/ehbio_project$ cut -f 1 -d ' ' ehbio3.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
## 替换ehbio3为ehbio4,直接运行命令
ct@ehbio:~/ehbio_project$ !!:gs/ehbio3/ehbio4
cut -f 1 -d ' ' ehbio4.fa | tail -n 4
>mYC
ACGGAGCGAGCTAGTGCAGCGAGGAGCTGAGTCGAGC
CAGGACAGGAGCTA
end
```
## Linux下的标准输入、输出、重定向、管道 {#stdinoutpipe}
在Linux系统中,有4个特殊的符号,`<`, `>`, `|`, `-`,在我们处理输入和输出时存在重要但具有迷惑性的作用。
默认Linux的命令的结果都是输出到标准输出,错误信息 (比如命令未找到或文件格式识别错误等) 输出到标准错误,而标准输出和标准错误默认都会显示到屏幕上。
`>`表示重定向标准输出,`> filename`就是把标准输出存储到文件filename里面。标准错误还是会显示在屏幕上。
`2 >&1` 表示把标准错误重定向到标准输出。Linux终端用`2`表示标准错误,`1`表示标准输出。
`-` (短横线):表示标准输入,一般用于1个程序需要多个输入的时候。
`<` 标准输入,后面可以跟可以产生输出的命令,一般用于1个程序需要多个输入的时候。相比`-`适用范围更广。
`|`管道符,表示把前一个命令的输出作为后一个命令的输入,前面也有一些展示例子。用于数据在不同的命令之间传输,用途是减少硬盘存取损耗。
下面我们通过一个程序`stdout_error.sh`来解释上面的文字 (Bash脚本写作,后面会有专门介绍),内容如下
```{bash eval=F}
#!/bin/bash
echo "I am std output"
# 下面是随便写的一个理论上不存在的命令, 理论上会报错的。
unexisted_command
```
运行这个脚本
```{bash eval=F}
# 标准输出和标准错误默认都会显示到屏幕上
ct@ehbio:~$ bash stdout_error.sh
I am std output
stdout_error.sh: line 5: unexisted_command: command not found
# 上一行的line 5 表示是第5行命令出错了,通常用来调试程序。
# 在这个例子中,bash脚本第5行是故意输入的一个错误命令,用来展示什么是标准错误
# >把结果输入到了文件;标准错误还显示在屏幕上
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout
stdout_error.sh: line 5: unexisted_command: command not found
ct@ehbio:~$ cat stdout_error.stdout
I am std output
# >把结果输入到了文件; 2>把标准错误输入到了另一个文件
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout 2>stdout_error.stderr
ct@ehbio:~$ cat stdout_error.stderr
stdout_error.sh: line 5: unexisted_command: command not found
# 标准输出和标准错误写入同一个文件
ct@ehbio:~$ bash stdout_error.sh >stdout_error.stdout 2>&1
ct@ehbio:~$ cat stdout_error.stdout
I am std output
stdout_error.sh: line 5: unexisted_command: command not found
```
下面看管道符和标准输入的使用。
```{bash eval=F}
# 管道符的使用
# 第一个命令的输出作为第二个的输入
# 前面的例子中也有使用
# tr: 是用于替换字符的,把空格替换为换行,文字就从一行变为了一列
ct@ehbio:~$ echo "1 2 3" | tr ' ' '\n'
1
2
3
# cat命令之前也用过,输出一段文字
# diff是比较2个文件的差异的,需要2个参数
# - (短横线)表示上一个命令的输出,传递给diff
# < 表示其后的命令的输出,也重定向给diff