cronジョブを実行できるようにスクリプト自体をコピーしたいのですが、スクリプト内でその場所を取得するのは困難です。posixでは信頼できない。より良いアプローチは、スクリプト全体を区別された文書にしてインポートすることです。
これを行うエレガントなPOSIXメソッドはありますか?
このサンプルスクリプトを使用してこれまで試したことは次のとおりです。
#!/bin/sh
FOO='hello world'
echo "$FOO"
cat "$0"
最初の方法
/tmp/.script$$
必要に応じてスクリプトが適切な場所にコピーできるように書かれています(busyboxはコンパイルを使用しませんmktemp
)。 Linux 2.6で実行されているか、それは/dev/fd/
必要ありませ/dev/stdin
ん/proc/self/fd/
が利用可能です。
#!/bin/sh
trap '{ rm -f "/tmp/.script$$"; exit; }' EXIT INT TERM
tee "/tmp/.script$$" <<'#SCRIPT' | . /proc/self/fd/0
#!/bin/sh
FOO='hello world'
echo "$FOO"
cat "/tmp/.script$$"
#SCRIPT
これは機能しますが、パイプで発生するため、外部で使用できる変数や関数はありません。
2番目の方法
#!/bin/sh
trap '{ rm -f "/tmp/.script$$"; exit; }' EXIT INT TERM
cat > "/tmp/.script$$" <<'#SCRIPT' && . "/tmp/.script$$"
#!/bin/sh
FOO='hello world'
echo "$FOO"
cat "/tmp/.script$$"
#SCRIPT
ここの範囲は固定されていますが、実行はスクリプトが成功したかどうかによって異なります。
3番目の方法
#!/bin/sh
trap '{ rm -f "/tmp/.script$$"; exit; }' EXIT INT TERM
. /proc/self/fd/0 <<EOF
$(tee "/tmp/.script$$" <<': "SCRIPT'
#!/bin/sh
FOO='hello world'
echo "$FOO"
cat "/tmp/.script$$"
: "SCRIPT
)
EOF
#"
機能的にこれは私が望むものですが、かなり醜いです。
うまくいかない
#!/bin/sh
trap '{ rm -f "/tmp/.script$$"; exit; }' EXIT INT TERM
{ ( tee "/tmp/.script$$" >/proc/$$/fd/0 ) <<'#SCRIPT' & } && . /proc/self/fd/0
#!/bin/sh
FOO='hello world'
echo "$FOO"
cat "/tmp/.script$$"
#SCRIPT
これは対話型シェルのようにユーザー入力を待ちます。 stdinが閉じられていないので、これがうまくいく理由を理解していますが、ファイルに接続せずに新しいファイル記述子を開く方法がわかりません。とにかくファイルに接続するには、2番目の方法がよりきれいです。働く)。