linux下安装JDK的时候,Sun公司为JDK6的linux版本提供了一个shell的安装包,用起来特别的好用,基本上和在Windows下安装软件没什么两样,shell文件执行之后,几乎一切都系都设置好了,不用我们自己再动手设置PATH和JAVA_HOME,可是一个shell文件中是如何把二进制代码包含进来的呢?

再例如淘宝为linux开发的淘宝插件,其实也是一个shell文件,但是执行这个shell文件之后,会安装很多二进制的东西,同样的问题,Shell只是文本文件,其中的二进制是怎么来包含进来的呢?

从文本文件转换出可执行文件,通过编译器把源程序编程成可执行程序当然是可以的,但是前面提到的哪两种情况都不是这样做的。原因有两个,第一对于大的项目来说,编译需要的时间比较长,环境比较复杂;第二,更加重要的是,这样做其实和从源代码编译程序没什么两样,对于不想让用户看到自己的源码的商业软件来说,这显然是不可取的。

我们看看一般的程序是如何发布他们的二进制包的。

一般的程序,无非是把二进制和必要的文档压缩到一个压缩文件中,然后通过README文档的解释程序的运行依赖什么样的假设,然后,你就可以把程序自行的移动到你想移动的地方去了。

很多时候,我们把程序放到任何地方都是可以运行的,但是程序可以运行,并不是说我们已经完成了程序的安装,举个例子来说,如果我们解压JDK的二进制包之后,直接把程序移动到一个地方,然后把对应的bin目录添加到PATH中就可以执行JDK提供的一系列工具了。

但是如果我们安装其他的依赖与JDK的程序的时候,比如TOMCAT,那么就会有问题。因为我们只是在PATH中加入了JDK的bin目录而没有制定JAVA_HOME这个环境变量,所以TOMCAT很可能会不能运行。

再比如我们使用man命令来查看一个程序的手册,一般情况下二进制包中也会包含man文档的,但是如果我们只是把解压的二进制包的路径添加到了PATH中,还不能在man中找到对应的文档。

也正是因为这样的原因吧,所以很多的二进制包的发布是使用deb或者rpm包来发布。安装的时候少了很多的烦恼。要制做deb或者rpm包当然是需要学习成本的,而且deb和rpm也只能在对应的linux发行版中使用,如果想要为所有的Linux发行版都提供一个安装文件,那么使用shell文件来做无疑是最好的办法。

Shell的学习成本低,而且对linux平台来说有通用,那么是如何做到的呢?

想想我们在手动安装的情形,无非是把压缩的二进制包解压,移动到特定的目录下,在PATH变量中添加二进制包的可执行文件的路径等等工作。首先我们把二进制包压缩文件和shell文件分开。这样一来,shell中只要完成解压,然后把解压后的目录移动到指定的目录中去,设置各种各样的环境变量然后就完成了工作了。

但是我们在如何把压缩文件和这个shell解压之后要执行的命令的shell文件一起放到一个shell文件中呢?

要做到这一点,首先这个shell文件中,要有可以解压的二进制内容,其次,这个shell要做的工作就是,把二进制内容,解压,然后把原来手动做的工作在这个shell中用命令完成。再用shell写个脚本完成一些手动完成的工作,这个任务比较容易,所以制作shell安装包的难点就是如何在其中包含二进制内容了。

如何在一个文本文件中记录二进制的内容呢?

这个问题早就被解决了。答案就是使用Base64编码。在linux下就有base64 这个命令程序就是来做这个工作的。base64可以把文件进行base64的编码,输出的标准输出中去或者把文件中的Base64编码的内容解码。命令base64除了可以对文件的内容做Base64的编解码外,也可以对标准输入中的数据进行Base64编辑码。

有了这些预备的知识,那么我们就可以看看具体的如何来做shell的二进制发布包了。

首先假设我们要发布的文件都放在名为test的当前文档中。

  1. 把要发布的文件打包

    1. tar zcf test.tar ./test
  2. 对打好的二进制包做Base64编码

    1. base64 ./test.tar > test_base64.txt
  3. 准备安装文件的shell文件

    1. test_base64="";#test_base64中的所有内容
    2. echo $test_base64|base64 -d >test.tar
    3. tar zxf test.tar
    4. rm test.tar
    5. # 其他的安装代码

