我有一个sh
脚本在我们的服务器上运行。
它以nohup
从另一个脚本开始,这样我就可以轻松关闭会话并且仍然可以运行
主脚本(将启动此脚本)也是sh
脚本。它可以用两个参数执行:
--start (will start application)
--stop (will stop it using kill PID)
但是由于应用程序是由我启动的,否则其他任何人(除了root)都不能停止已经运行的实例或重新启动它。
所以我在考虑将所有者更改为nobody
。这有帮助吗?如果是,那怎么办呢?
答案 0 :(得分:4)
设置脚本以关闭某些事件,而不是直到被杀死。然后让主脚本在--stop
触发该事件(事件可以像创建特定文件一样简单,或者更复杂的事情,比如将命令写入脚本定期读取的fifo)。这样,无论是谁启动了脚本,其他用户都应该能够关闭脚本。
如何执行此操作取决于脚本的详细信息。如果它没有可以检查关闭条件本身的循环,那么你可以做一些事情,比如它会产生一个后台进程来定期检查条件并在遇到时杀死它的父pid。
答案 1 :(得分:2)
特别为运行此脚本设置用户。
使用以下命令运行脚本:
su -l <user> -c "<command>"
<强>更新强>
提出这种方法假设修改有问题的脚本不是一种选择。
答案 2 :(得分:2)
将所有者更改为nobody
当然有助于您的目标。下面描述了使用专用帮助程序执行此操作的一种方法,该程序对用户不可见。
解决方案:您可以使用setuid程序确保脚本始终以同一用户身份运行。由于安全原因,您可能不允许制作shell脚本setuid,但您可以编写一个简单的启动程序,可能在C:
#include <stdio.h>
#include <unistd.h>
#define PROG "./daemon.sh"
int main(int argc, char** argv)
{
char action[32];
if (argc < 2) {
fprintf(stderr, "Usage: %s { --start | --stop }n", argv[0]);
return 0;
}
snprintf(action, sizeof(action), "%s-the-real-thing", argv[1]);
return execl(PROG, PROG, action, (char *)0);
}
这里我们假设您的脚本名为daemon.sh
,并且位于运行脚本的同一目录中。您可以根据需要使用完整路径或以其他明显方式进行更改。
编译并生成如下的setuid(假设此处名称为launcher.c
,我们决定以nobody
运行):
$ gcc -Wall launcher.c -o launcher
$ sudo chown nobody launcher
$ sudo chmod u+s launcher
您需要稍微修改您的shell脚本守护程序:
#!/bin/sh
prog=$(basename $0)
start()
{
i=0
while :; do
i=$(expr $i + 1)
echo "Daemon working like a mad horse... ($i)"
sleep 1
done
}
stop()
{
pids=$(ps axu | grep "$prog.*--start" | grep -v grep | awk '{print $2}')
echo "Killing [$pids]"
[ -n "$pids" ] && exec /bin/kill -KILL $pids
}
case "$1" in
--start|--stop) exec ./launcher $1;;
--start-the-real-thing) start;;
--stop-the-real-thing) stop;;
*) echo "Bad argument \"$1\"";;
esac
这里start
函数是完成所有有趣的funk,直到你通过调用stop
函数来杀死程序。从任何地方运行此操作都需要进行一些明显的更改,我希望您现有的kill
逻辑更加优雅。
用法与之前类似:
./daemon.sh --start
./daemon.sh --stop
说明:上述内容将分别执行./launcher --start
或./launcher --stop
。这会将有效用户更改为nobody
(或您选择设置程序的任何内容),并执行将执行所需原始操作的./daemon.sh --start-the-real-thing
或./daemon.sh --stop-the-real-thing
。
因为简单的启动程序只允许运行命名脚本,所以安全性很容易控制(只是为了确保,您可以在启动程序中检查argv[1]
确实是--start
或{{ 1}},然后可以运行两个命令行组合作为)。
答案 3 :(得分:-1)
您可以尝试以下选项:
在我看来,第三种方法是三种方法中最干净的方法。
编辑:由于'主进程'实际上是一个shell脚本,'thread'将更改为子shell。 &安培;要等待的子线程将是简单的'cat fifo'。
答案 4 :(得分:-2)
如果您具有root访问权限,则可以使用sudo
并将其配置为允许以root身份运行带有--stop
参数的脚本。