#lctp2021.051301#
李丛宇1 柴新宇1 刘昊1 张景旭1谢世卿2 祁康辉3 王雄飞1
(1 兰州大学物理科学与技术学院 甘肃 兰州 730000
2 兰州大学萃英学院 甘肃 兰州 730000
3 中国科学院近代物理研究所 甘肃 兰州 730000)
前言:
想要参与高能物理实验就必须会用 linux,而使用 linux 的过程中难免要用到 vim (vi)。而 shell 语言虽然不算是必须,但掌握一些知识,能写简单脚本,对于提高工作效率 是很有帮助的。笔者认为学习一种操作系统或者一种编程语言,最好是带有一定的目的性去学,为实 现某种需求去学习某种命令,学完后立马实践看看是否能满足自己的需求,不能满足则 要学习更高深的知识。我并不是反对通读教材,系统性的学习,但是在时间匮乏的情况 下,“干中学”不失为一种好方法。笔者至今也没有系统性的学习过有关知识,所以说下文我所写的内容只是我懂得的知 识,各种命令一定没有写全,即使是对于我提到的命令,它可以带的各种参数我也没有全 部掌握。如果以下内容仍然没有覆盖到读者的需求,请您上网搜索,多浏览几篇文章,应 该就可以掌握。本文将会不断更新,也欢迎各位读者批评指正。
第一章 linux
linux 和 Windows、Mac OS 一样,都是电脑操作系统。因笔者未曾使用过苹果系统,下文涉及到系统操作的比较时,均以微软系统为例。
首先我们要通过软件来连接远端的服务器,这类软件有很多,笔者感觉比较独特的有 PuTTY 和 MobaXterm。
PuTTY 最大的优点是小巧,功能基本上也够用。缺点就是没有多窗口,这个大概可 以通过 Windows10 的多桌面来弥补一下,但超过 3 个窗口恐怕就很难受了。另外 PuTTY 不能看图,这样 root 一半的功能就无法发挥了。MobaXterm 弥补了 PuTTY 的两个缺 点,而且还能记住密码,比较方便。另外 MobaXterm 的左侧可以图形化显示 linux 下的 文件,就类似于 Windows 文件资源管理器的左侧,而且可以随意把服务器上的文件下载 (download)到本地。
软件下载下来直接使用不一定舒适,可以先调节一下字体颜色,字号大小。另外,大 多数软件在长时间不操作后会与服务器断开,解决方法就是在设置 settings-SSH 中找到SSH keepalive 并勾选(图 1.1),或者在 connection 的第一行中把 0 改为非 0 数(意思是 每间隔多少秒向服务器发送一个空包以保持连接)(图 1.2)。另外,至少以上两款软件是没 有官方中文版的,其他汉化版不能保证其安全性,因此还是到官方下载为好。

图 1.1: MobaXterm

