libc.so.6被误删的恢复

说出来都是泪,国庆都都这个事耽搁了,libc.so.6文件被我不小心删掉了,踩了所有能踩到的坑,终于恢复了。

事情的起因是由于需要做进化树,出来可能树比较大,所以下载了命令行版的MEGA11(mega-cc-11.0.13-1.x86_64),但在安装过程中显示需要glibc2.34, 我用yum最多只能更新到glibc2.28,而是下载了glibc2.34源代码进行编译安装,安装在了/usr/local文件夹中,但系统默认的还是/lib64/中的glibc2.28,于是想着像其它软件一样,先把现在使用的libc.so.6删掉,然后重新建立一个软连接到/usr/local/glicb2.34中的libc.so.6,但当我删除掉/lib64中的libc.so.6后,一切都变了,除了cd命令,其它命令都用不了,除了当前运行的用户,其它用户远程连接也进去不了,想着第二天去机房登录root再改过来不就行了,便第二天去机房发现root用户也登录不了,这时windows思维来了,重启可以解决80%的问题,果断重启了,这也使我失去了最后一次挽救的机会,重启之后,原来的连接也断了,没办法,只能到处找攻略,发现手贱的不只我一个,于是按照攻略开启了曲折的营救模式。

由于服务器安装的是CentOS8,但CentOS8官方已不支持了,官网上下不到系统,我想CentOS7应该也可以,于是就下载了一个CentOS7系统制作启动盘,这就开启了踩坑之旅。

首先出现的是问题是进入救援模式后出现:

No Caching mode page found
Assuming drive cache:write through

2. 修改U盘位置

出现此种情况之后,安装无法进行下去,只能重启,通过搜索发现是由于系统没有识别引导路径,在进入到启动盘界面时,用上下键选择救援模式,然后按”e”进入编辑模式,将hd:后的内容换成U盘所在的盘符位置,如:

vmlinuz initrd=initrd.img inst.stage2=hd:LABEL=CentOSx207x20x86_64 rescue quiet
###修改为
vmlinuz initrd=initrd.img inst.stage2=hd:/dev/sdc4:/ rescue quiet
###如果不知道U盘的位置,可以退出后进入shell模式,然后使用:
ls /dev/sd*
##或者使用查看
fdisk -l

这一步没有问题后按”ctrl+x”运行,看见有选择界面后选择“ 1 continue”,可以运行了,但一直是出现一排排的等于号,我以为可能是由于服务器中文件比较多,加载时间比较长,但等我第二天过来一看还是如此,第三天也一样,我看到别人的只有两排等于号,第四天终于受不了,给终止了,重新找原因。

多年的经验告诉我,百娘在关键时候是不行的,解决问题的最佳途径是要找官方的说明文档,中文中论坛中的解释很多都是很片面的,而是找到了官方的关于救援模式的说明文件,里面详细说明了救援模式的来龙去脉,而且告诉了具体的操作方法,发现救援模式是用Anaconda做的一个小的linux环境,使用Alt+Tab可以切换到命令模式,可以运行

systemctl --no-wall rescue

重新进入救援模式,发现还是出现原来的情况,但是如果选择2 “Read-only mount”的话可以挂载文件,这下心里就有底了,实在弄不了可以选择这个把数据拷贝出来。

3. 更换系统盘

后来想了一下,会不会是由于我的系统是CentOS8,而我使用的救援模式所采用的系统是CentOS7,导致挂载失败,于是重新找了个CentOS8系统,由于官方不支持CentOS8了,很多镜像也去掉这个版本了,幸好阿里云镜像中还有,使用UltraISO做了个新的启动盘,由于U盘比较旧了,插在服务器上接触不良,老是识别不了,没办法重新找了一个好一点的金士顿的盘才做好,但是每次开机时都是直接进入了系统,没有先启动U盘,一开始时我不是已经设置了U盘先启动的吗,使我进一步怀疑是不是U盘有问题,插到其它的电脑试了都没有问题后,重新打开BIOS设置看下是不是U盘先启动,但发现启动顺序恢复到了默认设置,按F2重新设置启动顺序,终于顺利进入了U盘的救援模式,按照上面的操作按”e”进入编辑模式,将hd:后的内容换成U盘所在的盘符位置,进入到系统救援模式,按”1) Continue”,但又遇到了新的问题,就是找不到可用的 linux 系统,明明刚才用CentOS7启动盘的时候可以找到系统吗。而是又搜索了这个错误信息,终于找到了解决的办法。

