mirror of
https://github.com/LCTT/TranslateProject.git
synced 2024-12-26 21:30:55 +08:00
773 lines
25 KiB
Markdown
773 lines
25 KiB
Markdown
|
[#]: collector: (lujun9972)
|
|||
|
[#]: translator: ( )
|
|||
|
[#]: reviewer: ( )
|
|||
|
[#]: publisher: ( )
|
|||
|
[#]: url: ( )
|
|||
|
[#]: subject: (Run a command on binary files with this script)
|
|||
|
[#]: via: (https://opensource.com/article/20/3/run-binaries-script)
|
|||
|
[#]: author: (Nick Clifton https://opensource.com/users/nickclifton)
|
|||
|
|
|||
|
Run a command on binary files with this script
|
|||
|
======
|
|||
|
Try this simple script to easily run a command on binary files
|
|||
|
regardless of their packaging.
|
|||
|
![Binary code on a computer screen][1]
|
|||
|
|
|||
|
Examining files from the command-line is generally an easy thing to do. You just run the command you want, followed by a list of files to be examined. Dealing with binary files, however, is more complicated. These files are often packaged up into archives, tarballs, or other packaging formats. The run-on-binaries script provides a convenient way to run a command on a collection of files, regardless of how they are packaged.
|
|||
|
|
|||
|
The invocation of the script is quite simple:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`run-on-binaries <file(s}>`
|
|||
|
```
|
|||
|
|
|||
|
So, for example:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`run-on-binaries /usr/bin/ls foo.rpm`
|
|||
|
```
|
|||
|
|
|||
|
will list all of the files inside the **foo.rpm** file, while:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`run-on-binaries /usr/bin/readelf -a libc.a`
|
|||
|
```
|
|||
|
|
|||
|
will run the **readelf** program, with the **-a** command-line option, on all of the object files inside the **libc.a library**.
|
|||
|
|
|||
|
If necessary, the script can be passed a file containing a list of other files to be processed, rather than specifying them on the command line—like this:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`run-on-binaries --files-from=foo.lst /usr/bin/ps2ascii`
|
|||
|
```
|
|||
|
|
|||
|
This will run the **ps2ascii** script on all of the files listed in **foo.lst**. (The files just need to be separated by white space. There can be multiple files on a single line if desired).
|
|||
|
|
|||
|
Also, a skip list can be provided to stop the script from processing specified files:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`run-on-binaries --skip-list=skip.lst /usr/bin/wc *`
|
|||
|
```
|
|||
|
|
|||
|
This will run the **wc** program on all of the files in the current directory, except for those specified in **skip.lst**.
|
|||
|
|
|||
|
The script does not recurse into directories, but this can be handled by combining it with the **find** command, like this:
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`find . -type f -exec run-on-binaries @ ;`
|
|||
|
```
|
|||
|
|
|||
|
or
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
`find . -type d -exec run-on-binaries @/* ;`
|
|||
|
```
|
|||
|
|
|||
|
The only difference between these two invocations is that the second one only runs the target program once per directory, but gives it a long command-line of all of the files in the directory.
|
|||
|
|
|||
|
Though convenient, the script is lacking in several areas. Right now, it does not examine the PATH environment variable to find the command that it is asked to run, so a full path must be provided. Also, the script ought to be able to handle recursion on its own, without needing help from the find command.
|
|||
|
|
|||
|
The run-on-binaries script is part of the annobin package, which is available on Fedora. The sources for annobin can also be obtained from the git repository at <git://sourceware.org/git/annobin.git>.
|
|||
|
|
|||
|
### The script
|
|||
|
|
|||
|
|
|||
|
```
|
|||
|
#!/bin/bash
|
|||
|
|
|||
|
# Script to run another script/program on the executables inside a given file.
|
|||
|
#
|
|||
|
# Created by Nick Clifton. <[nickc@redhat.com][2]>
|
|||
|
# Copyright (c) 2018 Red Hat.
|
|||
|
#
|
|||
|
# This is free software; you can redistribute it and/or modify it
|
|||
|
# under the terms of the GNU General Public License as published
|
|||
|
# by the Free Software Foundation; either version 3, or (at your
|
|||
|
# option) any later version.
|
|||
|
|
|||
|
# It is distributed in the hope that it will be useful, but
|
|||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
# GNU General Public License for more details.
|
|||
|
#
|
|||
|
# Usage:
|
|||
|
# run-on-binaries-in [options] program [options-for-the-program] file(s)
|
|||
|
#
|
|||
|
# This script does not handle directories. This is deliberate.
|
|||
|
# It is intended that if recursion is needed then it will be
|
|||
|
# invoked from find, like this:
|
|||
|
#
|
|||
|
# find . -name "*.rpm" -exec run-on-binaries-in <script-to-run> {} \;
|
|||
|
|
|||
|
version=1.0
|
|||
|
|
|||
|
help ()
|
|||
|
{
|
|||
|
# The following exec goop is so that we don't have to manually
|
|||
|
# redirect every message to stderr in this function.
|
|||
|
exec 4>&1 # save stdout fd to fd #4
|
|||
|
exec 1>&2 # redirect stdout to stderr
|
|||
|
|
|||
|
cat <<__EOM__
|
|||
|
|
|||
|
This is a shell script to run another script/program on one or more binary
|
|||
|
files. If the file(s) specified are archives of some kind (including rpms)
|
|||
|
then the script/program is run on the binary executables inside the archive.
|
|||
|
|
|||
|
Usage: $prog {options} program {options-for-the-program} files(s)
|
|||
|
|
|||
|
{options} are:
|
|||
|
-h --help Display this information and then exit.
|
|||
|
-v --version Report the version number of this script.
|
|||
|
-V --verbose Report on progress.
|
|||
|
-q --quiet Do not include the script name in the output.
|
|||
|
-i --ignore Silently ignore files that are not executables or archives.
|
|||
|
-p=<TEXT> --prefix=<TEXT> Prefix normal output with this string.
|
|||
|
-t=<DIR> --tmpdir=<DIR> Temporary directory to use when opening archives.
|
|||
|
-f=<FILE> --files-from=<FILE> Process files listed in <FILE>.
|
|||
|
-s=<FILE> --skip-list=<FILE> Skip any file listed in <FILE>.
|
|||
|
-- Stop accumulating options.
|
|||
|
|
|||
|
Examples:
|
|||
|
|
|||
|
$prog hardened foo.rpm
|
|||
|
Runs the hardened script on the executable
|
|||
|
files inside foo.rpm.
|
|||
|
|
|||
|
$prog check-abi -v fred.tar.xz
|
|||
|
Runs the check-abi script on the decompressed
|
|||
|
contents of the fred.tar.xz archive, passing the
|
|||
|
-v option to check-abi as it does so.
|
|||
|
|
|||
|
$prog -V -f=list.txt readelf -a
|
|||
|
Runs the readelf program, with the -a option on
|
|||
|
every file listed in the list.txt. Describes
|
|||
|
what is being done as it works.
|
|||
|
|
|||
|
$prog -v -- -fred -a jim -b bert -- -c harry
|
|||
|
Runs the script "-fred" on the files jim, bert,
|
|||
|
"-c" and harry. Passes the options "-a" and
|
|||
|
"-b" to the script (even when run on jim).
|
|||
|
Reports the version of this script as well.
|
|||
|
|
|||
|
__EOM__
|
|||
|
exec 1>&4 # Copy stdout fd back from temporary save fd, #4
|
|||
|
}
|
|||
|
|
|||
|
main ()
|
|||
|
{
|
|||
|
init
|
|||
|
|
|||
|
parse_args ${1+"$@"}
|
|||
|
|
|||
|
if [ $failed -eq 0 ];
|
|||
|
then
|
|||
|
run_script_on_files
|
|||
|
fi
|
|||
|
|
|||
|
if [ $failed -ne 0 ];
|
|||
|
then
|
|||
|
exit 1
|
|||
|
else
|
|||
|
exit 0
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
report ()
|
|||
|
{
|
|||
|
if [ $quiet -eq 0 ];
|
|||
|
then
|
|||
|
echo -n $prog": "
|
|||
|
fi
|
|||
|
|
|||
|
echo ${1+"$@"}
|
|||
|
}
|
|||
|
|
|||
|
ice ()
|
|||
|
{
|
|||
|
report "Internal error: " ${1+"$@"}
|
|||
|
exit 1
|
|||
|
}
|
|||
|
|
|||
|
fail ()
|
|||
|
{
|
|||
|
report "Failure:" ${1+"$@"}
|
|||
|
failed=1
|
|||
|
}
|
|||
|
|
|||
|
verbose ()
|
|||
|
{
|
|||
|
if [ $verbose -ne 0 ]
|
|||
|
then
|
|||
|
report ${1+"$@"}
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
# Initialise global variables.
|
|||
|
init ()
|
|||
|
{
|
|||
|
files[0]="";
|
|||
|
# num_files is the number of files to be scanned.
|
|||
|
# files[0] is the script to run on the files.
|
|||
|
num_files=0;
|
|||
|
|
|||
|
script=""
|
|||
|
script_opts="";
|
|||
|
|
|||
|
prog_opts="-i"
|
|||
|
|
|||
|
tmpdir=/dev/shm
|
|||
|
prefix=""
|
|||
|
files_from=""
|
|||
|
skip_list=""
|
|||
|
|
|||
|
failed=0
|
|||
|
verbose=0
|
|||
|
ignore=0
|
|||
|
quiet=0
|
|||
|
}
|
|||
|
|
|||
|
# Parse our command line
|
|||
|
parse_args ()
|
|||
|
{
|
|||
|
abs_prog=$0;
|
|||
|
prog=`basename $abs_prog`;
|
|||
|
|
|||
|
# Locate any additional command line switches
|
|||
|
# Likewise accumulate non-switches to the files list.
|
|||
|
while [ $# -gt 0 ]
|
|||
|
do
|
|||
|
optname="`echo $1 | sed 's,=.*,,'`"
|
|||
|
optarg="`echo $1 | sed 's,^[^=]*=,,'`"
|
|||
|
case "$optname" in
|
|||
|
-v | --version)
|
|||
|
report "version: $version"
|
|||
|
;;
|
|||
|
-h | --help)
|
|||
|
help
|
|||
|
exit 0
|
|||
|
;;
|
|||
|
-q | --quiet)
|
|||
|
quiet=1;
|
|||
|
prog_opts="$prog_opts -q"
|
|||
|
;;
|
|||
|
-V | --verbose)
|
|||
|
if [ $verbose -eq 1 ];
|
|||
|
then
|
|||
|
# This has the effect of cancelling out the prog_opts="-i"
|
|||
|
# in the init function, so that recursive invocations of this
|
|||
|
# script will complain about unrecognised file types.
|
|||
|
if [ $quiet -eq 0 ];
|
|||
|
then
|
|||
|
prog_opts="-V -V"
|
|||
|
else
|
|||
|
prog_opts="-V -V -q"
|
|||
|
fi
|
|||
|
else
|
|||
|
verbose=1;
|
|||
|
prog_opts="$prog_opts -V"
|
|||
|
fi
|
|||
|
;;
|
|||
|
-i | --ignore)
|
|||
|
ignore=1
|
|||
|
;;
|
|||
|
-t | --tmpdir)
|
|||
|
if test "x$optarg" = "x$optname" ;
|
|||
|
then
|
|||
|
shift
|
|||
|
if [ $# -eq 0 ]
|
|||
|
then
|
|||
|
fail "$optname needs a directory name"
|
|||
|
else
|
|||
|
tmpdir=$1
|
|||
|
fi
|
|||
|
else
|
|||
|
tmpdir="$optarg"
|
|||
|
fi
|
|||
|
;;
|
|||
|
-p | --prefix)
|
|||
|
if test "x$optarg" = "x$optname" ;
|
|||
|
then
|
|||
|
shift
|
|||
|
if [ $# -eq 0 ]
|
|||
|
then
|
|||
|
fail "$optname needs a string argument"
|
|||
|
else
|
|||
|
prefix=$1
|
|||
|
fi
|
|||
|
else
|
|||
|
prefix="$optarg"
|
|||
|
fi
|
|||
|
;;
|
|||
|
-f | --files_from)
|
|||
|
if test "x$optarg" = "x$optname" ;
|
|||
|
then
|
|||
|
shift
|
|||
|
if [ $# -eq 0 ]
|
|||
|
then
|
|||
|
fail "$optname needs a file name"
|
|||
|
else
|
|||
|
files_from=$1
|
|||
|
fi
|
|||
|
else
|
|||
|
files_from="$optarg"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
-s | --skip-list)
|
|||
|
if test "x$optarg" = "x$optname" ;
|
|||
|
then
|
|||
|
shift
|
|||
|
if [ $# -eq 0 ]
|
|||
|
then
|
|||
|
fail "$optname needs a file name"
|
|||
|
else
|
|||
|
skip_list=$1
|
|||
|
fi
|
|||
|
else
|
|||
|
skip_list="$optarg"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
--)
|
|||
|
shift
|
|||
|
break;
|
|||
|
;;
|
|||
|
--*)
|
|||
|
fail "unrecognised option: $1"
|
|||
|
help
|
|||
|
;;
|
|||
|
*)
|
|||
|
script="$1";
|
|||
|
if ! [ -a "$script" ]
|
|||
|
then
|
|||
|
fail "$script: program/script not found"
|
|||
|
elif ! [ -x "$script" ]
|
|||
|
then
|
|||
|
fail "$script: program/script not executable"
|
|||
|
fi
|
|||
|
# After we have seen the first non-option we stop
|
|||
|
# accumulating options for this script and instead
|
|||
|
# start accumulating options for the script to be
|
|||
|
# run.
|
|||
|
shift
|
|||
|
break;
|
|||
|
;;
|
|||
|
esac
|
|||
|
shift
|
|||
|
done
|
|||
|
|
|||
|
# Read in the contents of the --file-from list, if specified.
|
|||
|
if test "x$files_from" != "x" ;
|
|||
|
then
|
|||
|
if ! [ -a "$files_from" ]
|
|||
|
then
|
|||
|
fail "$files_from: file not found"
|
|||
|
elif ! [ -r "$files_from" ]
|
|||
|
then
|
|||
|
fail "$files_from: file not readable"
|
|||
|
else
|
|||
|
eval 'files=($(cat $files_from))'
|
|||
|
num_files=${#files[*]}
|
|||
|
fi
|
|||
|
fi
|
|||
|
skip_files[foo]=bar
|
|||
|
|
|||
|
# Check that the skip list exists, if specified.
|
|||
|
if test "x$skip_list" != "x" ;
|
|||
|
then
|
|||
|
if ! [ -a "$skip_list" ]
|
|||
|
then
|
|||
|
fail "$skip_list: file not found"
|
|||
|
elif ! [ -r "$skip_list" ]
|
|||
|
then
|
|||
|
fail "$files_from: file not readable"
|
|||
|
fi
|
|||
|
fi
|
|||
|
|
|||
|
# Accumulate any remaining arguments separating out the arguments
|
|||
|
# for the script from the names of the files to scan.
|
|||
|
while [ $# -gt 0 ]
|
|||
|
do
|
|||
|
optname="`echo $1 | sed 's,=.*,,'`"
|
|||
|
optarg="`echo $1 | sed 's,^[^=]*=,,'`"
|
|||
|
case "$optname" in
|
|||
|
--)
|
|||
|
shift
|
|||
|
break;
|
|||
|
;;
|
|||
|
-*)
|
|||
|
script_opts="$script_opts $1"
|
|||
|
;;
|
|||
|
*)
|
|||
|
files[$num_files]="$1";
|
|||
|
let "num_files++"
|
|||
|
;;
|
|||
|
esac
|
|||
|
shift
|
|||
|
done
|
|||
|
|
|||
|
# Accumulate any remaining arguments without processing them.
|
|||
|
while [ $# -gt 0 ]
|
|||
|
do
|
|||
|
files[$num_files]="$1";
|
|||
|
let "num_files++";
|
|||
|
shift
|
|||
|
done
|
|||
|
|
|||
|
if [ $num_files -gt 0 ];
|
|||
|
then
|
|||
|
# Remember that we are counting from zero not one.
|
|||
|
let "num_files--"
|
|||
|
else
|
|||
|
fail "Must specify a program/script and at least one file to scan."
|
|||
|
fi
|
|||
|
}
|
|||
|
|
|||
|
run_script_on_files ()
|
|||
|
{
|
|||
|
local i
|
|||
|
|
|||
|
i=0;
|
|||
|
while [ $i -le $num_files ]
|
|||
|
do
|
|||
|
run_on_file i
|
|||
|
let "i++"
|
|||
|
done
|
|||
|
}
|
|||
|
|
|||
|
# syntax: run <command> [<args>]
|
|||
|
# If being verbose report the command being run, and
|
|||
|
# the directory in which it is run.
|
|||
|
run ()
|
|||
|
{
|
|||
|
local where
|
|||
|
|
|||
|
if test "x$1" = "x" ;
|
|||
|
then
|
|||
|
fail "run() called without an argument."
|
|||
|
fi
|
|||
|
|
|||
|
verbose " Running: ${1+$@}"
|
|||
|
|
|||
|
${1+$@}
|
|||
|
}
|
|||
|
|
|||
|
decompress ()
|
|||
|
{
|
|||
|
local abs_file decompressor decomp_args orig_file base_file
|
|||
|
|
|||
|
# Paranoia checks - the user should never encounter these.
|
|||
|
if test "x$4" = "x" ;
|
|||
|
then
|
|||
|
ice "decompress called with too few arguments"
|
|||
|
fi
|
|||
|
if test "x$5" != "x" ;
|
|||
|
then
|
|||
|
ice "decompress called with too many arguments"
|
|||
|
fi
|
|||
|
|
|||
|
abs_file=$1
|
|||
|
decompressor=$2
|
|||
|
decomp_args=$3
|
|||
|
orig_file=$4
|
|||
|
|
|||
|
base_file=`basename $abs_file`
|
|||
|
|
|||
|
run cp $abs_file $base_file
|
|||
|
run $decompressor $decomp_args $base_file
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$orig_file: Unable to decompress"
|
|||
|
fi
|
|||
|
|
|||
|
rm -f $base_file
|
|||
|
}
|
|||
|
|
|||
|
run_on_file ()
|
|||
|
{
|
|||
|
local file
|
|||
|
|
|||
|
# Paranoia checks - the user should never encounter these.
|
|||
|
if test "x$1" = "x" ;
|
|||
|
then
|
|||
|
ice "scan_file called without an argument"
|
|||
|
fi
|
|||
|
if test "x$2" != "x" ;
|
|||
|
then
|
|||
|
ice "scan_file called with too many arguments"
|
|||
|
fi
|
|||
|
|
|||
|
# Use quotes when accessing files in order to preserve
|
|||
|
# any spaces that might be in the directory name.
|
|||
|
file="${files[$1]}";
|
|||
|
|
|||
|
# Catch names that start with a dash - they might confuse readelf
|
|||
|
if test "x${file:0:1}" = "x-" ;
|
|||
|
then
|
|||
|
file="./$file"
|
|||
|
fi
|
|||
|
|
|||
|
# See if we should skip this file.
|
|||
|
if test "x$skip_list" != "x" ;
|
|||
|
then
|
|||
|
# This regexp looks for $file being the first text on a line, either
|
|||
|
# on its own, or with additional text separated from it by at least
|
|||
|
# one space character. So searching for "fred" in the following gives:
|
|||
|
# fr <\- no match
|
|||
|
# fred <\- match
|
|||
|
# fredjim <\- no match
|
|||
|
# fred bert <\- match
|
|||
|
regexp="^$file[^[:graph:]]*"
|
|||
|
grep --silent --regexp="$regexp" $skip_list
|
|||
|
if [ $? = 0 ];
|
|||
|
then
|
|||
|
verbose "$file: skipping"
|
|||
|
return
|
|||
|
fi
|
|||
|
fi
|
|||
|
|
|||
|
# Check the file.
|
|||
|
if ! [ -a "$file" ]
|
|||
|
then
|
|||
|
fail "$file: file not found"
|
|||
|
return
|
|||
|
elif ! [ -r "$file" ]
|
|||
|
then
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
fail "$file: not readable"
|
|||
|
fi
|
|||
|
return
|
|||
|
elif [ -d "$file" ]
|
|||
|
then
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
if [ $num_files -gt 1 ];
|
|||
|
then
|
|||
|
verbose "$file: skipping - it is a directory"
|
|||
|
else
|
|||
|
report "$file: skipping - it is a directory"
|
|||
|
fi
|
|||
|
fi
|
|||
|
return
|
|||
|
elif ! [ -f "$file" ]
|
|||
|
then
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
fail "$file: not an ordinary file"
|
|||
|
fi
|
|||
|
return
|
|||
|
fi
|
|||
|
|
|||
|
file_type=`file -b $file`
|
|||
|
case "$file_type" in
|
|||
|
*"ELF "*)
|
|||
|
verbose "$file: ELF format - running script/program"
|
|||
|
if test "x$prefix" != "x" ;
|
|||
|
then
|
|||
|
report "$prefix:"
|
|||
|
fi
|
|||
|
run $script $script_opts $file
|
|||
|
return
|
|||
|
;;
|
|||
|
"RPM "*)
|
|||
|
verbose "$file: RPM format."
|
|||
|
;;
|
|||
|
*" cpio "*)
|
|||
|
verbose "$file: CPIO format."
|
|||
|
;;
|
|||
|
*"tar "*)
|
|||
|
verbose "$file: TAR archive."
|
|||
|
;;
|
|||
|
*"Zip archive"*)
|
|||
|
verbose "$file: ZIP archive."
|
|||
|
;;
|
|||
|
*"ar archive"*)
|
|||
|
verbose "$file: AR archive."
|
|||
|
;;
|
|||
|
*"bzip2 compressed data"*)
|
|||
|
verbose "$file: contains bzip2 compressed data"
|
|||
|
;;
|
|||
|
*"gzip compressed data"*)
|
|||
|
verbose "$file: contains gzip compressed data"
|
|||
|
;;
|
|||
|
*"lzip compressed data"*)
|
|||
|
verbose "$file: contains lzip compressed data"
|
|||
|
;;
|
|||
|
*"XZ compressed data"*)
|
|||
|
verbose "$file: contains xz compressed data"
|
|||
|
;;
|
|||
|
*"shell script"* | *"ASCII text"*)
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
fail "$file: test/scripts cannot be scanned."
|
|||
|
fi
|
|||
|
return
|
|||
|
;;
|
|||
|
*"symbolic link"*)
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
# FIXME: We ought to be able to follow symbolic links
|
|||
|
fail "$file: symbolic links are not followed."
|
|||
|
fi
|
|||
|
return
|
|||
|
;;
|
|||
|
*)
|
|||
|
if [ $ignore -eq 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unsupported file type: $file_type"
|
|||
|
fi
|
|||
|
return
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
# We now know that we will need a temporary directory
|
|||
|
# so create one, and create paths to the file and scripts.
|
|||
|
if test "x${file:0:1}" = "x/" ;
|
|||
|
then
|
|||
|
abs_file=$file
|
|||
|
else
|
|||
|
abs_file="$PWD/$file"
|
|||
|
fi
|
|||
|
|
|||
|
if test "x${abs_prog:0:1}" != "x/" ;
|
|||
|
then
|
|||
|
abs_prog="$PWD/$abs_prog"
|
|||
|
fi
|
|||
|
|
|||
|
if test "x${script:0:1}" = "x/" ;
|
|||
|
then
|
|||
|
abs_script=$script
|
|||
|
else
|
|||
|
abs_script="$PWD/$script"
|
|||
|
fi
|
|||
|
|
|||
|
tmp_root=$tmpdir/delme.run.on.binary
|
|||
|
run mkdir -p "$tmp_root/$file"
|
|||
|
|
|||
|
verbose " Changing to directory: $tmp_root/$file"
|
|||
|
pushd "$tmp_root/$file" > /dev/null
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "Unable to change to temporary directory: $tmp_root/$file"
|
|||
|
return
|
|||
|
fi
|
|||
|
|
|||
|
# Run the file type switch again, although this time we do not need to
|
|||
|
# check for unrecognised types. (But we do, just in case...)
|
|||
|
# Note since are transforming the file we re-invoke the run-on-binaries
|
|||
|
# script on the decoded contents. This allows for archives that contain
|
|||
|
# other archives, and so on. We normally pass the -i option to the
|
|||
|
# invoked script so that it will not complain about unrecognised files in
|
|||
|
# the decoded archive, although we do not do this when running in very
|
|||
|
# verbose mode. We also pass an extended -t option to ensure that any
|
|||
|
# sub-archives are extracted into a unique directory tree.
|
|||
|
|
|||
|
case "$file_type" in
|
|||
|
"RPM "*)
|
|||
|
# The output redirect confuses the run function...
|
|||
|
verbose " Running: rpm2cpio $abs_file > delme.cpio"
|
|||
|
rpm2cpio $abs_file > delme.cpio
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unable to extract from rpm archive"
|
|||
|
else
|
|||
|
# Save time - run cpio now.
|
|||
|
run cpio --quiet --extract --make-directories --file delme.cpio
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unable to extract files from cpio archive"
|
|||
|
fi
|
|||
|
run rm -f delme.cpio
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
*" cpio "*)
|
|||
|
run cpio --quiet --extract --make-directories --file=$abs_file
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unable to extract files from cpio archive"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
*"tar "*)
|
|||
|
run tar --extract --file=$abs_file
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unable to extract files from tarball"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
*"ar archive"*)
|
|||
|
run ar x $abs_file
|
|||
|
if [ $? != 0 ];
|
|||
|
then
|
|||
|
fail "$file: Unable to extract files from ar archive"
|
|||
|
fi
|
|||
|
;;
|
|||
|
|
|||
|
*"Zip archive"*)
|
|||
|
decompress $abs_file unzip "-q" $file
|
|||
|
;;
|
|||
|
*"bzip2 compressed data"*)
|
|||
|
decompress $abs_file bzip2 "--quiet --decompress" $file
|
|||
|
;;
|
|||
|
*"gzip compressed data"*)
|
|||
|
decompress $abs_file gzip "--quiet --decompress" $file
|
|||
|
;;
|
|||
|
*"lzip compressed data"*)
|
|||
|
decompress $abs_file lzip "--quiet --decompress" $file
|
|||
|
;;
|
|||
|
*"XZ compressed data"*)
|
|||
|
decompress $abs_file xz "--quiet --decompress" $file
|
|||
|
;;
|
|||
|
*)
|
|||
|
ice "unhandled file type: $file_type"
|
|||
|
;;
|
|||
|
esac
|
|||
|
|
|||
|
if [ $failed -eq 0 ];
|
|||
|
then
|
|||
|
# Now scan the file(s) created in the previous step.
|
|||
|
run find . -type f -execdir $abs_prog $prog_opts -t=$tmp_root/$file -p=$file $abs_script $script_opts {} +
|
|||
|
fi
|
|||
|
|
|||
|
verbose " Deleting temporary directory: $tmp_root"
|
|||
|
rm -fr $tmp_root
|
|||
|
|
|||
|
verbose " Return to previous directory"
|
|||
|
popd > /dev/null
|
|||
|
}
|
|||
|
|
|||
|
# Invoke main
|
|||
|
main ${1+"$@"}
|
|||
|
```
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Git has extensions for handling binary blobs such as multimedia files, so today we will learn how...
|
|||
|
|
|||
|
--------------------------------------------------------------------------------
|
|||
|
|
|||
|
via: https://opensource.com/article/20/3/run-binaries-script
|
|||
|
|
|||
|
作者:[Nick Clifton][a]
|
|||
|
选题:[lujun9972][b]
|
|||
|
译者:[译者ID](https://github.com/译者ID)
|
|||
|
校对:[校对者ID](https://github.com/校对者ID)
|
|||
|
|
|||
|
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
|||
|
|
|||
|
[a]: https://opensource.com/users/nickclifton
|
|||
|
[b]: https://github.com/lujun9972
|
|||
|
[1]: https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/binary_code_computer_screen.png?itok=7IzHK1nn (Binary code on a computer screen)
|
|||
|
[2]: mailto:nickc@redhat.com
|