
cron ジョブに配置するスクリプトを作成しようとしています。
スクリプトは、プロセスが実行中かどうかを 5 分ごとにチェックし、実行されていない場合はプロセスを開始する必要がありますが、問題は、プロセスの開始時にプロセスが root によって所有され、特定のディレクトリ内の一部のファイルが変更されることです。そのため、スクリプトでサービスを開始し、10 秒待ってからサービスを停止し、その後、特定のディレクトリに移動してそのディレクトリ内のすべてのファイルの所有権を変更し、スクリプトでサービスを再度開始するようにしたいと考えました。
私の説明が意味を成すことを願っています。
これまでに思いついたのは次の通りです。スクリプトはサービスを開始および停止しますが、サービスが停止するとタイムアウトし、指定されたディレクトリの所有権は変更されません。
#!/bin/bash
exec_start="sudo systemctl start new-service"
exec_stop="sudo systemctl stop new-service"
check1=/root/testing/
username="user1"
process="new-service"
changing_ownership () {
cd $check1 && /usr/bin/chown $username:$username *
}
startAndStop(){
/usr/bin/sudo su - user1 && $exec_start &
sleep 10 && $exec_stop &
sleep 2 && exit
}
startAgain(){
/usr/bin/sudo su - user1 && $exec_start &
sleep 5 && exit
}
if ps ax | grep -v grep | grep $process > /dev/null
then
echo "running"
exit
else
echo "Not running...Going to start the service"
startAndStop
changing_ownership
startAgain
fi
exit
/root/testing/の内容は次のとおりです。
[root@server2 ~]# cd -
/root/testing
[root@server2 testing]# ll
total 0
-rw-r--r--. 1 root root 0 Sep 24 21:34 file1
-rw-r--r--. 1 root root 0 Sep 24 21:34 file2
-rw-r--r--. 1 root root 0 Sep 24 21:34 file3
-rw-r--r--. 1 root root 0 Sep 24 21:39 file8888
ありがとう
答え1
いくつかの問題が見つかりました。
簡単なテスト スクリプトを作成しました:
#!/bin/bash
startAndStop(){
echo "Start 1" &
echo "Sleep 2" && echo "Stop 3"
echo "Sleep 4" && exit
}
startAndStop
echo "Rest of Script"
これは、プログラムの startAndStop 関数をシミュレートします。
出力は次のとおりです。
$ bash test.sh
Sleep 2
Stop 3
Sleep 4
Start 1
この機能に関する 2 つのポイント:
物事は順不同で実行されます。単一の
&
開始タスクがバックグラウンドで実行されます。本当にそうしたいのですか? プロセスが開始して停止するまで待つのが嫌ですか?sleep
s を入れたことは知っていますが、終了するまで待つ方が良いと思います。コマンドが時間内に終了しないと、状況が非常におかしくなる可能性があります。が印刷されなかったことに注意してください
Rest of Script
。exit
コマンドは関数を終了せず、スクリプト全体を終了します。
があります/usr/bin/sudo su - user1 && $exec_start
。これはあなたがやりたいことではないと思います。 を設定しましたexec_start="sudo systemctl start new-service"
。したがって、最終的に行うことは、user1 に切り替えてから、サービスを開始するためにルート権限に昇格することです。私のマシン上の新しいスクリプト。$(pwd)
現在のディレクトリを印刷します。
#!/bin/bash
sudo su - user1 && /usr/bin/sudo echo $(pwd)
実行してみましょう:
[root]$ bash test.sh
[user1]$
貝殻が手に入った!&&
完了を待つ前のコマンドのsudo su -
、つまりルート シェルを提供する です。echo
シェルを終了するまでコマンドは実行されませんでした。
[user1]$ exit
logout
/root
[root]$
それでも、ディレクトリで/root
はなく、ディレクトリが返されました/home/user1
。これは間違いなくあなたが望んでいたものではありません。このスクリプトをcrontabに追加して実行してみてはどうでしょうか。ユーザーとして? これは root の crontab 行になります:
*/5 * * * * user1 /home/user1/new-service-watch.sh
そうすれば、ユーザーを二重に切り替える手間が省けます。スクリプトはcron
asによって開始されuser1
、その後はsudo
実行するだけで済みsystemctl
、その他すべてをそのユーザーとして維持できます。
ちょっとしたアイデアです。そのまま使用しないでください!!!!
編集: リクエストごとに、user1 としてサービスを開始するようにスクリプトを変更します。および定義$sudo_cmd
から削除されました。exec_start
exec_stop
*編集2:sudo
ファイルが root によって所有されている場合は、chowning を使用する必要があります。また、sudo
root がプロセスを開始した場合に備えて、サービスを停止する必要があります。`
#!/bin/bash
sudo_cmd="/usr/bin/sudo" # these are just my paths, change as needed
chown_cmd="$sudo_cmd /usr/bin/chown" # added sudo
systemctl_cmd="/bin/systemctl"
date_cmd="/bin/date"
# if define process before exec_start & exec_stop,
# you can use it in your exec_start & exec_stop definitions
process="new-service"
exec_start="$systemctl_cmd start $process" # don't sudo so it runs as user1
exec_stop="$sudo_cmd $systemctl_cmd stop $process" # added sudo
check1="/root/testing"
username="user1"
log_file="/var/log/new-service-watch.log" # why not log things? :)
# putting the entirety of the execution in
# braces lets you pipe it somewhere easily
{ # start_brace
changeOwnership()
{
echo "$($date_cmd) Changing ownership"
# there is no need to change directory
# because we will use '-R' to be recursive
$chown_cmd -R $username:$username $check1
}
startService()
{
echo "$($date_cmd) Starting $process"
$exec_start
sleep 5
}
stopService()
{
echo "$($date_cmd) Stopping $process"
$exec_stop
sleep 5
}
if ps ax | grep -v grep | grep $process > /dev/null
then
echo "$($date_cmd) Running...No action needed."
else
echo "$($date_cmd) Not running...Going to start the service."
startService
stopService
changeOwnership
startService
fi
} >> "$log_file" # end_brace