4. 激活引导分区

出现的错误信息如下:

you don't have any Linux partitions,
Press return to get a shell.
The system will reboot automatically when you exit from the shell.

参考这篇文章介绍的方法终于解决了。运行”fdisk -l”查看分区情况,看到/dev/sda1 后面加了个“*”号,这个可能就是引导分区了,运行”lvdisplay”查看逻辑卷,找到需要激活的逻辑卷,使用vgchange命令进行激活,但当我使用mount挂载时还是找不到,运行”systemctl –no-wall rescue”重新进入救援模式,按”1) Continue”没有出现找不到linux系统,激活的引导程序所在的系统找到了,不到1分钟swap中的内容就挂载上去,因为不需要修改/root和/home中的内容,所以选择不挂载这两个盘。这一步需要运行的命令如下:

###查看磁盘分区情况
fdisk -l
###查看逻辑卷
lvdisplay
###激活逻辑卷
vgchange -ay /dev/cl   ##cl是上一步需要激活的"VG name"
###重新进入救援模式
systemctl --no-wall rescue

5. 恢复libc.so.6文件

与CentOS7不同的是CentOS8默认挂载的文件夹是”/mnt/sysroot/”,不是”/mnt/sysimage”, “chroot /mnt/sysroot”进入到服务器的系统目录(注意不是启动盘中的系统目录),运行”ls‘可以看到系统目录中的文件,进入libc.so.6文件原来的目录”lib64″,拷贝一个libc.so.6文件到这个文件夹中就可以了。

###进入系统目录
chroot /mnt/sysroot
###拷贝文件
cp lib64/libc-2.28.so /lib/libc.so.6     ##因为原来libc.so.6只是libc-2.28.so的软连接,所以直接复制原文件过来就可以了
###重启系统
reboot 

由于系统软件有更改,重启时需要进行安全校验,可能进入系统会花费较长时间,可以更改启动文件来进行设置不检验,启动后再更过来,但是不建议这么做,因为服务器一般启动了很久才会关,有可能有搞忘了改,反正几天时间都花了,多等几分钟也没关系。

参考资料:

https://docs.centos.org/en-US/centos/install-guide/Rescue_Mode/         ###官方资料
https://www.thegeekdiary.com/how-to-boot-into-rescue-mode-or-emergency-mode-through-systemd-in-centos-rhel-7-and-8/                     ###多种进入救援模式的方法
https://www.tecmint.com/recover-or-rescue-corrupted-grub-boot-loader-in-centos-7/   ###CentOS7的救援模式
https://zhuanlan.zhihu.com/p/398478111   ###国内比较详细的介绍救援模式的方法
https://www.golinuxcloud.com/e2fsck-repair-filesystem-in-rescue-mode-ext4/ ###找不到linux系统搜到的解决方法
https://blog.csdn.net/leenhem/article/details/118111370   ###救援模式挂载lvm出错的解决方法

Augustus安装

Augustus作为基因预测必备软件,其源代码安装过程是迄今为止碰到的最难安装的软件,没有之一,现在终于勉强安好了(花了三天)。

  1. 下载最新的augustus版本并解压
wget -c https://github.com/Gaius-Augustus/Augustus/releases/download/v3.4.0/augustus-3.4.0.tar.gz
tar xzvf augustus-3.4.0.tar.gz
cd augustus-3.4.0/

2. 按照README.md的说明安装依赖包,如果是centos系统,安装对应的软件

## Install dependencies

