我正在尝试编写一个脚本,将其放置在 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
关于这个函数的两点:
事情执行顺序不对。单个
&
命令使启动任务处于后台。您确定要这样做吗?您不想等待进程完成启动后再停止它吗?我知道您输入了sleep
s,但我认为等待它退出更好。如果命令没有及时完成,事情可能会变得非常奇怪。注意它没有打印
Rest of Script
。该exit
命令不会退出该函数,而是退出整个脚本。
您有/usr/bin/sudo su - user1 && $exec_start
。我不认为这是您想要做的。您设置了exec_start="sudo systemctl start new-service"
。因此,您最终要做的是切换到 user1,然后提升到 root 权限以启动服务。新脚本,在我的计算机上。$(pwd)
将打印当前目录。
#!/bin/bash
sudo su - user1 && /usr/bin/sudo echo $(pwd)
让我们执行它:
[root]$ bash test.sh
[user1]$
我得到了一个 shell!&&
等待完成上一个命令的执行结果,即sudo su -
,它提供了一个 root shell。echo
直到我离开 shell 后,该命令才执行:
[user1]$ exit
logout
/root
[root]$
即使如此,它给出的也是/root
目录,而不是/home/user1
。这绝对不是你想要的。如何将此脚本添加到 crontab 中运行作为用户? 这将是 root 的 crontab 行:
*/5 * * * * user1 /home/user1/new-service-watch.sh
这样,您就不必进行双重切换用户操作了。脚本将以cron
身份启动user1
,然后您只需 即可sudo
运行systemctl
,并以该用户身份保留其他所有内容。
这是一个简单的想法。请不要按原样使用!
编辑:根据要求,将脚本更改为以用户 1 的身份启动服务。$sudo_cmd
从exec_start
和exec_stop
定义中删除。
*edit2: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