图1.2: PuTTY
linux 和 Windows 两种系统最直观的区别就是:Windows 有图形化界面,上手容易, 给小孩子一个下午或许就能自己探索出如何使用,而 linux 一般是非图形化的,让小孩子 自己探索恐怕就很难了,甚至可能还没探索出 ls 呢,先执行了 rm -r * 甚至 rm -rf /*。
非图形化界面系统的一切操作都是通过在屏幕上显示的那一行里输入命令(command) 来实现的,我们可以称之为命令行,鼠标基本上失去了作用,但用来复制粘贴还是很方便 的。linux 中(包括 vim 里),选中文字即复制,粘贴只需要右键单击即可。
下面详细介绍一下常用命令。
1.1 cd
即 change directory。Windows 下可以通过点击返回来回到上一层目录,点击对应文 件夹进入下一层目录,这在 linux 中都是通过 cd 命令来实现的,cd .. 返回上一层目录,cdxx 进入名为 xx 的文件夹。在 linux 中,一个. 就是指当前所在目录,两个.. 指上一层目录。
cd 命令后面可以加绝对路径和相对路径。
绝对路径往往比较长,所以平时我们可能不太愿意使用它,不过也正是因为它长,所 以定位准确。我们执行 pwd(print working directory) 命令,就能看到我们当前目录的绝对 路径。相对路径是以一个点. 和两个点.. 为基础的,而我们平时很少见到一个点,那是因为 它被简化了。我们要进入当前目录下的名为 xx 的文件夹,按照相对路径写法,应该是 cd ./xx/,实际使用中,前面的./和最后的斜杠/都可以省略,于是就变成了我们喜闻乐见的 cd xx。
linux 下 tab 键可以自动补全,所以说在 Linux 下文件名可以命的长一点,反正打几 个字母 tab 一下就能补全。如果你输入的文字对应到不止一个文件,Linux 会显示出来, 如vi ru tab 会补全出vi run,上面会显示run_conder.sh run.head run.foot(图 1.3), 所以说有时用 tab 就可以实现下文的 ls 的功能。

图 1.3:tab 自动补全
1.2 ls
即 list。你可能会问:Windows 每进一个目录都能看到下面的东西,通过右键 -属性还 能看到关于文件的更多信息,linux 怎么什么都看不到?因为这也需要执行命令。
执行 ls,我们就能看到当前目录下的文件和文件夹(以蓝色显示)(不含隐藏文件), 这个命令对于文件较少的目录还是能很快显示的,文件多了就会有明显的等待时间,而且 这个命令也会对服务器造成冲击,而用/bin/ls 就只是显示文件名,执行速度就快多了。我 们可以把这个命令设为快捷指令 l(后面会讲)。ls -a 可以显示出以. 开头的隐藏文件,ls -l 或 ll 可以显示文件的详细信息。
linux 下有一种模糊功能,* 可以表示任何名称,所以我们执行 ls *.txt 就可以列出当 前目录下所有以.txt 结尾的文件。顺便说一下,linux 下的文件名后缀可能只是个后缀了, 与文件属性没什么关系,但使用合理的后缀可以让我们的文件更加整齐。
cmd 命令行中,按上下键可以查看命令的历史记录,左右键自然就是左右移动光标了。
1.3 mkdir
即 make directory。linux 下创建文件夹用 mkdir 加名称,如果要创建多个文件夹,不 是用 & 连接,而是直接空格,其他命令对多个文件操作也是如此。而创建多层目录需要加 上参数 -p,如 mkdir -p test1/test2/test3/test4。
1.4 rm(dir)
删除文件夹用 rmdir,不过这个命令只能删除空文件夹,不太常用,一般都用 rm -r 加 文件夹名,rm 可以删除文件,-r 表示对文件夹进行操作(下面均以文件演示,文件夹只需 要补加 -r),-i 开启互动模式,在删除前会询问使用者,避免误删。
1.5 cp
复制文件用cp+来源+去向,都可以使用绝对路径或者相对路径。复制到当前目录下则 必须改名,如cp test1 test2,复制到其他地方则可改可不改,最后不写新的文件名就以 原文件名复制过去。
1.6 mv
移动文件或者改名,和 cp 基本差不多,在当前目录下 mv 是改名,如mv test1 test2 将 test1 改名为 test2,mv+文件+文件夹是把文件移动到文件夹,也可以再加上/xx 顺便改名为 xx。
1.7 diff
比较两个文件,如有区别,会分别输出两个文件中的对应内容,方便比较(图 1.4)。

图 1.4:diff
1.8 快捷键
设置指令的别名。在家目录 home 下一个神奇的隐藏文件.tcshrc 中输入alias+别名+ 指令名称,如
alias l "/bin/ls"。
如果已经把 ls 设置为/bin/ls 的快捷指令,又想使用真正的 ls,则要加转义符\,即\ls, 不过一般还是不要让快捷指令覆盖到真实指令为好。
1.9 文件内容查看
cat 正着看,tac 倒着看(由最后一行输出到第一行);nl 带着行号看(可以替代 cat);head 只看头几行,tail 只看尾几行,均默认显示 10 行,看所有以 log 结尾的文件的后 3 行 即tail -n3 *log。
1.10 grep
grep+‘字符串’+ 文件目录,引号可单可双,对于短字符串不加引号也行。不加任何 参数则输出文件名和对应字符串。
grep "xxx" * | wc -l 用来查找含有 xxx 字符的文件数,而wc -l 本身也是用来统 计行数的命令。例如
grep 'ApplicationMgr INFO Application Manager Finalized successfully' *log | wc -l
的作用是输出 log 文件中含有这一行成功信息的文件数,如果输出结果和 log 文件数一致 则说明所有作业都成功运行,建议将这条命令整合到快捷指令中。
1.11 sed
sed -i 's/xxx/yyy/g' 用于替换,其中参数 -i 表示直接修改原文件内容,不加则把 修改后的内容显示在屏幕上 (输出到终端),原文件内容不变,对我们常见的批量替换需求 来说用处不大。引号可单可双,s、g、/可以简单的看作形式,而且这一形式和后面 vim 里 的替换很像。
/是一种定界符,两个/之间的东西才是要查找和替换的内容,如果内容中也含有/(一 般是程序语言的注释//或者路径),则可以用转义符 -反斜线\ 告诉计算机这是真正 的斜线/而不是定界符/,也可以用井号 # 做定界符。有的时候内容中同时含有/和 #,那就必须使用转义符了,不过可以通过合理选择定界符来减少转义符的使用。例 如sed -i 's/1000/1/g' test*.txt 就是将test_00.txt、test_01.txt 中的 1000 替换 为 1m,以减少运行时间。sed ’1d’ xx 即删除 xx 中的第一行,’2,5d’ 表示删除第二到五 行,特别的,$ 表示最后一行。
1.12 查找 + 替换
例如sed -i "s/#path/path/g" `grep "#path" * -rl`,先查找含有 #path 的文件, 得到文件名,再对这些文件进行替换操作(也就是去掉注释 #)。注意要用反引号‘将 grep 语句括起来。另外这种查找和替换是同一个字符串这种写法应该说仅仅是个人习惯,它和 直接 grep 语句换成 * 没有本质区别。想要有区别的话,可以增长 grep 搜索的字符串,提 高搜索精度。
另一种解决方案是分步进行,先搜索你想要替换的字符串,观察是否可以全部替换, 如果可以,替换的操作对象可以打 *,否则就要明确对象,多个对象之间用空格隔开即可。、
1.13 hadd
用来将多个 root 文件合成为一个,格式为
hadd output.root input.root,例如
hadd data.root *.root, 既然是把当前目录下所有 root 合并,那就可以直接写成 *.root 或者 *root。另外这条命令不同于大多数命令,是先写 output,再写 input 的。
1.14 root
root 博大精深,可以再写一篇文章,这里只提一下基本操作。在任何一个目录下 输入 root(加不加具体.root 都行)回车,蹦出几行字,然后会出现新的命令行,再输 入TBrowser g(参数可随意替换),就能打开一个新窗口(浏览器),就能看到 root,下面 有树,再往下还有枝,退出就是输入.q(ctrl+z 也可以) 。
上面说的其实是 root+xx.root 的情况,其实 root 还可以加 c 或 cpp 程序,如果需要 看图,就用root -l x.c,如果不需要看图,就用root -l -q y.cxx。-l 在笔者看来最显 著的作用就是提高运行速度,不过即使不加这个参数,也是可以正常运行的。-q 就是让程 序运行完后自动退出,而不用人工输入.q 了。
1.15 上传和下载
常用 scp 指令。在你所用的软件中打开一个本地窗口,不做连接,执行”scp+ 远端地址 + 本地(./)”,
例如 scp licy19@lxslc7.ihep.ac.cn:/scratchfs/bes/ licy19/LamLambar/Data/Psipscan/ Data/*jpg /home/mobaxterm/Desktop。
1.16 输出重定向
command > file 将输出重定向到 fifile,>> file 则将输出以追加的方式重定向到 fifile。
问题的关键在于是否追加,这里的区别在后面写 shell 脚本时会有更明显的体现,如果 全程只向 fifile 中写入一次,那么> 和>>没有区别,如果目的是通过循环向 fifile 里写入,并且 想保留每次写入的信息,那就必须使用>>,这样每次循环中写入都是以追加而的方式来进 行的,之前的信息都不会丢失。而> 这种方式就有一种覆盖的意味,即使循环写入了 9 次, 保留的也只是最后一次写入的信息。
1.17 后台运行
command &:后台运行,这时理论上后台运行的任务对当前 cmd 窗口的操作不造成 影响,但如果这个 command 是带有输出的,那么前台还是会有输出(这一点对于下面的nohup 也是一样的)。& 对 ctrl+z(暂停)和 ctrl+c(终止)免疫,想要终止可以直接退出 终端,command 就被停止,而如果用 exit 退出,该 command 不会被挂断,这一点能做到 和 nohup 相同。如果想要停止,应该要先输入 fg 将任务调到前台再暂停或停止。
注:ctrl+z 和 ctrl+c 当然是有区别的,不过在平时只用 ctrl+z 也没什么大问题,毕竟 一般暂停之后也不会再让任务继续跑。
nohup command:表示不挂起(no hang up),也即,关闭终端或者退出某个账号,进 程也继续保持运行状态,因为 nohup command 后该指令将被上传到远端的服务器,这时 候无论你是 exit、退出终端、关机甚至突然断电、断网,该命令都是不会被挂断的,这对 于那些执行时间较长的命令来说尤为重要,所以说 nohup 的抗冲击性比 & 还要好,唯一不 如 & 的地方就是当前 cmd 窗口不能再干其他事情,所以可以考虑把 nohup sh 设为快捷指令。
另外,如果将nohup sh yy.sh \& 写入一个 xx.sh 脚本,在执行 xx.sh 后,yy.sh 的输出 将被定向到 nohup.out 里,不会在屏幕上输出,屏幕上只会显示nohup: ignoring input and appending output to 'nohup.out', 加之 & 的后台运行功能,此时 cmd 窗口能正常使用,前台也不会不断输出提交作业的信 息,上面那一句话出现的次数和 xx.sh 脚本中提交 yy.sh 的数量是一致的,出现频率也不 会太高。
如果上文所说的脚本提交后发现有问题,该如何终止呢?答案是悲观的,可能根本停 不下来。靠物理方法(如断网、退出终端等)不再适用,直接暂停或终止也不管用,fg jobs 也调不出任务,这应该说是把 nohup command & 写在脚本里的坏处。连任务都找不到, 更不用谈停止任务了。
总之,综合评判,至少在外部提交脚本时最好用 nohup sh,至于脚本内用不用 nohup 和 & 看个人习惯,如果都写上的话中途可能停止不了,写 & 可以干其他事情,但体验不 好,因为屏幕上还在不断输出;写 nohup 能让屏幕输出变得简洁一些。
注:在高能所环境下,hep_sub job.sh 也可以将程序提交到后台,作用和 nohup 相 似。