我试图写一个shell脚本,创建另一个自解压的tar存档,压缩和编码在base64。我不知道从这里去哪里,几乎没有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:not found gzip:stdin:unexpected end of file tar:Child returned status 1 tar:Error is not recoverable:exiting now
3条答案
按热度按时间nzrxty8p1#
期望输出
概括地说,您要生成的脚本应该如下所示:
字符串
base64
命令解码它的标准输入,它作为一个here文档提供,以一个只包含EOF
的行结束。输出被写入tar
,并带有从标准输入中提取gzip数据的选项。最小脚本
所以,一个最小的生成器脚本看起来像这样:
型
这将重复
base64 … | tar …
行,然后使用tar
在标准输出上生成一个压缩的tar文件,其中包含命令行上指定的文件或目录,输出通过管道传输到GNU coreutils版本的base64
,并带有指定输出行宽度为72个字符的选项(加上新行)。这后面都跟有EOF
来标记here文档的结束。你可以在两个脚本中的任何一个中添加shebang行(
#!/bin/sh
)。不需要选择一个更具体的shell;这只使用了可以追溯到过去的核心shell脚本结构-在POSIX在任何人眼中都是一线生机之前。可能的并发症
可能的复杂性包括对Mac OS X
base64
的支持,其使用信息如下:型
-v
选项和-d
选项都生成base64: invalid option -- v
(对应于相应的字母),以及用法。似乎没有办法从中获取版本信息。然而,当您请求base64 --version
时,GNU的base64
确实会生成一条有用的消息。标准输出的第一行将包含如下内容:型
这是写入标准输出的。所以,你可以自动检测你是否有GNU
base64
并相应地调整。你需要在生成器脚本中有一个测试,并在生成的脚本中有一个测试的副本。这绝对是一个更精致的程序。vshtjzan2#
有必要自己做这件事吗?有一个名为makeself的现有工具可以为你做这件事。如果你需要自己写这件事,这里有一些想法:
您的输出文件是一个归档文件,其前面粘有一个shell脚本。提取过程通过
base64
和tar
运行 * 整个 * 输出文件,而不仅仅是归档文件。base64
调用将脚本部分变成垃圾,然后混淆tar
。您需要做的是添加一些代码,将脚本与归档文件分开,然后只在归档文件部分运行其余的命令。一种可能的方法是调整提取脚本,如下所示:字符串
确保在标记文本之后的脚本部分中除了换行符之外没有任何内容(这个网站上的标记并不显示)。这样,您就可以使用
grep
来查找包含标记的行号,然后使用tail
剥离这些行号。剩下的将是存档部分,这是正常处理的其余代码。exit
行确保 shell 不试图执行标记文本或存档内容作为代码。您可以保持提取代码在一个较低的压缩格式,如果你愿意,但是你最终不得不为存档部分创建一个临时文件,并确保它被删除。z4bn682m3#
有一种方法可以不使用base64编码。
你可以在文件前面加上一个小的头,当运行时,它会从文件中剥离出来,并将其传递给tar。这个选项使文件比base64做同样的事情更小。我也认为这个选项更符合压缩的精神。
这是我能做的最好的,并且仍然可以正常运行:
字符串
如果你愿意,你可以在开始时加入shebang。
型
作为参考,-a选项用于压缩自动检测。
要实际使用该代码段,请运行以下命令
型
不过这种方法有一些复杂之处,即固定的跳过值。除非头部本身发生变化,否则它不会引起问题。
如果你决定改变头脚本,你可以得到新的大小的头文件和编辑跳过选项使用dd。