shell - 自解压 tar 存档(shell 脚本)

标签 shell unix scripting tar self-extracting

我试图编写一个 shell 脚本来创建另一个以 base64 压缩和编码的自解压 tar 存档。我不知道从这里到哪里去,而且在 shell 脚本方面几乎没有经验。

因为这个脚本创建了压缩和编码的 tar 存档,但是当我尝试从终端运行 ./tarName 时,自解压不起作用。任何建议表示赞赏

#!/bin/sh
tarName=$1;

if [ -e $tarName.tar.gz ] 

    then /bin/echo "$tarName already exists" 
    exit 0
fi

shift;
for files;
do
    tar -czvf tmpTarBall.tar.gz $files;
done

echo "#!/bin/sh" >> $tarName.tar.gz;
echo "base64 -d $tarName.tar.gz"  >> $tarName.tar.gz;
echo "tar -xzvf $tarName.tar.gz" >> $tarName.tar.gz;
chmod +x ./$tarName.tar.gz;

base64 tmpTarBall.tar.gz >> $tarName.tar.gz;
rm tmpTarBall.tar.gz;

------------更新

环顾四周,这就是我现在所拥有的,但仍然不起作用。谁能给我解释一下为什么?

#!/bin/sh
tarName=$1;

if [ -e $tarName.tar.gz ] 

    then /bin/echo "$tarName already exists" 
    exit 0
fi

shift;
for files;
do
    tar -czvf tmpTarBall.tar.gz $files;
done

cat > extract.sh;
echo "#!/bin/sh" >> extract.sh;
echo "sed '0,/^#TARBALL#$/d' $0 | $tarName.tar.gz | base64 -d | tar -xzv; exit 0" >> extract.sh;
echo "#TARBALL#" >> extract.sh;

cat extract.sh tmpTarBall.tar.gz > $tarName.tar.gz;
chmod +x ./$tarName.tar.gz;

rm extract.sh tmpTarBall.tar.gz;

当我尝试运行 tarName.tar.gz 时出现错误: ./tarName.tar.gz: 2: ./tarName.tar.gz: tarName.tar.gz: 未找到 gzip: stdin: 文件意外结束 tar: child 返回​​状态 1 tar: 错误不可恢复:现在退出

最佳答案

期望的输出

大体上,您要生成的脚本应该如下所示:

base64 -d <<'EOF' | tar -xzf -
…base-64 encoded data…
EOF

base64 命令对其标准输入进行解码,该标准输入作为此处文档提供,以仅包含 EOF 的行结尾。输出被写入 tar,带有从标准输入中提取 gzip 数据的选项。

最小脚本

因此,一个最小的生成器脚本如下所示:

echo "base64 -d <<'EOF' | tar -czf -"
tar -czf - "$@" | base64 -w 72
echo "EOF"

这与 base64 相呼应…… | tar … 行,然后使用 tar 在标准输出上生成一个压缩的 tar 文件,其中包含在命令行中命名的文件或目录,输出通过管道传输到 GNU coreutils 版本的 base64 以及指定输出行宽度应为 72 个字符(加上换行符)的选项。这一切之后都是 EOF 以标记此处文档的结尾。

您可以将 shebang 行 (#!/bin/sh) 添加到一个或两个脚本中。无需选择更具体的 shell ;这仅使用核心 shell 脚本构造,这些构造可以追溯到昔日的日子——在 POSIX 还没有出现在任何人眼中之前。

可能的并发症

可能的并发症包括对 Mac OS X base64 的支持,它具有如下用法消息:

Usage:  base64 [-dhvD] [-b num] [-i in_file] [-o out_file]
  -h, --help     display this message
  -D, --decode   decodes input
  -b, --break    break encoded string into num character lines
  -i, --input    input file (default: "-" for stdin)
  -o, --output   output file (default: "-" for stdout)

-v 选项和 -d 选项都会生成 base64: invalid option --v (对于适当的字母),加上用法。似乎没有办法从中获取版本信息。但是,当您请求 base64 --version 时,GNU 的 base64 会生成一条有用的消息。标准输出的第一行将包含如下内容:

base64 (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Simon Josefsson.

这是写入标准输出。因此,您可以自动检测您是否拥有 GNU base64 并相应地进行调整。您需要在生成器脚本中进行一个测试,并在生成的脚本中复制一份测试。这绝对是一个更精致的程序。

关于shell - 自解压 tar 存档(shell 脚本),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35922782/

相关文章:

macos - 在终端中打印文件的特定行

unix - LSof生存指南

用于运行 C 程序的 Python 脚本

linux - 两个文件与 while .sh 的比较

linux - 通过python进行glob函数后的文件编辑

linux - 如何绕过 Linux "Too Many Arguments"限制

linux - shell脚本移动和复制

linux - 需要 shell 脚本来提取以模式开头的子字符串

mysql - 从 shell 打印 mysql ROW_COUNT() 结果

linux - 在目录中查找重复的文件名(不指定确切的文件名)