您的位置:首页 > 运维架构 > Linux

换一种方式创建Linux下的自解压文件

2015-08-07 15:33 495 查看
看到Windows上的自解压程序双击后就自动将数据文件提取出来,很是便捷,那么如何在Linux创建自解压文件呢?方法自然是有很多的,有一天,小明又滚出去了,这回他没有想着怎样再回到教室,他很好奇,于是他搜索了一下关于如何在Linux下创建自解压文件的问题,他发现所有结果貌似都非常统一,用了tail的特性,而且用的是tail以行的方式输出。额,天下文章……,他表示深以为然。他跟我说了此事,我回他:“小明,GCQ!”

在本文中,笔者准备了2种方法创建自解压文件,其一,也是利用tail的特性,但是不使用行,而使用字节输出。其二,用C语言将zip粉饰一下门面。
tail命令有一个参数:c,可以输出最后给定数量的字节,如果应用于创建自解压文件,相比较通过行输出,笔者的强迫症使笔者觉得这样比较顺眼一些。wc命令也有一个参数:c,可以计算文件的字节数,配合awk加工一下输出便可提取出字节大小。大致思路是这样:通过创建一个含有有解压命令的shell脚本,与一个压缩包合并为一个文件,脚本中实现从自身指定位置中提取压缩包并解压。于是有了以下用于创建这个怪物的shell脚本:

#!/bin/bash
#
#make a self-decompress file
#version: 0.1
#
#Create by Daisuchuan on Ubuntu Linux. Mar.26,2015
if [ $# != 1 ];then #判断参数数量
echo "$0:Only support one argument." #只支持1个参数
echo "USAGE: $0 file" #打印帮助信息
exit 1 #异常退出
fi
tar -czf .data.tar.gz $1 #压缩文件,不加v选项
DATA_SIZE=`wc -c .data.tar.gz|awk '{print $1}'` #取压缩文件大小
echo "#!/bin/bash">$1.run #开始制作shell文件头
echo "tail -c $DATA_SIZE \$0 >>.data.tar.gz">>$1.run #将最后的数据字节输出
echo "tar -xvzf .data.tar.gz">>$1.run #解压数据,加v选项
echo "rm .data.tar.gz">>$1.run #删除临时文件
echo "echo 'has been decompressed.'">>$1.run #打印提示
echo "exit 0">>$1.run
cat .data.tar.gz >>$1.run #数据文件加到shell尾
chmod +x $1.run #添加可执行权限
rm .data.tar.gz #删除临时文件
echo "$1.run has been created." #打印提示信息
exit 0

那么另一种思路,我们打算使用C语言(这是件扯淡的事情,因为笔者没有通过C语言实现任何压缩算法,仅仅调用了zip命令而已),笔者只有这样几个需要:1.可以自解压。2.不要用shell脚本。3.带点加密功能。4.即使没有Linux系统,或者该系统位元与bin文件不符,也有解压方法。

那么实现的思路也就清晰了,zip有一个特性,它自己可以忽略文件头部额外的非压缩包数据,它还可以支持密码,于是笔者有了法子:用C语言创建一个调用zip命令解压自身的可执行文件,再将此文件尾部追加zip压缩包。

照着这个思路,首先要写源文件,然后编译好,然后压缩一个需要的数据文件,再与之合并,笔者想把这些工作一并交给程序,自己就想只执行一个程序,啪~蹦出来一个可以自解压的文件,像之前的那个方法一样便捷,小明说,之前是shell脚本,一切都可以帮你配置。笔者已经不想再用shell脚本了,通过C吧。

于是让C自己编写用于作为文件头部程序的源文件,自己调用gcc编译为可执行文件,自己调用zip压缩并加密一个文件,自己调用cat合并文件。(小明:好多系统命令调用,这个看起来怎么。。。像shell)笔者只编译这一个勤劳的C Source File即可。

小明说这个看来看去,功能近似shell,笔者说:归根究底,这生成一个二进制可执行文件,可作为一个命令,此命令又可以自己生成另外一个二进制可执行文件,此文件含有压缩包。

小明:给这个命令取个名字吧

笔者:随便

小明:crauz ......create auto unzip !

笔者:随便

小明:即然这样,那把makefile和readme也写下,至少像个完整的小麻雀。

笔者:......

小明:你说的加密是zip密码?C源文件能不能加密?

笔者:源文件加密,你怎么看?

小明:混乱C代码,自然加密,可读可编译。

笔者:......

于是,有了以下几个文件:
README:

=======================================================
Create Autounzip Files on Linux (crauz) Version 0.2
=======================================================

Copyright (C) 2015 Dai Suchuan
天舞飞星 / saintdsc@163.com ip6tables@qq.com
-------------------------------------------------------
Files in this distribution:

README this
makefile GNU makefile
crauz.c source file
Building and installing:
-------------------------------------------------------
tar -xvf crauz-VERSION.tar.gz
cd crauz-VERSION
#you need gcc or any C compiler (edit Makefile CC=YOUR_C_COMPILER)
make
#you must be root in next step:
make install

-------------------------------------------------------
#Perhaps the password is "aGFwcHluZXd5ZWFyCg==",if you get a file created by old versions.(Just for debugging)

makefile:
#FILE:makefile
#create autounzip
CC = gcc
OBJs = crauz.o
crauz:$(OBJs)
@echo create crauz...
@$(CC) -o crauz $(OBJs)
$(OBJs):crauz.c
@echo create $(OBJs)...
@$(CC) -c crauz.c
install:
@echo installing...
@mv crauz /usr/local/bin/crauz
uninstall:
@echo uninstalling...
@rm /usr/local/bin/crauz
.PHONY:clean
clean:
@echo clean...
@rm crauz $(OBJs)
crauz.c:
/*Create autounzip file. Designed by Daisuchuan. Mar.26,2015. Ubuntu 12.04 LTS*/
#define _ 1 //1
#define _o_ for
#define __oo__ return
#define o_o(__) system(__)
#define ___o(_,__) fopen(_,__)
#define o___(o__o) fclose(o__o)
#define o__o(o_o,__) strcat(o_o,__)
#define _____________(____) printf(____) //13
#define ____o(o_o,o__o,o___o) fprintf(o_o,o__o,o___o)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int ____; //4
typedef char __; //2
typedef FILE _______; //7
__* _________ =/*9*/
"I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KaW50IG1haW4oaW50IGFyZ2Ms\nIGNoYXIgKiphcmd2KQp7CiAgICAgICAgY2hhciogbmFtZT0oY2hhciopbWFsbG9jKHNpemVvZihj\naGFyKSk7CiAgICAgICAgc3ByaW50ZihuYW1lLCJ1bnppcCAtUCBWR0ZzYXlCcGN5QmphR1ZoY0M1\nVGFHOTNJRzFsSUhSb1pTQmpiMlJsSVFvPSAgJXMiLGFyZ3ZbMF0pOwoJc3lzdGVtKG5hbWUpOwoJ\nc3lzdGVtKCJjbGVhciIpOwoJcHJpbnRmKCJhdXRvdW56aXAgZmlsZXMgaGF2ZSBiZWVuIHVuemlw\nZWQuXG4iKTsKCXJldHVybiAwOwp9Cg==";
____ _____(____ ________/*argc8*/, __ **o_o_o_o/*argv*/) //5
{
__ ____________[_<<_<<_<<_<<_<<_<<_<<_] ="zip -P VGFsayBpcyBjaGVhcC5TaG93IG1lIHRoZSBjb2RlIQo= .__";//12args
__* __________ = " ";//10
____ ___; //3
_______ *___________=___o("./.______________","w+");//11&14
____o(___________,"%s",_________);
o___(___________);//source
o_o("base64 -d .______________>.______");
_o_ (___=_;___<=________-_;___++)
{
o__o(____________,__________);//blank to args
o__o(____________,o_o_o_o[___]);
}
o_o(____________);//args
o_o("base64 -d .______________>.______");
o_o("gcc -x 'c' ./.______ -o ._____");
o_o("cat ./._____ ./.__ > ./autounzip.run");
o_o("chmod +x ./autounzip.run");
o_o("rm ./.______ ./.__ ./._____ ./.______________");
__oo__ _>>_;
}
____ ______()//6
{
_____________("crauz V0.2...............by DaiSuchuan\n_________________________________________\nAuto-unzip file have been created.You can execute it like an application.\nFor example,type this in terminal:\n ./autounzip.run\n");
__oo__ _>>_;
}
____ main(____ argc, __ **argv)
{
_____(argc, argv);
______();
__oo__ _>>_;
}

//source.c 6 a.zip 2 a.bin 5
//"Talk is cheap.Show me the code!"
小明:额,虽然是可以编译的,但总感觉是填空题......

笔者:......

小明:那别的环境怎么解压?

笔者:改扩展名为zip,输入密码解压,头部数据会被忽略......
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息