一、常用的linux命令
1.shell脚本里的命令
. ./export.sh
示意:第一个点 空格 :表示把后面执行结果(如导入环境变量)导入到当前文件
第二个点:执行当前目录的文件
#如果删除软件后,再次安装提示已安装,肯定是卸载不彻底,用下面命令吧
dpkg -l | grep docker | awk '{print $2}' | sudo xargs dpkg -P
- ls -1
列出文件及文件夹的名字
# shell 使用 -- 接收参数
#横杠后面跟一个字符的选项用单横杠,后面跟一个单词的用双横杠
utils/prepare_lang.sh --position-dependent-phones false data/local/dict "<SIL>" data/local/lang data/lang
$$#shell本身pid;
$0 #shell文件名
$@ #输入参数列表,每一个参数独立
$* #输入参数,所有参数在一个字符串内
$# #参数的个数
$(命令) #如:a=$(ls)
${表达式/变量名} # 获取变量值,也可以做布尔、字符串切割运算,如:${!argpos}
if [ "${!argpos}" == "--config" ]; then
fi
# []和test:判断字符串,整数,文件
# [[]]:支持字符串模糊匹配,正则
# let和(()):主要进行算数运算
# if [ -f file ] 如果文件存在
# if [ -d … ] 如果目录存在
# if [ -s file ] 如果文件存在且非空
# if [ -r file ] 如果文件存在且可读
# if [ -w file ] 如果文件存在且可写
# if [ -x file ] 如果文件存在且可执行
# if [ -z $string ] 如果string 为空
# val=${1:-start}如果$1存在且不为空m=$1,如果$1不存在或为空,那么m=start; #:-为三元运算
eval '[ -z "${'$name'+xxx}" ]' #eval command-line;参数不限数目,彼此之间分号分开
#假如$name 设定为空值或非空,xxx作为回传值。没有设定不做处理
shift 3 #位置参数用shift命令左移。比如shift 3表示原来的$4现在变成$1
2. perl
#!/usr/bin/env perl
$full_list = $ARGV[0];
$test_list = $ARGV[1];
$train_list = $ARGV[2];
open FL, $full_list;
$nol = 0;
while ($l = <FL>)#因该以行为单位读取的$l自己会变化吧
{
$nol++;#统计行数
}
close FL;
$i = 0;
open FL, $full_list;
#以下代码以写入( > )的方式打开文件 test_list.txt
open TESTLIST, ">$test_list";
open TRAINLIST, ">$train_list";
while ($l = <FL>)
{
#chomp 是 chop 的安全版本,相对于chop 删除字符串或list最后任意字符。
#chomp 只删除 '\n',否则不删除。
chomp($l);
$i++;
# 全部数据分两份,前一半数据放在TRAINLIST ,后一半放在TESTLIST
if ($i <= $nol/2 )
{
## 写入TRAINLIST 文件数据
print TRAINLIST "$l\n";
}
else
{
print TESTLIST "$l\n";
}
}
#!/usr/bin/env perl
$waves_dir = $ARGV[0];
$in_list = $ARGV[1];
open IL, $in_list;
while ($l = <IL>)
{
chomp($l);
#. :结束符号
$full_path = $waves_dir . "\/" . $l;
# ~ 对后面的正则表达式表示匹配的意思,替换.wav字符串为空
$l =~ s/\.wav//;
#在循环内print即可写入文件$in_list
print "$l $full_path\n";
}
for x in train_yesno test_yesno; do
mkdir -p data/$x
cp data/local/${x}_wav.scp data/$x/wav.scp
cp data/local/$x.txt data/$x/text
cat data/$x/text | awk '{printf("%s global\n", $1);}' > data/$x/utt2spk
#command1 < infile > outfile
#同时替换输入和输出,执行command1,从文件infile读取内容,然后将输出写入到outfile中
utils/utt2spk_to_spk2utt.pl <data/$x/utt2spk >data/$x/spk2utt
done
if ( @ARGV > 1 ) {
#die会终止程序的运行,内容打印出来
die "Usage: utt2spk_to_spk2utt.pl [ utt2spk ] > spk2utt";
}
# <>表示从标准输入读入数据 即:data/$x/utt2spk
while(<>){
#$_ 在while循环里,当从文件句柄甚至是从标准输入读入时,如果不显式赋值给一个变量,读取的这一行会被赋值给$_
#数组变量@开头,下表从0开始;
@A = split(" ", $_);
@A == 2 || die "Invalid line in utt2spk file: $_";
#赋值操作
# 哈希变量$seen_spk,key是s;这种方式获取变量
# push 从数组的末尾加入元素
($u,$s) = @A;
if(!$seen_spk{$s}) {
$seen_spk{$s} = 1;
push @spklist, $s;
}
push (@{$spk_hash{$s}}, "$u");
}
# global
foreach $s (@spklist) {
# 连接符 元素
$l = join(' ',@{$spk_hash{$s}});
print "$s $l\n";
}
子程序(函数)
二、linux中的一些概念
1.linux内核锁:自旋锁和信号量
- 自旋锁:只能被一个可执行线程持有,如果一个可执行线程试图请求一个已经被征用(持有)的自旋锁,那么这个线程会一致 循环—旋转–等待锁可重新可用。自旋锁可以在任何时刻防止多于一个可执行线程同时进入临界区
- 信号量,是一种睡眠锁,如果一个任务试图获取一个已经被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由可以去执行其他代码,当持有信号量的进程将信号释放后,在等待队列中的任务会被唤醒,从而获得该信号量。信号量适用于锁会被长时间持有的情况,只能在进程上下文中使用,因为中断上线文中是不能被调度的;当代码持有信号量时,不可再持有自旋锁。
2.申请大块内核内存
申请大块内存的成功率随着系统运行时间的增加而减少,虽然可以通过vmalloc系统调用申请物理不连续虚拟地址连续的内存,但使用效率不高且在32位系统上vmalloc的内存地址空间有限。如果非常需要申请成功,只能退佣“启动内存 boot memory”
3.用户进程间通信方式
- 管道(pipe):允许一个进程和另一个与它有共同祖先的进程之间通信;
- 命名管道(named pipe):克服了管道没有名字的限制,因此除具有管道所具有的所有功能外,他还允许无亲缘关系的进程进行通信,命名管道在文件系统中有对应的文件名,命名管道通过命令mkfifo或系统调用mkfifo来创建
- 信号(signal):信号是比较复杂的通讯方式,用于通知进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身,
- 消息(message)队列:消息队列是消息的链接表,包括posix消息队列system V消息队列。有足够权限的进程可以向消息队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流及缓冲区大小的限制等缺陷。
- 共享内存:使得多个进程可以访问同一块内存空间,是最快的可用的IPC形式。是针对其他通信机制运行效率低而设计的。往往与其他通信机制,如信号量结合起来使用,来达到进程间的同步或互斥。
- 信号量(semaphore):主要作为进程间及同一进程不通线程的同步手段
- 套接字(socket1):更为一般的进程间通信机制,可用于不通机器之间的通信。
- 通过伙伴系统申请内核内存的函数:在物理页面管理上实现了基于区的伙伴系统(zone based buddy system).对不通区的内存使用单独的伙伴系统(buddy system)管理,而且独立的监控空闲页面。对应的函数:
alloc_pages(gfp_mask,order),__get_free_pages(gfp_mask,order)等;
- linux虚拟文件系统的关键数据结构:
struct super_block,struct inode,struct file,struct dentry
三 内核笔记
1.内核一些概念
- 1.git log --pretty=‘format=:%an’ filepath #%an 作者(author)的名字
2.sort -u -k 2,2 # -u uniq去重,-k 指定进行排序的列
3.EAL4是安全保障的专项认证《信息技术安全评估准则》的其中一个评估等级,是国际标准化组织统一现有多种准则的结果,评估等级分为EAL1、EAL2、EAL3、EAL4、EAL5、EAL6和EAL7共七个等级。
4.微内核-只有最基本的功能由中央内核实现,所有其他功能都委托给独立进程;错点:各个组件之间通信消炎药额外的CPU,所以性能差;
宏内核:内核的全部代码都打包到一个文件中,包括子系统(内存/文件/设备驱动系统程序),内核中的每个函数都可以访问内核中的所有其他部分。、
5.pstree:用于查看进程数之之间的关系;参数 -p 列出每个进程的PID,-u 列出每个进程的所属账号名称;-apnh 显示进程间的关系
6.UNIX操作系统创建新进程的机制,分别是fork和exec:
fork,创建一个当前进程的副本,主要原理就是将内存复制操作延迟到父进程或子进程向某内存页面写入数据之前,在只读访问的情况下父子进程可以公用统一内存页。
exec:将一个新程序加载到当前进程的内存中并执行。
2.之前的一点知识
一、AT&T汇编语法格式(与英特尔汇编不太一样)
1.寄存器的引用 引用寄存器要在寄存器号前加%,栗子:mov % eax,% ebx
2.操作数顺序 mov % eax(源),% ebx(目的)
3.常数/立即数的格式 使用立即数,在数前加(不加$则认为是内存地址)$,栗子: mov ¥4,%ebx
符号常数直接引用,栗子:mov value, % ebx
引用符号地址在符号前加$,栗子:mov $value, % ebx
4.操作数长度 操作数长度用加在指令后的符号表示 :b(byte) w(word),l(long) 栗子:movw % ax,%bx
绝对转移和调用指令(jmp/call)的操作数前要加上*作为前缀
转移指令和远调指令的操作码,在为ljump 和lcall, 栗子:ljump $esction,$offset
远调返回指令 lret $stack_adjust
寻址方式 section:disp(base,index,scale)表示,计算方法:base+index*scale+disp 栗子:movl array(,%eax,4),%eax movb $4,%fs:(%eax)
_asm_("asm statements":outputs:inputs:registers-modified);汇编语句----含义:asm statements 这条汇编语句执行后,输出的寄存器 outpust,inputs是在汇编代码执行前输入的参数,在汇编代码执行过程中会被修改的寄存器 栗子:_asm_("pushl %%eax \n\t" movl $0, %%eax \n\t" "popl %eax");