理解できない次のスクリプトがあります。誰かがこれを説明できますか?
#!/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
これはUnixシェルスクリプトであることを示すshebangです。
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
ここではスクリプトを実行し$prog
て引数を渡します。${1+"$@"}
これは、基本的にそのスクリプトに渡された引数を拡張することを意味します"$1" "$2" "$3" ...
。この構文の説明を参照してください。ここ。最後に、コマンドの終了ステータス結果を保存し、それを$res
($?
最新のフォアグラウンドパイプ終了ステータス)に保存します。最後に、同じ終了レベルで終了します。
else
echo "Cannot decompress $0"
/bin/rm -rf $tmpdir
exit 1
fi;
とても簡単です。if
上記のコマンドが機能しない場合は、一時スクリプトのコピーを削除して$tmpdir
ステータス1(エラー)で終了します。