The following dependencies are required for AUGUSTUS:
- For gzip compressed input:
 (set ZIPINPUT = false in [common.mk](common.mk) if this feature is not required or the required libraries are not available)
  - libboost-iostreams-dev
  - zlib1g-dev
- For [comparative AUGUSTUS](docs/README-cgp.md) (multi-species, CGP):
  (set COMPGENEPRED = false in [common.mk](common.mk) if the libraries required by the CGP version are not available. Augustus can then only be run in single-genome mode, which is what most users need.)
  - libgsl-dev
  - libboost-all-dev
  - libsuitesparse-dev
  - liblpsolve55-dev
  - libsqlite3-dev (add SQLITE = false to [common.mk](common.mk) if this feature is not required or the required library is not available)
  - libmysql++-dev (add MYSQL = false to [common.mk](common.mk) if this feature is not required or the required library is not available)
- For compiling bam2hints and filterBam:
  - libbamtools-dev
- For compiling utrrnaseq:
  - libboost-all-dev (version must be >Boost_1_49_0)
- For compiling bam2wig:
  - Follow [these instructions](./auxprogs/bam2wig/README.md). Note that it shouldn't be a problem to compile AUGUSTUS without bam2wig. In practice, you can simply use `bamToWig.py` to accomplish the same task.
- For compiling homgenemapping
  (set BOOST = FALSE in [./auxprogs/homgenemapping/src/Makefile](./auxprogs/homgenemapping/src/Makefile) if the option --printHomologs is not required or the required libraries are not available)
  - libboost-all-dev

3. 由于后面make时一直显示错误“ /usr/bin/ld: cannot find -lmysqlclient ”,尽管mysql和mysql++已经安装好,只能选择“add MYSQL = false to common.mk”了,然后在common.mk文件后面增加suitesparse和htslib库文件的地址,如果不知道库文件的地址在哪里,可以用find或者locate 命令查找suitesparse和htslib。

MYSQL = false
INCLUDE_PATH_SUITESPARSE := -I/usr/include/suitesparse
LIBRARY_PATH_SUITESPARSE := -L/usr/lib64 -Wl,-rpath,/usr/lib64

INCLUDE_PATH_HTSLIB   := -I/usr/local/include/htslib
LIBRARY_PATH_HTSLIB   := -L/usr/local/lib -Wl,-rpath,/usr/local/lib

4. 如果是Centos系统bamtools需要手动安装,其中还需要先安装jsoncpp,bamtools可以安装在当前用户目录,如我的是安装在“~/local/bamtools”这个目录,记住这个路径,后面还要用到。

wget https://github.com/pezmaster31/bamtools/archive/refs/tags/v2.5.2.tar.gz
tar xzvf bamtools-2.5.2.tar.gz
cd bamtools-2.5.2/
yum install jsoncpp-devel.x86_64   #########BamTools also makes use of JsonCpp for certain serialization tasks.
mkdir build
cd build/
mkdir ~/local/bamtools
cmake -DCMAKE_INSTALL_PREFIX=~/local/bamtools ..
make && make install

修改augustus-3.4.0/auxprogs/bam2hints和
augustus-3.4.0/ auxprogs/filterBam/src下的Makefile文件,指明bamtools库文件所在位置。

Now bamtools should have been correctly installed. Next, we need to modify the Makefiles of bam2hints and filterBam to adapt them with our manually installed bamtools.

First, go to the “augustus-3.4.0/auxprogs/bam2hints” directory and make the following changes for the Makefile:

Add:
   BAMTOOLS = ~/local/bamtools

Replace:
   INCLUDES = /usr/include/bamtools
By:
   INCLUDES = $(BAMTOOLS)/include/bamtools

Replace:
   LIBS = -lbamtools -lz
By:
   LIBS = $(BAMTOOLS)/lib64/libbamtools.a -lz

Then, go to the “augustus-3.4.0/auxprogs/filterBam/src” directory and make the following changes for the Makefile:

Replace:
BAMTOOLS = /usr/include/bamtools
By:
BAMTOOLS = ~/local/bamtools

