是否可以编写一个bash脚本,其中包含一个二进制可执行程序?
我的意思是一个脚本,它包含一个文本形式的可执行文件转储,在执行它时会被这个脚本转储回可执行文件?
我很想知道一个解决方案,它可以开箱即用,无需安装额外的软件包。有可能吗?
谢谢!
答案 0 :(得分:6)
我之前从未做过这样的事情;)
这将编译一些c源代码,创建一个包含二进制文件的b.bash
脚本(以及用于简单开发的原始脚本)
(a.bash)
#!/bin/bash
if [ "$0" == "b.bash" ];then
tail -n +$[ `grep -n '^BINARY' $0|cut -d ':' -f 1` + 1 ] $0 | base64 -d > a2.out
chmod +x a2.out
./a2.out
echo $?
exit
fi
cat "$0" > b.bash
echo "BINARY" >> b.bash
cat > a.c << EOF
int main(){
return 12;
}
EOF
gcc a.c
base64 a.out >> b.bash
调用(a.bash生成b.bash):
bash a.bash ;bash b.bash
我不知道如何避免在执行之前将二进制文件写入临时文件...
答案 1 :(得分:4)
我尝试了这个并且它有效。十六进制是用xxd生成的。
#!/bin/bash
xxd -r >foo <<'EndHere'
0000000: 7f45 4c46 0201 0100 0000 0000 0000 0000 .ELF............
0000010: 0200 3e00 0100 0000 e003 4000 0000 0000 ..>.......@.....
0000020: 4000 0000 0000 0000 000a 0000 0000 0000 @...............
0000030: 0000 0000 4000 3800 0800 4000 1e00 1b00 ....@.8...@.....
0000040: 0600 0000 0500 0000 4000 0000 0000 0000 ........@.......
0000050: 4000 4000 0000 0000 4000 4000 0000 0000 @.@.....@.@.....
...
0001960: 6400 5f65 6461 7461 006d 6169 6e00 5f69 d._edata.main._i
0001970: 6e69 7400 nit.
EndHere
chmod +x foo
./foo
答案 2 :(得分:3)
不要像其他几个答案所暗示的那样重新发明轮子,只需使用古老的shar命令,这个命令正是通过设计实现的。
假设要嵌入脚本的文件为binaryfile
,只需运行
$ shar binaryfile > binaryfile.shar
然后你就定了。您有一个名为binaryfile.shar
的shell脚本,执行后将提取binaryfile
。
答案 3 :(得分:1)
您可以使用uuencode / uudecode将二进制文件转换为文本,然后再转换为二进制文件。
http://linux.die.net/man/1/uuencode
因此,您可以将二进制数据作为文本存储在脚本中,并将其输出到二进制文件中。
uuencode binaryFile&gt; output.txt的
然后将这些数据放入您的脚本中,并在创建二进制文件时使用uudecode。
答案 4 :(得分:0)
那么,如果我做得对,你想在你的脚本中包含一个二进制文件并在脚本退出时执行它吗?
这是一个binarymaker
脚本(这不仅创建一个提取二进制文件的脚本,而且将任何脚本与任何二进制文件合并):
#!/bin/bash
lineCount=$(wc -l "$1" | cut -f 1 -d ' ') # just get the line count
((lineCount+=2)) # because we are going to append a line
head -n 1 "$1" > "$3" # this is done to ensure that shebang is preserved
echo "trap 'tail -n +$lineCount \$0 > binary; chmod +x binary; ./binary' EXIT" >> "$3"
tail -n +2 "$1" >> "$3"
cat "$2" >> "$3"
exit 0
你应该像这样运行
./binarymaker myscript mybinary resultscript
如果您运行resultscript
,则myscript
和mybinary
都将被执行。您可以选择在之后向rm
二进制文件添加命令。
另外,不要忘记在脚本末尾退出,否则它会继续并尝试解析二进制数据。
如果你正在使用另一个脚本而不是二进制文件,那么它可以从管道执行,如下所示:
tail -n +$lineCount \$0 | source /dev/stdin
但它不适用于真正的二进制文件。此外,如果您的bash版本低于4
,它也不起作用答案 5 :(得分:0)
我必须制作一个安装程序脚本才能将其部署到甚至没有tar的计算机上,我结束了将busybox(用于tar和gunzip)和tarball嵌入到Shell脚本中的部署。我是 dd方法完成的:
#!/usr/bin/env bash
get_length()
{
ls -l "$1" | cut -f5 -d' '
}
# First parameter is the number of semicolons to add to second parameter
# NOTE: we do not use an "add_blanks" function directly because it seems bash
# removes duplicated blanks. The workaround is adding other character and
# replacing later using e.g. sed.
add_semicolons()
{
scratch="$2"
for n in $(seq 1 $1)
do
scratch+=";"
done
echo $scratch
}
# Default values
output="installer"
input="deployable.tar.gz"
shell="busybox"
shell_len=$(get_length "$shell")
payload_len=$(get_length "$input")
# START OF INSTALLATION SCRIPT GENERATION.
#
# Note: generated scripts reserves 9 digits for the skip (ibs) offsets.
# When the script is first written, these digits are written as semicolons.
# Later when the lengths are computed, these semicolons are replaced by the
# correct numbers, but the 9-digit length must be preserved by adding blanks
# until 9 digits are filled. Failure to do this will cause the script length
# to vary and offsets would need to be iteratively computed.
# Add shebang
echo "#!/usr/bin/env ash" > "$output"
echo "echo Extracting installer..." >> "$output"
# Add lines to extract binary data and extract payload
echo "mkdir -p /tmp/installer" >> "$output"
echo "dd if=\"$(basename $output)\" ibs=;;;;;;;;; skip=1 | dd ibs=$shell_len count=1 of=/tmp/installer/shell 2>/dev/null" >> "$output"
echo "chmod +x /tmp/installer/shell" >> "$output";
echo "dd if=\"$(basename $output)\" ibs=;;;;;;;;; skip=1 2>/dev/null of=/tmp/installer/payload.tar.gz 2>/dev/null" >> "$output"
# From here on, the binary extraction is completed, do something with extracted files...
# [...]
# Use exit command to avoid the shell script parsing to reach the binary part
echo "echo Done!" >> "$output"
echo "exit 0" >> "$output"
# We reserved 9 blanks for the ibs offsets. Thus fill offsets with blanks up to 9 chars total
script_len=$(get_length "$output")
skip_len=$((script_len + shell_len))
to_add=$((9 - ${#script_len}))
script_len_str=$(add_semicolons $to_add $script_len)
to_add=$((9 - ${#skip_len}))
skip_len_str=$(add_semicolons $to_add $skip_len)
# Add skip values
sed -i "4s/ibs=;;;;;;;;;/ibs=$script_len_str/" "$output"
sed -i "4s/;/ /g" "$output"
sed -i "6s/ibs=;;;;;;;;;/ibs=$skip_len_str/" "$output"
sed -i "6s/;/ /g" "$output"
cat "$shell" >> "$output"
cat "$input" >> "$output"
chmod +x "$output"
答案 6 :(得分:-1)
当然可以!
您可以使用以下命令将任何二进制文件转储到文件中:
echo $binary > file
有很多安装脚本可以做这样的事情。