写到这里,我们已经把道理将明白了。但是可不可以写一个shell程序,专门来生成这样的发布包软件呢?当然可以。下面是我写的这个打包程序的源代码。

  1. function mkpackage(){
  2. target_dir=$1
  3. felow_install_shell_command_file=$2
  4. echo "tar -zcf ._test_dir.tar.gz $target_dir"
  5. tar -zcf ._test_dir.tar.gz $target_dir
  6. base64 ._test_dir.tar.gz >._base64
  7. rm ._test_dir.tar.gz
  8. printf "test_base64=\"">install.sh
  9. while IFS='' read -r line || [[ -n "$line" ]]; do
  10. printf "$line\\" >>install.sh
  11. printf "n" >>install.sh
  12. done <./._base64
  13. rm ._base64
  14. echo "\"" >>install.sh
  15. echo 'printf $test_base64|base64 -d >._temp.tar.gz;'>>install.sh
  16. echo 'tar zxf ._temp.tar.gz' >> install.sh
  17. echo 'rm ._temp.tar.gz' >>install.sh
  18. if [[ -e $fellow_install_shell_command_file ]]; then
  19. cat $fellow_install_shell_command_file >>install.sh
  20. fi
  21. chmod +x install.sh
  22. }
  23. function usage(){
  24. echo "usage:"
  25. echo " $1 test_dir [the_command.sh]"
  26. }
  27. if [[ $# != 0 ]]
  28. then
  29. mkpackage $1 $2
  30. else
  31. usage $0
  32. fi

这个程序接受两个输入参数,第一个表示要打的程序包目录,第二个是解压后,安装动作的shell脚本文件。最后这个程序生成一个名为 install.sh 的文件。执行 install.sh 之后,会首先得到加压的程序包内容,然后执行第二个参数指定的 shell 脚本的内容。这样我们就做了用Shell发布二进制文件的一个打包程序。当然了,在最后发布之前,还需要把这个shell压缩一下。以便消除因为Base64编码而带来的文件长度的变大的影响。

本文来自云栖社区合作伙伴“Linux中国”,原文发布日期:2015-09-25

如何用 Bash 创建一个二进制发布包相关推荐

  1. Linux安装jdk详细步骤,二进制发布包安装!

    目录 前言.linux软件安装方式 ==>二进制发布包安装: ==>rpm安装: ==>yum安装: ==>源码编译安装: 一.检查Linux系统是否带有jdk并删除 二.官网 ...

  2. ITK:创建一个二进制球结构元素

    ITK:创建一个二进制球结构元素 内容提要 C++实现代码 内容提要 创建一个椭圆形结构元素 C++实现代码 #include "itkBinaryBallStructuringElemen ...

  3. vscode如何创建一个go项目_如何用手机创建一个网站

    如何用手机创建网站?其实正确的说法是如何创建一个手机网站才对,因为很难用手机去制作网站,很不方便.一般是用电脑模拟手机去建网站. 我们知道现在很多人上网都是通过手机上网,所以我们自己建网站时,也要学会 ...

  4. 如何用python创建一个下载网站-使用Python下载文件的简单示例

    Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发. 学习如何使用各种Python模块从web下载文件 在本教程中,你将学习如何使用不同的Python模块从we ...

  5. Maven如何用Eclipse创建一个Maven项目【笔记自用】

    1.Maven的安装与设置环境变量 想要创建一个Maven项目需要先安装Maven,并且设置好环境变量 去下载Maven 设置环境变量 新建变量MAVEN_HOME,值为Maven的目录X:\XXX\ ...

  6. python创建函数如何调用字典对象_我不知道如何用Python创建一个调用我函数的字典...

    除了不传递值并尝试调用dict之外,您正在计算列表完全填充之前的平均值,在代码中,当您完成附加后,在循环外计算平均值:def posNumAvg(values): pos = [] # average ...

  7. 如何用Eclipse创建一个JavaSwing的项目

    创建之前必须先给开发工具安装WindowBuilder插件(安装方法可自行百度) 方式一: 创建项目 new--other--WindowBuilder--SWT Designer----SWT/JF ...

  8. ae制作小球轨迹运动_AE教程AE特效:教你如何用AE创建一个弹跳运动的小球特效...

    这篇教程是通过AE制作一个弹跳运动的小球,整个教程比较简单,但是会带给你惊喜,教程主要分2个部分完成,感兴趣的同学们一起来学习一下吧. 操作步骤: 这个教程分为两个部分. 第一,怎么用AE做出这样的一 ...

  9. java 如何创建一个数组_如何用Java创建一个数组?

    在Java中,可以使用new关键字像对象一样创建数组.使用new关键字在Java中创建数组的语法-type[] reference = new type[10]; 哪里,type是数组元素的数据类型. ...

最新文章

  1. Redis 数据库结构设计
  2. Android常见面试题(一)
  3. java添加删除用户信息泄露_java删除用户404错误!!神奇!增改查都没问题啊!!...
  4. [EF Core]数据迁移(二)
  5. docker history 27f1068ca9da --no-trunc查看镜像dockerfile内容
  6. Eclipse使用Android2.3和3.0的SDK
  7. Linux而不必进入password登陆自己主动sshserver方法
  8. vue指令-单向和双向绑定
  9. convolutional layer 源代码
  10. 解决Maven打包(编译)慢的问题
  11. SQL Server检索存储过程的结果集
  12. 作者:林立,华中科技大学计算机科学与技术学院讲师。
  13. html5 getchildren,jquery children() find()用法
  14. iis10 HTTP 错误 500.19 - Internal Server Error
  15. 计算机组成原理第七章测试题,计算机组成原理 课堂练习-第七章
  16. mybatis注解开发-动态SQL
  17. SQL Server数据库出现恢复挂起时的解决办法
  18. java集成极光推送
  19. cron表达式每隔1小时一次_cron 每隔1小时50分钟_cron每小时执行一次
  20. mysql schemata 链接_MYSQL联合注入

热门文章

  1. php mysql 命令行模式_PHP 的命令行模式
  2. python读写excel模块pandas_python3 基于pandas读写Excel
  3. mysql odbc连接池_Java Mysql连接池配置和案例分析--超时异常和处理
  4. 算数计算机在线应用,数学计算器
  5. java中replaceall用法_Java中String的ReplaceAll使用小结
  6. viturbox网卡驱动_VirtualBox Host
  7. java生日验证_Java验证身份证号码是否有效
  8. 目前用到的两个分页存储过程:
  9. 只能输入数字或含两位小数的正则
  10. 只精通python_七步精通Python机器学习--转载