Replace:
INCLUDES = -I$(BAMTOOLS) -Iheaders -I./bamtools
By:
INCLUDES = -I$(BAMTOOLS)/include/bamtools -Iheaders -I./bamtools

Replace:
LIBS = -lbamtools -lz
By:
LIBS = $(BAMTOOLS)/lib64/libbamtools.a -lz

Now, we are finally ready to compile Augustus. Get back to the “augustus-3.4.0” directory and type “make BAMTOOLS=~/local/bamtools”, viola!
make BAMTOOLS=~/local/bamtools

如果出现“bam2wig.c:12:10: fatal error: bgzf.h: No such file or directory” 和 “bam2wig.c:18:17: fatal error: sam.h: No such file or directory”, 使用find或者locate命令查找“bgzf.h” 和 “sam.h” 的位置,然后在 “auxprogs/bam2wig/bam2wig.c”文件中修改这两个文件的位置, 例如:

#include "/usr/local/include/htslib/bgzf.h"
#include "/usr/local/include/htslib/sam.h"

重新运行:

make BAMTOOLS=~/local/bamtools

如果没有再产生错误,恭喜,已经成功安装好了,如果方便后面的使用,可以将需要用到的代码加入环境变量。

export PATH=$PATH:~/soft/augustus-3.4.0/bin:~/soft/augustus-3.4.0/scripts

试着运行一下,查找有没有合适的参考物种:

augustus --species=help

如果有其它错误,可以参考这篇博文

mysql++安装

MySQL++是基于 C++的 对MySQL和MariaDB的再次封装, 它建立在与标准c++库相同的原则之上,使处理数据库如同处理std容器(STL)一样简单。MySQL++还提供了一些工具,可以让您在自己的代码中避免重复的SQL,为这些常见任务提供了本地c++接口。 因此首先需要先安装mysql.

yum install mysql-devel

如果没有root权限,也可以下载源代码包安装。下载mysql++并编译安装:

wget https://tangentsoft.com/mysqlpp/releases/mysql++-3.3.0.tar.gz
 tar xzvf mysql++-3.3.0.tar.gz
 cd mysql++-3.3.0/
 ./configure --prefix=/home/usr/local/installdir --with-mysql=/usr/bin --with-mysql-lib=/usr/lib64/mysql --with-mysql-include=/usr/include/mysql 

make
make install

如果没有管理员权限的话可以安装在用户自己的目录下,通过设置“–prefix=/home/usr/local/installdir”目录,如果配置时出现”
configure: error: The MySQL library cannot be found. “找不到MySQL库,但是mysql已经安装了,那是因为配置程序在固定位置找不到所需要库,可以手动指定mysql库所在位置,如果是用yum安装的可以使用“–with-mysql-lib=/usr/lib64/mysql –with-mysql-include=/usr/include/mysql”指定mysql及库所有的位置,如果不是yum安装的,自己也不知道安装在哪里,可以使用“whereis mysql”查找mysql安装的位置,然后更改为其位置。

由于默认多线程是不开启的,如果需要开启,配置时添加–enable-thread-check这个参数,但是会显示”Didn’t find mysqlclient_r library in “这个错误,找不半天还是没有解决这个错误,最后还是去掉这个参数,舍弃多线程。

如果其它程序需要调用mysql++,但却显示找不到mysql++库,可以运行下面程序:

echo "/usr/local/lib64" > /etc/ld.so.conf
ldconfig
ln -s /usr/local/lib/libmysqlpp.so /usr/lib/libmysqlpp.so 

如果是安装在用户自己的目录下,把“/usr/local/lib64″更改成安装目录的库文件夹,libmysqlpp.so的位置也做相应的修改。

Error loading shared libraries libcrypto.so.1.1

openssh文件损坏,导致连不上网,也运行不了远程连接。连网时出现“Error loading shared libraries libcrypto.so.1.1”,“error while loading shared libraries: libcrypto.so.1.1: cannot open shared object file: No such file or directory”,因为OpenSSL库默认存储在/usr/lib64下,该目录也将包含在搜索路径中。如果OpenSSL是从源代码编译的,那么共享库将安装在/usr/local/lib64下(如果在配置OpenSSL时未使用前缀选项)。这意味着,新安装的库不在搜索路径中,这就是此错误的原因。所以我们需要做的就是,使用下面的命令在搜索路径中包含OpenSSL库。

