我有一个编译为单个二进制文件的 go web 应用程序,我试图通过 init.d 进行管理。这是我的 init.d 脚本:
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/my-go-app
DAEMON_ARGS="--logFile /var/log/my-go-app/my-go-app.log"
NAME=my-go-app
DESC=my-go-app
RUNDIR=/var/run/my-go-app
PIDFILE=$RUNDIR/my-go-app.pid
test -x $DAEMON || exit 0
if [ -r /etc/default/$NAME ]
then
. /etc/default/$NAME
fi
. /lib/lsb/init-functions
set -e
case "$1" in
start)
echo -n "Starting $DESC: "
mkdir -p $RUNDIR
touch $PIDFILE
chown ubuntu:ubuntu $RUNDIR $PIDFILE
chmod 755 $RUNDIR
if [ -n "$ULIMIT" ]
then
ulimit -n $ULIMIT
fi
if start-stop-daemon --start --quiet --umask 007 --pidfile $PIDFILE --chuid ubuntu:ubuntu --exec $DAEMON -- $DAEMON_ARGS
then
echo "$NAME."
else
echo "failed"
fi
;;
stop)
echo -n "Stopping $DESC: "
if start-stop-daemon --stop --retry forever/TERM/1 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
then
echo "$NAME."
else
echo "failed"
fi
rm -f $PIDFILE
sleep 1
;;
restart|force-reload)
${0} stop
${0} start
;;
status)
echo -n "$DESC is "
if start-stop-daemon --stop --quiet --signal 0 --name ${NAME} --pidfile ${PIDFILE}
then
echo "running"
else
echo "not running"
exit 1
fi
;;
*)
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
问题是,当我运行 service my-go-app start 时,它只是挂起,如下所示:
ubuntu@ip-10-0-0-40:~$ service my-go-app start
Starting my-go-app:
永远不会回来。在这种状态下,如果我打开一个单独的终端,我可以通过检查日志文件看到应用程序正在运行,但是/var/run/my-go-app/my-go-app.pid 中没有任何内容(尽管pid 文件确实被创建了)。
有没有人遇到过(并希望解决过)这个问题?如何将我的 go 应用作为 init.d 守护进程运行?
编辑:
我能够通过在启动服务时将“-b -m”命令行标志添加到 start-stop-daemon 来让它工作。该行现在看起来像这样:
start-stop-daemon -b -m --start --quiet --umask 007 --pidfile $PIDFILE --chuid ubuntu:ubuntu --exec $DAEMON -- $DAEMON_ARGS
我对这种方法的担忧是 start-stop-daemon 联机帮助页中的警告:
-b, --background
Typically used with programs that don't detach on their own. This option will force start-stop-daemon to fork before starting the process, and
force it into the background. WARNING: start-stop-daemon cannot check the exit status if the process fails to execute for any reason. This is
a last resort, and is only meant for programs that either make no sense forking on their own, or where it's not feasible to add the code for
them to do this themselves.
这对我来说似乎是个坏主意,因为听起来 SysV 不知道进程是否终止。我理解正确吗?有没有其他人尝试过这种方法?
最佳答案
如果您正在运行带有 Upstart 的系统,您可以使用此脚本:
start on runlevel [2345]
stop on runlevel [016] or unmounting-filesystem
# Replace {soft} and {hard} with the soft and hard resource limits you desire
#limit nofile {soft} {hard}
umask 007
setuid ubuntu
setgid ubuntu
exec /usr/bin/my-go-app --logFile /var/log/my-go-app/my-go-app.log
您还可以在您的应用程序已启动并正确初始化的位置将以下代码添加到您的守护程序中:
if ("yes" == os.Getenv("MYAPP_RAISESTOP")) {
p, err := os.FindProcess(os.Getpid())
p.Signal(syscall.SIGSTOP)
}
以及上述 upstart 工作的以下行:
env MYAPP_RAISESTOP="yes"
expect stop
如果 if () { } 不是真正的 Go 语法,我很抱歉;我是一个 C 程序员哈哈(虽然 () 和 {} 里面的东西是真实的,我做了一点研究:)。
最后一点确保 Upstart 会等到您的应用程序正确设置后才会触发 started 事件。如果没有其他工作在等待您的应用程序,那么您真的不需要它。
关于golang webapp init.d 脚本挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25494400/
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚
我有一个在Linux服务器上运行的ruby脚本。它不使用rails或任何东西。它基本上是一个命令行ruby脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
有没有一种简单的方法可以判断ruby脚本是否已经在运行,然后适本地处理它?例如:我有一个名为really_long_script.rb的脚本。我让它每5分钟运行一次。当它运行时,我想看看之前运行的是否还在运行,然后停止第二个脚本的执行。有什么想法吗? 最佳答案 ps是一种非常糟糕的方法,并且可能会出现竞争条件。传统的Unix/Linux方法是将PID写入文件(通常在/var/run中)并在启动时检查该文件是否存在。例如pid文件位于/var/run/myscript.pid然后你会在运行程序之前检查它是否存在。有一些技巧可以避免
我正在开发一个Ruby脚本,需要在没有Ruby解释器的情况下部署到系统上。它将需要在使用ELF格式的FreeBSD系统上运行。我知道有一个ruby2exe项目可以编译在Windows上运行的ruby脚本,但是在其他操作系统上这样做容易吗?甚至可能吗? 最佳答案 您是否检查过Rubinius或JRuby是否允许您预编译您的代码? 关于ruby-ruby脚本可以预编译成二进制文件吗?,我们在StackOverflow上找到一个类似的问题: https://
我目前可以将stdout重定向到ruby/rails中的字符串变量,只需在bash中运行命令并将结果设置为我的字符串变量,如下所示。val=%x[#{cmd}]其中cmd是表示bash命令的字符串。但是,这仅捕获stdout,因为我想捕获stderr并将其设置为ruby中的字符串——有什么想法吗? 最佳答案 简单地重定向它:val=%x[#{cmd}2>&1]如果您只想从stderr捕获输出,请在将其复制到fd2后关闭stdout的文件描述符。val=%x[#{cmd}2>&1>/dev/null]
我们如何从ruby脚本返回值?#!/usr/bin/envrubya="test"a我们如何在Ubuntu终端或java或c中访问'a'的值? 最佳答案 在ruby/python脚本中打印你的变量,然后可以通过示例从shell脚本中读取它:#!/bin/bashruby_var=$(rubymyrubyscript.rb)python_var=$(pythonmypythonscript.py)echo"$ruby_var"echo"$python_var"注意你的ruby/python脚本只打印这个变量(有更多复杂的方
我在跑Fastlane(适用于iOS的持续构建工具)以执行用于解密文件的自定义shell脚本。这是命令。sh"./decrypt.shENV['ENCRYPTION_P12']"我想不出将环境变量传递给该脚本的方法。显然,如果我将密码硬编码到脚本中,它就可以正常工作。sh"./decrypt.shmypwd"有什么建议吗? 最佳答案 从直接Shell中扩展假设这里的sh是一个faSTLane命令,它以给定的参数作为脚本文本调用shell命令:#asafastlanedirectivesh'./decrypt.sh"$ENCRYPTI
我希望这些值匹配。当shell脚本由于某些错误条件而退出时(因此返回非零值),它们不匹配。壳$?返回1,ruby$?返回256。>>%x[lskkr]ls:kkr:Nosuchfileordirectory=>"">>puts$?256=>nil>>exitHadoop:~Madcap$lskkrls:kkr:NosuchfileordirectoryHadoop:~Madcap$echo$?1 最佳答案 在Ruby中$?是一个Process::Status实例。打印$?等同于调用$?.to_s,这等同于$?.to_i.to_s(来
我有一个Ruby文件,我将它作为rubyfile.rb"parameters"运行。我更喜欢将它作为regtask参数运行,而不必每次都包含ruby和文件名。我希望它与ls处于同一级别。我将如何做到这一点? 最佳答案 编辑你的文件,确保这是第一行,这样你的系统就知道如何执行你的文件:#!/usr/bin/envruby接下来,更改文件的权限以使其可执行:chmoda+xfile.rb最后,重命名并将其移动到将要执行的位置,而无需编写其完整路径:mkdir-p~/binmvfile.rb~/bin/regtask(如果~/bin存在,