这与 WebSphere MQ 如何执行命令有关。当您从 shell 程序执行文本文件时,为方便起见,shell 会在文件开头查找 shebang 行,以获取有关要运行什么可执行文件的线索。然后它运行指定的程序并将文件作为参数传递。因此,例如,如果您运行/home/mqm/dlq/dlqhandler.sh
并且脚本中的第一行是#! /bin/sh
您的 shell/bin/sh /home/mqm/dlq/dlqhandler.sh
代表您将其转换为并提交它。效果是启动一个新的子外壳并将其作为参数传递给您的脚本文件。
WebSphere MQ 使用操作系统直接执行您在STARTCMD
现场放置的任何内容。没有由 shell 执行的方便替换,因此如果您指定的内容是脚本,操作系统不知道如何处理它。更改为STARTARG(/bin/sh /home/mqm/dlq/dlqhandler.sh)
将无济于事,因为操作系统不将其视为命令和参数,而是将其视为具有嵌入式空间的命令。
但是,WebSphere MQ 确实STARTARG
为此目的提供了一个参数。如果您更改为使用以下命令(假设您的脚本的 shebang 行执行/bin.sh
)它应该可以工作:
DEFINE SERVICE(dlqhandler) +
CONTROL(MANUAL) DESCR('DLQ Handler Service') +
SERVTYPE(SERVER) STARTCMD('/bin/sh') +
STARTARG('/home/mqm/dlq/dlqhandler.sh') +
STDOUT('/home/mqm/dlq/dlq.log') +
STDERR('/home/mqm/dlq/dlq.err') +
REPLACE
更新:
经过一些测试,我们发现 Linux 服务器被配置为运行受限 shell。这阻止了使用路径名传递参数,并且与此问题相关,执行托管在共享驱动器上的任何内容,例如/hom/mqm
. 在受限环境中,将脚本和日志移动到目录下/var/mqm
解决了问题。
在测试期间,我们能够通过使用 shell 内置命令来隔离问题。这些没有路径或权限问题,因此排除了文件系统权限等问题。例如,STARTCMD('/bin/sh') STARTARG('-c "echo It works"')
告诉我们 QMgr 能够/bin/sh
正确调用。将脚本更改为读取失败的单行,echo It works
这告诉我们问题不是脚本的内容,而是脚本本身。使用STARTARG('-c set')
工作并向我们展示了当前目录在哪里以及$PATH
. 将脚本移动到当前目录解决了权限问题,并且一些进一步的实验表明它不是/
脚本路径中的失败。我们看到的唯一明显的区别是/home/mqm
和/var/mqm
一个是共享的,一个是专用的。最终的服务定义是:
DEFINE SERVICE(dlqhandler) +
CONTROL(QMGR) DESCR('DLQ Handler Service') +
SERVTYPE(SERVER) STARTCMD('/bin/sh') +
STARTARG('-c "+MQ_INSTALL_PATH+bin/runmqdlq < +MQ_DATA_PATH+subdir/+QMNAME+.rules.table"') +
STDOUT('+MQ_DATA_PATH+subdir/dlq.+QMNAME+.log') +
STDERR('+MQ_DATA_PATH+subdir/dlq.+QMNAME+.err') +
STOPCMD('+MQ_INSTALL_PATH+bin/amqsstop') +
STOPARG('-m +QMNAME+ -p +MQ_SERVER_PID+') +
REPLACE
将subdir
上面替换为规则文件的路径。因此,例如,+MQ_DATA_PATH+subdir/+QMNAME+.rules.table
可能+MQ_DATA_PATH+exits/+QMNAME+.rules.table
会期望在/var/mqm/exits
默认安装的股票 Linux 上使用规则文件。