echo "/usr/local/lib64" > /etc/ld.so.conf.d/openssl.conf
ldconfig

conda环境激活与退出

非根用户在本用户下安装和激活环境并安装conda包:

1、首先初始化shell,我这里选择的是bash。

conda init bash

2、退出当前的shell,重新打开shell,然后激活选择的环境,如admixture。

conda activate admixture

3、退出激活的环境

conda deactivate admixture

4、更新conda

conda update conda
5、增加conda源
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
conda config --set show_channel_urls yes
conda config --show-sources

R语言保存PDF不能显示中文文字

今天在使用pheatmap画图时,发现图片如果保存为图片形式(png, jpeg)时,中文能正常显示,如果保存为矢量图PDF时,中文的字都被点代替了,不能正常显示,查找了好久,终于找到解决办法 了,就是在pdf函数中指定中文字体,如pdf(“heatmap.pdf”, family = “GB1”),具体情况可以参考这篇文章

linux挂载移动硬盘

挂载移动硬盘可以使用mount命令,注意需要root权限,先使用fdisk -l查看插入的硬盘名称,移动硬盘一般在最后几行,然后使用mount命令挂载。

fdisk -l
mount /dev/sdc1 /mnt/

卸载硬盘使用unmount命令,如果显示busy,就使用-f参数强行卸载。

umount -f /mnt

如果还是不行的话,可能是其它用户正在挂载的目录里面,或者root用户正在挂载的目录里面,退出挂载的目录,然后使用umount命令就可以了。

利用primer3批量设计引物

1、Primer3的下载与安装

primer3官网上下载相应版本的程序,解压后安装,然后检测是否有安装错误。例如安装2.6.1版本:

wget https://github.com/primer3-org/primer3/archive/refs/tags/v2.6.1.tar.gz
tar xzvf primer3-2.6.1.tar.gz
cd primer3-2.6.1/src
make
make test

安装好之后只需要调用src文件夹中的primer3_core程序就可以了,可以拷贝到其它的地方使用。

primer3的各参数说明可以参考官方文档,中文的可以参考这篇博客

2、模板的准备

将模板序列单独放在一个文件,如果是fasta格式的可以命名为fasta格式的代码读取文件,如果是tsv格式的(第一列为序列id,第二列为模板序列),使用tsv格式对应的代码读取文件。然后用下面代码进行批量设计。如果对引物条件不敏感,可以在参数中加入这个参数PRIMER_PICK_ANYWAY=1“,如果想获得多对引物可以修改这个参数”PRIMER_NUM_RETURN=1“。其它参数也可以根据需要修改或者添加。

#!/usr/bin/perl
use strict;
use warnings;

my $primer3_core = "./primer3_core";
my $Seq_file = "./input_file";
my $primer3out_file = "./primer3out.txt";

############Change the parameter if need #######
my $primer3input = <<SET;
PRIMER_TASK=generic
PRIMER_PICK_LEFT_PRIMER=1
PRIMER_PICK_INTERNAL_OLIGO=0
PRIMER_PICK_RIGHT_PRIMER=1
PRIMER_PRODUCT_SIZE_RANGE=75-100
PRIMER_EXPLAIN_FLAG=1
PRIMER_FIRST_BASE_INDEX=1
PRIMER_LIBERAL_BASE=1
SEQUENCE_FORCE_LEFT_END=41
PRIMER_NUM_RETURN=1
PRIMER_OPT_SIZE=20
PRIMER_MIN_SIZE=18
PRIMER_MAX_SIZE=25
PRIMER_MIN_GC=30.0
PRIMER_MAX_GC=70.0
PRIMER_MIN_TM=58.0
PRIMER_OPT_TM=60.0
PRIMER_MAX_TM=62.0
=
SET

