1. debootstrap
如果你和我一样使用debian,那么你可以使用
debootstrap
来搭建一个真实的环境。(ubuntu似乎也能用,自行了解吧)
# 第一个参数是发现版本,用的testing版本
# 第二个参数./testing是下载保存位置
# 第三个参数是镜像源,用国内源,不然很慢。也可以用本地仓库。
sudo debootstrap testing ./testing https://mirrors.tuna.tsinghua.edu.cn/debian
sudo chroot ./testing # 切换到虚拟环境
debootstrap
会制作一份最小化的debian系统,可以是stable、unstable、testing等。
这个最小化系统可以用来作为
chroot
的绝佳环境,然后就和使用普通系统一样了,安装开发包、编译第三方库都很方便。
什么docker、虚拟机,统统都是辣鸡。
为了安全,防止误操作,最好加上指示:
export PS1="(chroot) \u@\h:\w $ "
- PS1就是指示shell的变量
-
(chroot)
是我们加的前缀,可以自己改 -
\u
是用户名 -
\h
是主机名 -
\w
是当前工作目录
原来如果是:
root@debian:/ $
设置后就变为:
(chroot) root@debian:/ $
chroot不是100%安全的,还是稍微注意下,不要做太危险的行为
,测试用足够了。
2. 手动复刻简单的运行环境
这里我新建一个空的
tmp
来演示。
使用
chroot
命令需要root权限,当我们直接
chroot .
的时候,报错了。
sixqaq@debian:~/tmp$ pwd
/home/sixqaq/tmp
sixqaq@debian:~/tmp$ sudo chroot .
chroot: failed to run command ‘/bin/bash’: No such file or directory
sixqaq@debian:~/tmp$
应该是需要
bin
,
lib
这些目录的。
了解过的使用方法有两种,一种是
mount
一份系统的,这种常用于系统修复和改动。
另一种是用于测试。
如果用于测试,那么我们就不能直接用系统的,而是拷贝一份。
我看了下自己的系统:
/lib
有8G;
bin
也有1G了;
/etc
和
/lib64
都比较小,忽略不计。
全部拷贝有点太大了,我们只需要拷贝自己需要的就行了。
开始创建环境
mkdir tmp && cd tmp # 把tmp当成根目录来演示
mkdir bin lib lib64 # 创建这三个需要的目录
cp /bin/{bash,ls} ./bin # 拷贝我们需要的命令,这里bash是必须的
只有命令是用不了的,缺少动态链接库,用
ldd
看一下:
$ ldd /bin/bash
linux-vdso.so.1 (0x00007fff29ffd000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fdf432c7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf430e6000)
/lib64/ld-linux-x86-64.so.2 (0x00007fdf4345d000)
可以手动复制,但是太慢了。
注意到都是
/lib
或者
/lib64
开头的,我们用
grep
提取:
$ ldd /bin/bash | grep -E -o '/lib.*\.[0-9]'
/lib/x86_64-linux-gnu/libtinfo.so.6
/lib/x86_64-linux-gnu/libc.so.6
/lib64/ld-linux-x86-64.so.2
-E
是使用POSIX正则表达式扩展语法,
-o
(
--only-matching
) 只打印匹配的部分。
所以
/bin/bash
的链接库的拷贝就这样:
cp -v --parents `ldd /bin/bash | grep -E -o '/lib.*\.[0-9]'` .
--parents
将自动创建需要的目录层级。
.
是当前目录
tmp
。
对于ls命令同理。
脚本
把环境创建的写成一个脚本
inti.sh
:
#!/bin/bash
chr=.
list='bash ls cat echo grep sed cp rm'
for cmd in $list
do
cp -v --parents /bin/$cmd $chr
cp -v --parents `ldd /bin/$cmd | egrep -o '/lib.*\.[0-9]'` $chr
done
这样只用执行脚本,就会自动在当前目录创建
bin
,
lib
,
lib64
,并且拷贝相关的链接库。
cd tmp && rm -rf *
bash init.sh
然后环境就好了,我们写一个hello world:
#include <stdio.h>
int main(void)
{
printf("Hello world\n");
return 0;
}
在系统环境下用gcc编译:
gcc main.c -o main
然后进入
chroot
:
sudo chroot .
执行main:
$ main
Hello world
不过看起来也只能跑个程序了,稍微复杂的功能,比如vi/vim、clear命令,都无法通过上面的方法迁移进去。
而且它们会有各种依赖,配置文件什么的,想完全复现,找个系统复制一份吧。。。