以下を含むスクリプトがあります。
#!/bin/bash
printenv
コマンドラインから実行するとき:
env testscript.sh
bash testscript.sh
sh testscript.sh
毎回出力しますSHELL=/bin/bash
が、cronで実行すると常に出力されますSHELL=/bin/sh
。 cronにshebangを適用させるにはどうすればよいですか?
クローンパスを確認しましたが、これには/ binが含まれています。
答え1
shebangが動作しており、cronはそれとは何の関係もありません。ファイルの実行時にファイルの内容がで始まると、#!
カーネルは#!
その行で指定されたファイルを実行し、元のファイルを引数として渡します。
SHELL
問題は、スクリプトが実行されているシェルがシェルスクリプトに反映されていると信じているようです。そうではありません。実際、ほとんどの場合、SHELL
ユーザーの好みを意味します。インタラクティブシェルの役割は、ターミナルエミュレータなどのアプリケーションに実行するシェルを決定させることです。 cronでSHELL
crontabエントリ(時間表示の後の行の一部)を実行するために使用するプログラムをcronに通知する変数。
シェルはSHELL
起動時に設定されない限り、この変数を設定しません。
事実はSHELL
おそらく/bin/sh
関係がないでしょう。スクリプトには#!/bin/bash
1行があるため、bashによって実行されます。自信がある場合は、ps $$
スクリプトを追加してps
スクリプトを実行しているシェルに関する情報を表示してください。
答え2
バッシュリファレンスマニュアル説明する:
SHELL - シェルの絶対パス名がこの環境変数に保持されます。シェルがシェルなしで起動されると、Bashはそのシェルに現在のユーザーログインシェルのフルパス名を割り当てます。
man 5 crontab
説明する:
いくつかの環境変数はcron(8)デーモンによって自動的に設定されます。 SHELL は /bin/sh に設定され、LOGNAME と HOME は crontab 所有者の /etc/passwd 行で設定されます。 PATH は "/usr/bin:/bin" に設定されます。 HOME、SHELL、および PATH は crontab の設定で上書きできます。
したがって、このSHELL
変数はBashの起動時に設定されます。
努力するSHELL=/bin/awesome/shell bash testcript.sh
。あなたは見なければなりませんSHELL=/bin/awesome/shell
Sherbonが動作します。あなたの行動が記録されます:)
答え3
ただし、cronで実行すると常にSHELL = / bin / shが出力されます。なぜこれですか?
これはcronSHELL
がに設定されているためです/bin/sh
。これは、cron が crontab エントリの実行に使用する基本プログラムであるためです。からman 5 crontab
:
いくつかの環境変数はcron(8)デーモンによって自動的に設定されます。 SHELLは/bin/shに設定されています...
Evgeny Vereshchaginの答えがすでに指摘したように、変数がすでに設定されている場合、Bashは後でそれを修正しません。
cronにshebangを適用させるにはどうすればよいですか?
クローンはすでに適用中です。あなたのスクリプトのために、次の例に示すように。
以下があるとしましょうdisplay_process_tree.sh
。
#!/bin/bash
pid=$$
depth=0
while
[ "$pid" -gt 0 ] &&
read -r ppid name < <(ps -o ppid= -o comm= -p "$pid")
do
eval $(echo printf '" %0.s"' {0..$depth})
if [[ -r /proc/$pid/exe ]]; then
echo -n "$name - "
readlink -f /proc/$pid/exe
else
echo $name
fi
pid=$ppid
depth=$((depth+1))
done
次のcrontabもあります。
* * * * * /path/to/display_process_tree.sh > /tmp/display_process_tree.log
これで、出力が到着するのを待つと、/tmp/display_process_tree.log
次のプロセスツリーが見つかります。
display_process - /bin/bash
sh - /bin/dash
cron
cron
systemd
これは、cronが実際に/bin/sh
スクリプトの/bin/dash
新しいプロセスを開くために(私のシステムにリンクされている)使用法を示しています。/bin/bash
答え4
shebangを次に変更します。
#!/bin/env bash
または、crontab -e
cronの独自の環境変数が異なるため、独自の環境変数を使用してスクリプトを実行するように実行します。
ちなみに、によるとこの記事はaskubuntuにあります。cron
、スクリプトの上部にPATHを提供する必要があります。
PATH=/opt/someApp/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# rest of script follows
ただし、PATHに正しい検索ディレクトリがあると思われる場合は、それを除外できます。