open(F, $Seq_file) or die "Can not open the flankingSeq file $!\n";
open(POUT, ">$primer3out_file");
my $print_out_head = join("\t", ("primer_id", "Foward", "Reverse"));
print POUT $print_out_head."\n";

my %id2seq;
my $id="";
my $seq="";

############if the input file is the fasta format##################
while(<F>){
	if(/^>(\S+)/){
		if($id){
			$id2seq{$id}=$seq;
			$seq="";
		}
		$id=$1;
	}else{
		s/\s+$//;
		$seq.=$_;
	}
	if(eof){
		$id2seq{$id}=$seq;
	}
}

############if the input file is the tsv format, use this code################
#while(<F>){
#	s/\s+$//;
#	($id, $seq)=split/\t/;
#	$id2seq{$id}=$seq;
#}		
		
foreach my $primer_id(keys %id2seq){
	my (@primer_left, @primer_right)=&primerPick($primer_id, $id2seq{$primer_id});
	my $i=0;
	while($i<=$#primer_left){
		print POUT $primer_id."\t".$primer_left[$i]."\t". $primer_right[$i]."\n" if($primer_left[$i] and $primer_right[$i]);
	}
}
	
close(POUT);
system("rm ./primer3input.txt");


sub primerPick{
	my ($snp_id, $template)=@_;
	my $attachmentSet = <<ASET;
SEQUENCE_ID=$snp_id
SEQUENCE_TEMPLATE=$template
ASET

	my $primer3set=$attachmentSet.$primer3input;
	open(OUT, ">./primer3input.txt");
	print OUT $primer3set;
	close(OUT);	
	
	my $primer3output = `$primer3_core --default_version=2 --io_version=4 --strict_tags  <./primer3input.txt `;
	my @primer_left="";
	if($primer3output=~/PRIMER_LEFT_(\d+)_SEQUENCE=(\w+)/g){
		$primer_left[$1]=$2;
	}
	my @primer_right="";
	if($primer3output=~/PRIMER_RIGHT_(\d+)_SEQUENCE=(\w+)/g){
		$primer_right[$1]=$2;
	}
	
	return @primer_left,@primer_right;
}

如果只是检测设计的引物是否满足条件,可以引入以下函数修改对应的参数。

sub checkPrimer{
	my ($primer_id, $primer_left, $primer_right, $template)=@_;
	my $primer3set=$primer3input;
	$primer3set=~s/PRIMER_TASK=generic/PRIMER_TASK=check_primers/;
	$primer3set=~s/PRIMER_PICK_LEFT_PRIMER=1/PRIMER_PICK_LEFT_PRIMER=0/;
	$primer3set=~s/PRIMER_PICK_RIGHT_PRIMER=1/PRIMER_PICK_RIGHT_PRIMER=0/;
	my $attachmentSet = <<ASET;
SEQUENCE_ID=$primer_id
SEQUENCE_TEMPLATE=$template
SEQUENCE_PRIMER=$primer_left
SEQUENCE_PRIMER_REVCOMP=$primer_right
ASET
	$primer3set = $attachmentSet.$primer3set;
	open(OUT, ">./primer3input.txt");
	print OUT $primer3set;
	close(OUT);
	my $primer3out = `$primer3_core --default_version=2 --io_version=4 --strict_tags  <./primer3input.txt `;

	if($primer3out=~/PRIMER_PAIR_EXPLAIN=considered 1, ok 1/){
		return 1;
	}else{
		return 0;
	}
}

perl删除字符串中的重复字符

在设计KASP引物时,需要知道双等位基因型对应的碱基,这就需要从GT中却除重复的基因型,可以参考下面的代码:

#!/usr/bin/perl
use strict;
use warnings;
my $string="A/C	A/C	A/C	A/C	A/C	A/A	A/C	A/A	A/C	A/C	A/C	A/C	A/A	A/C	A/C	A/A";
$string=~s/\s+//g;
while($string =~ s/((.).*)\2+/$1/g) {};
print $string."\n";