科学网

 找回密码
  注册

tag 标签: bash

相关帖子

版块 作者 回复/查看 最后发表

没有相关内容

相关日志

脚本摸索
sixiangzhe14 2020-9-23 17:39
一、 for i in {1..9};do tail -6 relax/file$i/s* check;echo -e \\n check ;done 用途是在1到9个文件夹下将log文件中的后六行写入到check文件中,并且每循环一次加一个空行。 echo -e \\n表示加空行的意思,shell bash语言。 这样写好一些 for i in {1..9};do tail -6 relax/file$i/s* | echo -e \\n check ;done for i in {1..9};do tail -6 relax/file$i/s* ;echo -e \\n ;done 效果一样,只是打印在屏幕上。 直接在屏幕上写命令和把命令写成文本不大一样 直接在屏幕上写命令,for循环后面的do不能加分号,换行要写成echo -e \\n,并且$前面不用写转义字符\\,直接写成$i,而用sed命令写成文本换行直接用\\n,添加$需要写成\\$形式。 二、 用sed在文本中添加字段,如果存在$变量,需要前面加上转义字符\\,否则写入的文本中将丢失$i和$5。 sed -i 6c tail -1 file\\$i/OSZICAR | awk '{print \\$5}' log 转义字符是一种特殊的字符常量。制转义字符以反斜线\\开头,后du跟一个或几个字符。转义字符具有特定的含义,不同于字符原有的意义,故称“转义”字符。“\\n”就是一个转义字符,其意义是“回车换行”。 三、 其中有11个文件夹 file10 file2 file4 file6 file8 file1 file11 file3 file5 file7 file9 要读取每个文件夹中POSCAR的原子数。 for i in {1..11} do sed -n '7p;8q' file$i/POSCAR temp done cat -n temp num 在文件夹1到11中,读取POSCAR第7行,循环结束后,在temp文件中每行前面加上序号。 sed -n '7p;8q' file$i/POSCAR temp 7p表示打印第7行,也就是原子数,8q表示终止,退出 其中temp为中间临时文件,为了是要在最终每行前面加上序号 cat -n temp num 一定是要在循环之外加上 四、 for i in 1 2 5 6 7 do mkdir file$i cp INCAR KPOINTS POTCAT file$i done 命令 sed -i 1i mkdir relax \\n cd relax ex1 在第一行插入relax文件夹,并且换行加上一行cd relax 效果如下 mkdir relax cd relax for i in 1 2 5 6 7 do mkdir file$i cp INCAR KPOINTS POTCAT file$i done 五、 例子: $cat ex3 for i in 1 2 5 6 do cat level$i/level.txt level.txt done 在第3行后加一行echo -e \\n 只能用命令$sed -i '3a echo -e \\\\n ' ex3 $cat ex3 for i in 1 2 5 6 do cat level$i/level.txt level.txt echo -e \\n done $sed -i '3a echo -e \\\\n ' ex3 写成这样,单引号改为双引号会有问题,$sed -i 3a echo -e \\\\n ex3 只能外面单引号,里面双引号,用\\\\取消转义 上面这样写有问题,按照下面这样 for i in 1 2 5 6 do cat level$i/level.txt level.txt echo -e \\n level.txt done 这样写出的level.txt才会中间有空行。
个人分类: linux|0 个评论
bash下如何防止误删除
richor 2018-10-3 15:42
用 rmv 代替 rm 。 #rmv #!/bin/sh dirpath=$HOME/.local/Trash foriin$*;do full_date=`date+%Y%m%d%H%M%S` filename=`basename$i` /bin/mv$i${dirpath}/$filename.$full_date done 提升可执行权限:chmod a+x ./rmv 同时给 rm 开保护。 alias rm='rm –i' 由于有 rmv 存在, rm 很少用,便不会出现诸如这里的 disaster: https://superuser.com/questions/382407/best-practices-to-alias-the-rm-command-and-make-it-safer
个人分类: 计算机|1 次阅读|0 个评论
如何用bash脚本批量提交多组任务
richor 2018-4-8 21:31
涉及到 sed 脚本内引用变量: http://www.cnblogs.com/gx-303841541/archive/2012/10/25/2738029.html #job.sh #changetherandomnumberinpr.mdp foriin{1..4} do cp-rrun0run${i} cdrun${i} k=$(($i*2000)) seds/140000/${k}/g../pr.mdppr.mdp grompp-fpr.mdp-cpr.gro-pabeta.top-omd.tpr qsub-Nc1_p2md${i}-penorte24-qthin.q-cwd-V-bymdrun-nt24-deffnmmd cd.. done
个人分类: 计算机|5312 次阅读|0 个评论
GMT: bash script template
haibaraxx 2017-1-17 04:28
1. Open a new text editor window and type: #!/bin/bash # Purpose: # Date: # Author: 2. Save it as template.sh 3. Make it executable: chmod u+x template.sh 4. Use as template for future scripts, i.e. cp template.sh nc2ascii.sh Then edit the new script file. This retains the script's executable permissions . 5. The header will let you find your scripts later using searching tools.
个人分类: GMT|1854 次阅读|0 个评论
显著增加bash交互舒适度的.inputrc
qiaol618 2015-4-2 10:52
在家目录下边touch一个“.inputrc”,内容及功效如下: \e[A: history-search-backward #定义下箭头为根据已键入内容向后搜索命令历史 \e[B: history-search-forward #定义上箭头为根据已键入内容前后搜索命令历史 set show-all-if-ambiguous on #自动完成有多种可能时给出提示,而不是报警 set completion-ignore-case on #自动完成忽略大小写 这里是完整的选项说明: https://www.gnu.org/software/bash/manual/html_node/Readline-Init-File-Syntax.html
个人分类: 用电脑|4040 次阅读|0 个评论
正则表达式基础知识
热度 1 Jerkwin 2014-4-11 02:42
正则表达式基础知识 2014–04–03 13:49:31 整理网络上关于正则表达式异同的资料, 加以补充. 正则表达式是基于样式匹配的文本处理技术的关键所在。想要在编写文本处理工具方面驾轻就熟,就必须对正则表达式有个基本的了解。 正则表达式:在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。正则表达式是一种用于文本匹配的形式小巧、具有高针对性的编程语言,在很多文本编辑器或其他工具里,正则表达式通常被用来检索和/或替换那些符合某个模式的文本内容。许多程序设计语言都支持利用正则表达式进行字符串操作。例如,在Perl中就内建了一个功能强大的正则表达式引擎。正则表达式通常缩写成“regex”,单数有regexp、regex,复数有regexps、regexes、regexen。 正则表达式这个概念最初是由Unix中的工具软件(例如sed和grep)普及开的。由于起源于Unix系统,因此很多语法规则是一样的。但是随着逐渐发展,扩展出以下几个类型。 一、正则表达式分类 基本的正则表达式(Basic Regular Expression, 又叫 Basic RegEx, 简称 BREs) 扩展的正则表达式(Extended Regular Expression, 又叫 Extended RegEx, 简称 EREs) Perl的正则表达式(Perl Regular Expression, 又叫 Perl RegEx, 简称 PREs) 只有掌握了正则表达式,才能全面地掌握 Linux 下的常用文本工具(例如:grep、egrep、GUN sed、 Awk 等) 的用法 二、Linux 中常用文本工具与正则表达式的关系 常握 Linux 下几种常用文本工具的特点,对于我们更好的使用正则表达式是很有帮助的. grep, egrep 正则表达式特点 grep 支持:BREs、EREs、PREs 正则表达式 grep 指令后不跟任何参数,则表示要使用 BREs grep 指令后跟 “-E” 参数,则表示要使用 EREs grep 指令后跟 “-P” 参数,则表示要使用 PREs egrep 支持:EREs、PREs 正则表达式 egrep 指令后不跟任何参数,则表示要使用 EREs egrep 指令后跟 “-P” 参数,则表示要使用 PREs grep 与 egrep 正则匹配文件,处理文件方法 grep 与 egrep 的处理对象:文本文件 grep 与 egrep 在处理文本文件时,是按行处理的 grep 与 egrep 的处理过程:查找文本文件中是否含要查找的 “关键字”(关键字可以是正则表达式),如果含有要查找的 ”关健字“,那么默认返回该文本文件中包含该”关健字“的该行的内容,并在标准输出中显示出来,除非使用了“ 重定向符号 sed 正则表达式特点 sed 支持:BREs、EREs sed 指令默认是使用“BREs” sed 命令参数“-r” ,则表示要使用“EREs” sed 功能与作用 sed 处理的对象:文本文件 sed 在处理文本文件的时候,也是按行处理的 sed 处理操作:对文本文件的内容进行 — 查找、替换、删除、增加等操作 Awk(gawk)正则表达式特点 Awk 文本工具支持:EREs awk 指令默认是使用 “EREs” Awk 文本工具处理文本的特点 awk 处理的对象:文本文件 awk 处理操作:主要是对列进行操作 三、Linux中常见3种类型正则表达式比较 基本组成部分 元字符(meta character)是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的文本处理工具都支持。 POSIX字符类是一个形如 的特殊元序列(meta sequence),可以用于匹配特定的字符范围。 常用Linux/Unix工具中的表示法 PCRE记法 vi/vim grep awk sed * * * * * + \+ \+ + \+ ? \= \? ? \? {m,n} \{m,n} \{m,n\} {m,n} \{m,n\} \b \ \ \ \ \ \ \y \ \ (…) \( …\) \(…\) (…) (…) (…|…) \(…|…\) \(…|…\) (…|…) (…|…) \1 \2 \1 \2 \1 \2 不支持 \1 \2 几种POSIX流派的说明 流派 说明 工具 BRE ( ) { }都必须转义使用,不支持+ ? | grep、sed、vi(但vi支持这些多选结构和反向引用) GNU BRE ( ){ } + ? |都必须转义使用 GNU grep、GNU sed ERE 元字符不必转义,+ ? ( ) { } |可以直接使用,\1、\2的支持不确定 egrep、awk GNU ERE 元字符不必转义,+ ? ( ) { } |可以直接使用,支持\1、\2 grep –E、GNU awk 常见正则表达式比较 字符 说明 BRE ERE PRE python . 除换行符'\n'之外的任意单个字符(awk中可匹配换行符) . . 匹配含\n在内的任一字符用(^$)|(.) . 匹配含\n在内的任一字符可用 . \ 转义符,将下一个字符标记为一个特殊字符、一个原义字符、一个向后引用或一个八进制转义符 \ \\ 转义字符本身 \\ ^ 行首(awk中匹配字符串的开始) ^ $ 行尾(awk中匹配字符串的结尾) $ ^$ 空行 ^$ ^str$ 行 ^str$ \ 单词开头 \ 不支持,用\b代替 不支持 \ 单词结尾 \ \x\ 一个单词或一个特定字符 \x\ () 表达式 不支持,用\(\)代替 () \(\) 表达式 \(\) 不支持,同() * 前面的子表达式0或多次(等价于{0,}) * + 前面的子表达式1或多次(等价于{1,}) 不支持,同\+ + \+ 前面的子表达式1或多次(等价于\{1,\}) \+ 不支持,同+ ? 前面的子表达式0或1次(等价于{0,1}) 不支持,同\? ? \? 前面的子表达式0或1次(等价于\{0,1\}) \? 不支持,同? {n} 前面的子表达式n次,n为0或正整数 不支持,同\{n\} {n} {n,} 前面的子表达式大于等于n次 不支持,同\{n,\} {n,} {n,m} 前面的子表达式最少n次且最多m次,n=m(逗号前后不能有空格) 不支持同\{n,m\} {n,m} \| 交替匹配|两边的任意一项 不支持,同\| | x|y x或y 不支持,同x\|y x|y 之中的任意一个字符 之外的任一字符 0到9中的任一数字字符(要写成递增) 字符集合,匹配所包含的任意一个字符(被放在 非字符集合,匹配未包含的任意一个字符(不包括换行符,awk中则匹配未包含的任意一个字符和换行符) 大写或小写字母中的任意一个字符(要写成递增) 除大写与小写字母之外的任意一个字符(写成递增) ? 紧跟在任何一个其他限制符(* + ? {n} {n,} {n,m})后面时,使用非贪婪匹配模式.非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配 不支持 元字符 \w 包括下划线的任何单词字符(等价于 ) \w \W 任何非单词字符(等价于 ) \W \b 单词边界,指单词和空格间的位置 \b \B 非单词边界 \B \d 0到9中的任一数字字符(等价于 ) 不支持 \d \D 非数字字符(等价于 ) \D \s 任何空白字符,包括空格,制表符,换页符等等(等价于 ) \s \S 任何非空白字符(等价于 ) \S \t 一个横向制表符(等价于\x09和\cI) \t \v 一个垂直制表符(等价于\x0b和\cK) \v \n 一个换行符(等价于\x0a和\cJ) \n \f 一个换页符(等价于\x0c和\cL) \f \r 一个回车符(等价于\x0d和\cM) \r \cx 由x指明的控制字符,x的值必须为A-Z或a-z之一,否则将c视为一个原义的c字符 \cx \xn n为十六进制转义值,必须为确定的两个数字长 \xn \num num为正整数,表示对所获取的匹配的引用 \num POSIX字符类 任何一个小写字母( ) 任何一个大写字母( ) 任何一个字母( ) 任何一个数字( ) 任何一个字母或数字( ) 任何一个空白字符(制表符,空格) 空格和制表符(横向和纵向) 任何一个可见的且可以打印的字符(不包括空格和换行符等) 任何一个控制字符(ASCII字符集中的前32个字符,用十进制表示为0到31,如换行符,制表符等) 任何一个可以打印的字符(不包括 ,字符串结束符\0,EOF文件结束符-1,但包括空格) 任何一个标点符号(不包括 字符集) 任何一个十六进制数(即0-9 a-f A-F) 四、不同类型正则表达式比较 当使用BERs(基本正则表达式)时,必须在下列这些符号前加上转义字符\屏蔽掉它们的 speical meaning ? + | { } ( ) 修饰符用在正则表达式结尾,例如:/dog/i,其中 “i“ 就是修饰符,它代表的含义就是:匹配时不区分大小写. 常见的修饰符如下: g 全局匹配(即:一行上的每个出现,而不只是一行上的第一个出现) s 把整个匹配串当作一行处理 m 多行匹配 i 忽略大小写 x 允许注释和空格的出现 U 非贪婪匹配 五、正则表达式顺口溜 网上有流传的一套关于正则的口诀, 内容多却不够顺口, 我就编个顺口溜吧, 不够雅驯, 姑妄闻之. 正则匹配很重要 文本处理功能妙 基本规则要知道 字符次数范围到 字符匹配最简单 点把尖刀把山翻(.^$) 点号任意都能套 尖刀首尾来报告 特殊字符认不了 反斜线来把它找 若要重复字符串 小括号中站一站 次数限定要记好 星加问号少不了{*+?} 星号任意都能套 加号至少要一炮 剩下问号零或幺 不怕麻烦大括号 说起范围记得好 中括号中字符表 竖杠两旁选一个 尖尖进去全完了 横线跑来帮帮忙 由低到高全阵亡 六、正则表达式图解 如果你想弄清楚某个正则表达式的意思, 可以试试 这里 . 虽然只支持javascript的正则语法, 对其他语言也很有帮助. 相关资料 linux shell 正则表达式(BREs,EREs,PREs)差异比较 或 Shell正则表达式与grep、sed、awk的特点 Shell正则表达式 Linux/Unix工具与正则表达式的POSIX规范 正则表达式口诀及教程 各种语言正则表达式语法比较 常用的正则表达式全面总结 揭开正则表达式的神秘面纱 正则图解
个人分类: 我的工具箱|4575 次阅读|2 个评论
利用sort与uniq过滤文件
Jerkwin 2014-3-30 05:20
利用sort与uniq过滤文件 2014–03–28 18:11:32 设有两类文件, 扩展名分别为A和B, 可能的集合关系如下: 并集 A ∪ B : 属于A或B的文件, 所有可能文件 ls *.A *.B | sort | uniq 交集 A ∩ B : 同时属于A和B的文件, A和B互有对应的文件 ls *.A *.B | sort | uniq -d 交集的补集 A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ : 不同时属于A和B的文件, A和B无对应的文件 ls *.A *.B | sort | uniq -u A的差集 A − B = A ∩ A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ : 属于A但不属于B的文件 ls *.A *.B *.B | sort | uniq -u B的差集 B − A = B ∩ A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ : 属于B但不属于A的文件 ls *.B *.A *.A | sort | uniq -u 若A包含B, 上面的做法可以简化. 并集 A ∪ B = A : ls *.A 交集 A ∩ B = B : ls *.B 交集的补集 A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ = A − B : ls *.A *.B | sort | uniq -u A的差集 A − B = A ∩ A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ : ls *.A *.B | sort | uniq -u B的差集 B − A = B ∩ A ∩ B ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ ˉ = ∅ 应用场景 提交很多作业, 每个作业有一个输入文件, 完成后会产生一个输出文件, 输入文件和输出文件存放于同一文件夹下 适当利用这些命令可以快速过滤文件, 知道哪些作业已完成, 哪些作业未完成, 也可以快速地将已完成的作业移到其他地方保存.
个人分类: 我的工具箱|2684 次阅读|0 个评论
Bash脚本中使用颜色
Jerkwin 2014-3-22 07:39
Bash脚本中使用颜色 2014–03–21 16:40:35 在bash脚本的输出中适当使用颜色可以使结果呈现得更直观, 便于快速获取信息. 试想, 从一堆黑色文字中获取某个数字, 你可能要花点时间查看, 分析, 才能知道答案. 若这个数字是以红色标识出来的, 那大多数人一眼就可以得到答案, 所花的时间也要少得多. 利用 echo 命令可以设置输出的颜色, 格式为: echo -e “\033[前景色;背景色;模式m输出字符\033[0m” \033 为ASCII码 ESC (八进制33, 十进制27), 也可用 \e 代替, 即 echo -e “\e[前景色;背景色;模式m输出字符\e[0m” 30–37设置前景色, 40–47设置背景色, 颜色为ANSI标准色 前/背 色 30/40 黑 31/41 红 32/42 绿 33/43 黄 34/44 蓝 35/45 紫 36/46 青 37/47 白 模式中设置字符的特殊属性, 常用的有 0 恢复默认 1 高亮 4 下划线 5 闪烁 7 反显 8 消隐 例: echo -e “\e[41;37m 红底白字 \e[0m” echo -e “\e[37;41;1m 红底白字+高亮 \e[0m” 测试代码 echo T = 'RGB' echo B\F { 30 . . 37 } m for BACK in { 40 . . 47 } ; do echo - en $BACK for FORE in { 30 . . 37 } m ; do echo - en \e [ $BACK ; $FORE $T \e [ 0 m done echo done echo for MODE in 1 4 5 7 8 ; do echo B\F { 30 . . 37 } ; $ { MODE } m for BACK in { 40 . . 47 } ; do echo - en $BACK for FORE in { 30 . . 37 } ; $ { MODE } m ; do echo - en \e [ $BACK ; $FORE $T \e [ 0 m done echo done echo done echo F\B { 40 . . 47 } m for FORE in { 30 . . 37 } ; do echo - en $FORE for BACK in { 40 . . 47 } m ; do echo - en \e [ $FORE ; $BACK $T \e [ 0 m done echo done echo for MODE in 1 4 5 7 8 ; do echo F\B { 40 . . 47 } ; $ { MODE } m for FORE in { 30 . . 37 } ; do echo - en $FORE for BACK in { 40 . . 47 } ; $ { MODE } m ; do echo - en \e [ $FORE ; $BACK $T \e [ 0 m done echo done echo done 输出 注意 利用 echo 设置输出颜色与模式后, 命令行中所有的输出都会以设置的格式输出, 除非再利用 echo 设置为默认格式. 由于所用数字不重复, 背景, 前景, 模式三个数字顺序无关紧要, 可以任意顺序指定.
个人分类: 我的工具箱|4392 次阅读|0 个评论
Bash命令行参数的手动处理
Jerkwin 2014-2-21 11:30
Bash命令行参数的手动处理 2014–01–30 13:45:22 在编写Bash脚本时, 为了保证脚本的通用性, 有时需要传入命令行参数. 这就需要我们对命令行参数进行解析处理. 虽然说起来很简单, 也有一般的通用处理方法, 但通用的方法总有其不便之处, 知道一些简单的手动处理方法还是很有必要的. 假定处理时参数顺序固定, 读入后被用来设定其他变量值, 若执行 bash Prg.bsh Opt1 Opt2 Opt3 后, 变量 P1=Opt1; P2=Opt2; P3=Opt3 最好是先给出变量 P1, P2, P3 的默认值, 然后根据命令行参数的个数进行设置. quick-and-dirty的if-elif处理 if ] ; then P 1 = $ 1 elif ] ; then P 1 = $ 1 ; P 2 = $ 2 elif ] ; then P 1 = $ 1 ; P 2 = $ 2 ; P 3 = $ 3 fi 形式简单点的方式 ] { P 1 = $ 1 ; } ] { P 1 = $ 1 ; P 2 = $ 2 ; } ] { P 1 = $ 1 ; P 2 = $ 2 ; P 3 = $ 3 ; } 更聪明点的方式 ] { P 1 = $ 1 ; } ] { P 2 = $ 2 ; } ] { P 3 = $ 3 ; } 直接判断参数存在与否 ] { P 1 = $ 1 ; } ] { P 2 = $ 2 ; } ] { P 3 = $ 3 ; } 更好点的判断方式 ] { P 1 = $ 1 ; } ] { P 2 = $ 2 ; } ] { P 3 = $ 3 ; } 更高级的变量替换方式 P 1 = $ { 1 : - Opt 1 } P 2 = $ { 2 : - Opt 2 } P 3 = $ { 3 : - Opt 3 } 利用数组 Opt = ( Opt 1 Opt 2 Opt 2 ) for ( ( i = 1 ; i $# ; i + + ) ) ; do Opt = $ { ! i } done P 1 = $ { Opt } P 2 = $ { Opt } P 3 = $ { Opt } 上面的处理假定传入参数的顺序是固定的, 当参数个数过多时, 这种限定会使得脚本使用不便. 若传入的各个参数之间没有明显的标志相区别, 一种解决方法就是利用选项了. 先将参数全部存入数组, 然后从中解析出相应的选项, 再根据选项设定相应参数的值. 简单示例代码如下: opt = ( $@ ) ; N = $ { #opt } for ( ( i = 0 ; i N ; i + + ) ) ; do arg = $ { opt } ; j = $ ( ( i + 1 ) ) ] { P 1 = $ { opt } ; } ] { P 2 = $ { opt } ; } ] { P 3 = $ { opt } ; } opt = ; opt = done 当然, 最通用的方法是利用 getopt 和 getopts , 使用时请参考相应的资料. 参考 Bash Shell中命令行选项/参数处理 Mendel Cooper著, 杨春敏, 黄毅译, 高级Bash脚本编程指南, V3.9.1-HTML–2006年5月26日, 4.4 特殊的变量类型
个人分类: 我的工具箱|4374 次阅读|0 个评论
Bash游戏编程: 俄罗斯方块
Jerkwin 2014-1-23 08:58
Bash 游戏编程: 俄罗斯方块 2014-01-19 11:55:17 俄罗斯方块是个经典游戏 , 想必很多人都玩过 . 利用 Bash, 我们也可以实现一个简单的俄罗斯方块游戏 . 之所以这样做 , 不是因为利用 Bash 实现起来简单 , 而是因为在实现过程中对 Bash 编程的方方面面都能有所了解 , 可作为 Bash 编程的范例 . 下面是网上找到的两种实现 , 供有意学习 Bash 的人参考 . shell 版俄罗斯方块 作者 : xhchen 网页 : http://bbs.chinaunix.net/thread-184858-1-1.html 十多年前的代码了 , 写得中规中矩 , 很容易读懂 . Linux Shell 版俄罗斯方块游戏 作者 : YongYe 网页 : http://www.bathome.net/thread-15219-1-1.html 最近的一个实现 , 功能多些 , 代码读起来可能比第一个稍难 , 但是也很容易懂 .
个人分类: 我的工具箱|4197 次阅读|0 个评论
Bash脚本实现批量作业并行化
热度 1 Jerkwin 2013-12-16 03:27
Bash 脚本实现批量作业并行化 2013-12-14 21:26:02 在 Linux 下运行作业时 , 经常会遇到以下情形 : 有大量作业需要运行 , 完成每个作业所需要的时间也不是很长 . 如果我们以串行方式来运行这些作业 , 可能要耗费较长的时间 ; 若采用并行方式运行则可以大大节约运行时间 . 再者 , 目前的计算机绝大部分都是多核架构 , 要想充分发挥它们的计算能力也需要并行化 . 总结网上看到的资料 , 利用 Bash 脚本 , 可以采用下面几种方法实现批量作业的并行化 . 注意 , 下面论述中将不会区分进程和线程 , 也不会区分并行和并发 . 1. 采用 GNU 的 paralle 程序 parallel 是 GNU 专门用于并行化的一个程序 , 对于简单的批量作业并行化非常合适 . 使用 parallel 不需要编写脚本 , 只需在原命令的基础上简单地加上 parallel 就可以了 . 所以 , 如果能用 paralle 并行化你的作业 , 请优先使用 . 有关 paralle 的详细说明 , 请参考其 官方文档 . 2. 最简单的并行化方法 :+wait 利用 Bash 的后台运行 和 wait 函数 , 可实现最简单的批量作业并行化 . 如下面的代码 , 串行执行大约需要 10 秒 改为下面的简单并行代码理想情况下可将运行时间压缩到 3 秒左右 3. 进程数可控的并行化方法 (1): 模拟队列 使用 Bash 脚本同时运行多个进程并无困难 , 主要存在的问题是如何控制同时运行的进程数目 . 上面的简单并行化方法使用时进程数无法控制 , 因而功能有限 , 因为大多数时候我们需要运行的作业数远远超过可用处理器数 , 这种情况下若大量作业同时在后台运行 , 会导致运行速度变慢 , 并行效率大大下降 . 一种简单的解决方案就是模拟一个限定最大进程数的队列 , 以进程 PID 做为队列元素 , 每隔一定时间检查队列 , 若队列中有作业完成 , 则添加新的作业到队列中 . 这种方法还可以避免由于不同作业耗时不同而产生的无用等待 . 下面是根据网上的代码改写的一种实现 . 实用性更强的代码 , 请 参考原文 . 一个更简洁的方法是记录 PID 到数组 , 通过检查 PID 存在与否以确定作业是否运行完毕 . 可实现如下 3. 进程数可控的并行化方法 (2): 命名管道 上面的并行化方法也可利用命名管道来实现 , 命名管道是 Linux 下进程间进行通讯的一种方法 , 也称为先入先出 (fifo,first in first out) 文件 . 具体方法是创建一个 fifo 文件 , 作为进程池 , 里面存放一定数目的 令牌 . 作业运行规则如下 : 所有作业排队依次领取令牌 ; 每个作业运行前从进程池中领取一块令牌 , 完成后再归还令牌 ; 当进程池中没有令牌时 , 要运行的作业只能等待 . 这样就能保证同时运行的作业数等于令牌数 . 前面的模拟队列方法实际就是以 PID 作为令牌的实现 . 据我已查看的资料 , 这种方法在网络上讨论最多 . 实现也很简洁 , 但理解其代码需要的 Linux 知识较多 . 下面是我改写的示例代码及其注释 . 注意 : (1) exec6$Pfifo 这一句很重要 , 若无此语句 , 向 $Pfifo 写入数据时 , 程序会被阻塞 , 直到有 read 读出了文件中的数据为止 . 而执行了此语句 , 就可以在程序运行期间不断向文件写入数据而不会阻塞 , 并且数据会被保存下来以供 read 读出 . (2) 当 $Pfifo 中已经没有数据时 ,read 无法读到数据 , 进程会被阻塞在 read 操作上 , 直到有子进程运行结束,向 $Pfifo 写入一行 . (3) 核心执行部分也可使用如下方式 {} 和 () 的区别在 shell 是否会衍生子进程 (4) 此方法在目前的 Cygwin( 版本 1.7.27) 下无法使用 , 因其不支持双向命名管道 . 有人提到一个 解决方案 , 使用两个文件描述符来替代单个文件描述符 , 但此方法我没有测试成功 . 参考资料 : 1. 简洁的模拟队列方法实现 shell 里如何实现 多线程 ? http://blog.linuxeden.com/html/55/t-164155.html 2. 模拟队列方法 , 实用性更强的代码 A srcipt for running processes in parallel in Bash http://pebblesinthesand.wordpress.com/2008/05/22/a-srcipt-for-running-processes-in-parallel-in-bash/ 3. 命名管道方法及其解释 bash 实现 多进程 http://www.cnitblog.com/sysop/archive/2008/11/03/50974.aspx SHELL 模拟多线程脚本的详细注解 http://findingcc.blog.51cto.com/1045158/287417 一段相当精彩的 shell 脚本(模拟多线程) http://www.blogbus.com/luobeng-logs/123290553.html Linux 下模拟多线程的并发并发 shell 脚本 http://www.centoscn.com/shell/2013/0731/823.html shell 脚本模拟多进程 http://www.phpfans.net/article/htmls/201009/MzA3ODEy.html shell 并发脚本学习 http://raocl.wordpress.com/tag/mkfifo/ 4. Cygwin 下双向命名管道的问题 bi-directional named pipe http://cygwin.com/ml/cygwin/2009-07/msg00081.html
个人分类: 我的工具箱|15521 次阅读|1 个评论
ubuntu10.04 LTS 安装GAMIT/GLOBK步骤(Bash环境配)本文亲自总结
zhangyong1361 2012-12-31 20:11
ubuntu10.04 LTS 安装GAMIT/GLOBK步骤(Bash环境配)本文亲自总结
GAMIT/GLOBK软件(以下简称GAMIT)的由来与应用,在这里就不用多介绍了。相信准备GAMIT的各位对该软件应该具有一定的了解了。下面言归正传,叙述在ubuntu10.04LTS版上安装GAMIT的步骤,为什么采用10.04LTS版本,因为该版本对于GAMIT来说比较合适,特别说明,以下均在root用户下安装。 1、编译器问题 GAMIT软件推荐使用4.2以上的gcc及gfortran编译器(4.3除外,据相关资料介绍,该版本编译器有问题,会导致GAMIT编译失败,另外用4.6版本的编译器时,需要修改GAMIT的源码参数, 繁琐故不推荐),在这里作者推荐使用4.2或者4.4版本的编译器。Ubuntu10.04LTS版,默认编译器版本的4.4.3,但是没有安装gfortran编译器,所以要自己安装gfortran编译器。在终端中输入 : apt-get install gfortran 便会自动安装该系统版本的最新版gfortran,如果想使用4.2版本的gcc及gforrtan编译器,参考相关治疗下载安装4.2编译器,并配置默认编译器版本为4.2版。 2、libx11-dev软件包安装 libx11-dev是X11(X Window)的客户库(X11 client- side library)。该软件包包含了全部的X11应用编程接口(API)基本函数。其中,libX11.a和Xlib.h是 GAMIT/GLOBK所必须依赖的两个库文件,主要是为Globk的提供图形库支持。Ubuntu的默认配置不包含该软件包, 故需要用户自己安装,在终端中输入: apt-get install libx11-dev 便会自动下载安装libx11-dev软件及其相关附件。 3、SHELL安装 GAMIT软件的相关命令是在csh或tcsh下运行的,而Ubuntu默认的是bash,故要下载csh及tcsh,有相关安装说明中降到需要把系统的默认SHELL改为csh或者tcsh,但是本人认为那样并不是完美的,在系统默认的bash下也可以运行GAMIT的软件(前提是安装了csh tcsh且在bash中加入GAMIT途径,增加途径这个后面在叙述),而且bash默认支持上下键命令回滚、文件类型分色区分等,csh及tcsh要进行相关繁琐的手动配置才能实现上述功能,且对于新手一时难以配置成功,故建议直接采用bash,不用修改系统的SHELL模式。在这里只要安装csh tcsh即可。输入如下命令安装csh、tcsh。 apt-get install csh apt-get install tcsh 安装完即可。 4、FTP软件安装 GAMIT软件有自动从FTP服务器下载数据的功能,此功能需要FTP软件的支持,GAMIT软件支持NCFTP和WGET两种FTP软件,Ubuntu自带了WGET,但没有预装NCFTP。如果你想使用NCFTP(如在sh_get_rinex命令中增加选项 -ftp_prog ncftp ), 则需要安装ncftp软件,在终端中输入: apt-get install ncftp 自动安装完即可,无需任何配置。 5、awk tail ls gzip gunzip等软件 这类软件ubuntu默认已经安装了,就不用管他了。如果在日后充分熟悉了GAMIT及Ubuntu系统后,可以查看这些软件的用处及不同版本的异同。对于初学者可忽略此处。 6、GMT及NETCDF软件安装 GAMIT软件计算完后可以调用相应的命令进行绘图,该绘图命令是基于GMT和NETCDF实现的。GMT及NETCDF软件的安装方式有两种:第一种,是自己下载GMT 及NETCDF软件自己进行编译配置,这个比较繁琐不利于初学者,此处不推荐,等日后熟悉了可以参考相关资料安装。第二种,是利用apt-get命令进行安装,在终端中输入: apt-get install gmt 便会自动下载安装gmt及netcdf,此处安装的精简版的,但已经满足GAMIT的需要。 以上6大步骤是安装GAMIT软件之前的系统配置,安装代码如下(安装顺序随意) apt-get install gfortran apt-get install csh apt-get install tcsh apt-get install libx11-dev apt-get install ncftp apt-get install gmt 下面就是正式安装GAMIT软件。 7、正式安装GAMIT/GLOBK软件 在OPT目录下新建名为 gamit 的目录,(目录名可以根据自己习惯定),将按转包解压后里面的文件全部复制到所建的文件夹下。在终端中 用 cd 命令进入gamit目录。输入 chmod +x install_software 跟GAMIT安装脚本赋予可执行权限,然后输入 ./install_software 便会自动安装,然后根据提示,基本就一路NEXT了,GAMIT安装中其实是一路 'y' 加回车。 如果gamit目录下有升级包,安装过程中会提示是否应用更新包,如 Do you want to apply incremental updates: incremental_updates.080812.tar.Z incremental_updates.080919.tar.Z incremental_updates.081022.tar.Z Continue ? (y/n) 一路 'y'即可。安装到最后,会提示 ++++++++++++++++++ GLOBK installed ++++++++++++++++++ Create the gg link in your home directory to the version of gamit/globk you just installed ? (y/n) 意思是安装成功,是否在主文件夹下生成gg链接,此处输入 y ,因为gamit运行时是从主文件夹下gg链接进入gamit软件的tables目录中链接文件的。输入y后,会提示 Don't forget to set your : path to include /opt/gamit/gamit/bin and /opt/gamit/kf/bin : HELP_DIR environment variable in you shell profile (in .cshrc/.tcshrc add: setenv HELP_DIR /opt/gamit/help/) : INSTITUTE evnironment variable in your shell profile (in your .cshrc/.tcshrc add: setenv INSTITUTE where_i_work) where_i_work is a 3 character identifier for your solutions 此处的意思是,需要再shell配置文件中把GAMIT的可执行文件目录添加进系统途径中,这样才能在终端中调用。显示的内容是让配置csh或者tcsh,但本文建议配置bash,原因上面叙述了。 8、GAMIT软件配置 其他安装说明建议建议在主文件夹下配置.bashrc文件(说明在ubuntu系统下.开头的文件是隐藏文件,用Ctrl+H键来显示隐藏文件),该文件是针对当前用户的SHELL生效的,如果用户在root下安装了gamit,但是想在其他用户下(如一般在管理员用户下运行)则还需要再相应的用户下再次配置该用户的.bashrc文件,故本人建议配置/etc/bash.bashrc文件,该文件对于任何用户都有效,无需重复配置,配置一次就对所有用户生效。 打开bash.bashrc文件在其最后面添加如下:(说明,如果配置.bashrc文件也是在其下面添加如下代码,下面是截的图,贴源码时,网页会自动解析代码,显示错误) 配置完后,在root用户下的安装与配置便完成了,在其他用户下还要稍微配置下后面叙述。 9、 GAMIT 测试 在终端中输入 doy 显示相关doy命令的提示便说明安装成功,测试安装的gamit是否正常运行,可以参考gamit安装目录下example下的README文件进行实验,或者计算自己的项目文件。 10、其他用户下配置 退出root用户,进入自己使用的用户,进入该用户的主文件夹,建立gg链接到gamit的安装目录,在终端中进入主文件夹,输入: sudo ln -s /opt/gamit gg (注意现在是非root下,运行和权限相关的命令需要添加sudo) 将gamit链接到主文件夹下的gg链接,(为什么要这样做,上文说了,gamit链接文件是从gg中进入的,root下在安装过程中提示你,已经生成了,但是其他用户需要自己链接)。链接完后,会发现gg文件夹上有一把锁,说明该用户对其无使用权限,需要对gamit安装的文件进行权限解除,进入到/opt 下,输入 sudo chmod 777 gamit 对gamit主目录进行解锁,另外还有对其所有的文件进行解锁,进入gamit目录,输入 sudo chmod 777 * -R 对所有的gamit进行解锁,解锁完成后,会发现gg文件夹上的锁没了,说明解锁成功。此时在终端中输入 doy 显示提示便说明成功,如果不解锁,会提示权限问题。 以上步骤为本人安装gamit的步骤(为了彻底搞清楚GAMIT的安装与为什么这样配置安装环境,及相关影响,本人安装GAMIT数十次,重装不同ubuntu系统达十几次),使用时有问题可以联系本人 E-mail: zhangyong1361@163.com 张勇 2012-12-31
个人分类: GAMIT/GLOBK|6007 次阅读|0 个评论
bash快捷键cheat sheet
ddbb12 2011-10-5 19:24
近日来对各种的cheat sheet尤为喜欢,真是能起到帮助作用的好工具。 看到了一个关于bash操作的快捷键文章,一时兴起,做成了cheat sheet,希望能有助于提高bash操作效率。 Bash快捷键-cheat-sheet.pdf
个人分类: 计算机|3160 次阅读|0 个评论

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-5-21 00:03

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部