bash脚本解释

bash脚本解释

我有以下我无法理解的脚本。有人可以解释一下吗?

#!/bin/sh
skip=14
tmpdir=`/bin/mktemp -d ${TMPDIR:-/tmp}/gzexe.XXXXXXXXXX` || exit 1

prog="${tmpdir}/`echo \"$0\" | sed 's|^.*/||'`"

if /usr/bin/tail -n +$skip "$0" | "/bin"/gzip -cd > "$prog"; then
  /bin/chmod 700 "$prog"
  trap '/bin/rm -rf $tmpdir; exit $res' EXIT
  "$prog" ${1+"$@"}; res=$?
else
  echo "Cannot decompress $0"
  /bin/rm -rf $tmpdir
  exit 1
fi;
exit $res   

答案1

就像 cas 和 kcmakwana 所说的那样,这个脚本是自解压的。

#!/bin/sh

这是一个 shebang 来表示这是一个 unix shell 脚本。

skip=14

$skip我们声明一个带有字符串值的变量14

tmpdir=`/bin/mktemp -d ${TMPDIR:-/tmp}/gzexe.XXXXXXXXXX` || exit 1

这里的重音符号表示执行内容并将其放入新的命令字符串中。 (这与 ) 不同吗$(my command)?在这里,我们尝试为临时目录声明一个名称。该${TMPDIR:-/tmp}代码意味着我们获取环境变量的值$TMPDIR(如果存在),否则我们使用/tmp并将字符串附加/gzexe.XXXXXXXXXX到我们正在生成的路径中。这|| exit 1意味着如果该命令失败,我们将退出此脚本并显示 1 级错误(0 级表示成功)。看这个问题有关退出代码的更多信息。

prog="${tmpdir}/`echo \"$0\" | sed 's|^.*/||'`"

这里我们为文件路径定义另一个变量。正在$0扩展该脚本的名称。sed我们将该字符串通过管道传输到的命令是修剪该路径的前导部分./。这里将 sed 视为您通过管道输入的字符串的搜索和替换函数。因此,如果我们将此脚本命名为myscript.sh$0并且./myscript.sh应该$prog包含/tmp/myscript.sh.这是最好的行为吗?

if /usr/bin/tail -n +$skip "$0" | "/bin"/gzip -cd > "$prog"; then

在这里,我们从该脚本的第 14 行开始输出内容,$0并将该内容通过标志传输到 gzip 中,-c and -d该标志依次解压缩传入的文本并将结果打印到标准输出。接下来,标准输出被重定向到$prog我们之前声明的文件路径。这是最好的行为吗?明确地将预期内容回显到 中会更安全吗$prog

  /bin/chmod 700 "$prog"

在这里,我们为生成的文件设置权限,以便所有者可以读/写/执行,但其他人无法对该文件执行任何操作。

  trap '/bin/rm -rf $tmpdir; exit $res' EXIT

使用 trap 命令的典型场景是捕获 SIGINT 信号。当用户通过按 Ctrl+C 中断脚本的执行时,系统会发送此信号。因此,当用户发送 ctrl-c 命令时,脚本将尝试删除位于的文件并以我们在下一行中声明的$tmpdir级别退出$res

  "$prog" ${1+"$@"}; res=$?
exit $res  

在这里,我们执行脚本 at$prog并向其传递参数,${1+"$@"}这基本上意味着我们扩展传递到该脚本中的任何参数,即"$1" "$2" "$3" ...。查看该语法的解释这里。最后,我们保存该命令的退出状态结果并将其保存到$res$?是最近的前台管道退出状态)。最后我们以相同的退出级别退出。

else
  echo "Cannot decompress $0"
  /bin/rm -rf $tmpdir
  exit 1
fi;

非常简单,如果if上面的命令不起作用,我们删除临时脚本副本$tmpdir并以状态 1(错误)退出。

相关内容