Websphere MQ Dead letter queue handler failure - ibm-mq

I am trying to create a dead letter queue handler on linux box with following string
DEFINE SERVICE(dlqhandler) + CONTROL(MANUAL) + DESCR('DLQ Handler Service') +
SERVTYPE(SERVER) + STARTCMD('/home/mqm/dlq/dlqhandler.sh') +
STDOUT('/home/mqm/dlq/dlq.log') +
STDERR('/home/mqm/dlq/dlq.err') +
REPLACE
However service fails to start. Does any one have any idea about this?
Regards
J

This has to do with how the command is executed by WebSphere MQ. When you execute a text file from a shell program, as a convenience the shell looks for a shebang line at the head of the file for a clue as to what executable to run. It then runs the specified program and passes the file as an argument. So, for example, if you run /home/mqm/dlq/dlqhandler.sh and the first line in the script is #! /bin/sh your shell converts this to /bin/sh /home/mqm/dlq/dlqhandler.sh on your behalf and submits it. The effect is to start a new sub-shell and pass it your script file as an argument.
WebSphere MQ uses the OS to directly execute whatever you put in the STARTCMD field. There is no convenient substitution as performed by the shell so if the thing you specify is a script, the OS doesn't know what to do with it. Changing to STARTARG(/bin/sh /home/mqm/dlq/dlqhandler.sh) won't help because the OS sees this not as a command and an argument but as a command with an embedded space.
However, WebSphere MQ does provide a STARTARG parameter for this purpose. If you change to use the following command (assuming that your script's shebang line executes /bin.sh) it should work:
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
UPDATE:
After some testing we discovered that the Linux server was configured to run a restricted shell. This prevented passing arguments with path names and, relevant to this issue, executing anything hosted on a shared drive such as /hom/mqm. In the restricted environment, moving the scripts and logs to a directory under /var/mqm solved the problem.
During the testing we were able to isolate the issue by using shell builtin commands. These have no path or permission issues so ruled out things like filesystem permissions and so forth. For example, STARTCMD('/bin/sh') STARTARG('-c "echo It works"') told us that the QMgr was able to invoke /bin/sh correctly. Changing the script to a single line that read echo It works failed which told us that it wasn't the content of the script but the script itself that was the problem. Using STARTARG('-c set') worked and showed us where the current directory was and the contents of $PATH. Moving the script to the current directory solved the permission problem and some further experimentation showed it wasn't the / in the script path that was failing. The only obvious difference we saw between /home/mqm and /var/mqm was that one was shared and one was a dedicated mount. The final service definition was:
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
Replace subdir above with the path to the rules file. So for example, +MQ_DATA_PATH+subdir/+QMNAME+.rules.table might be +MQ_DATA_PATH+exits/+QMNAME+.rules.table which would expect the rules file in /var/mqm/exits on stock Linux with default install.

Related

Call UniVerse Command from Shell

I have a UniVerse (Rocket U2) system, and want to be able to call certain UniVerse/TCL commands from a shell script. However whenever I run the uv binary it seems to stop the execution of the rest of the shell script.
For Example if I run:
/u2/uv/bin/uv
It starts a UniVerse session. The next line of the script (RUNPY run_tests.py) is meant to be executed in the TCL environment, but is never input to TCL. I have tried passing in string parameters to the uv binary to be executed, but doesn't appear to do anything.
Is there a way to call UniVerse/TCL commands from a UNIX/Shell environment?
You can type this manually or put it into a shell script. I have not run into any issues with this paradigm, but your choice of shell could theoretically affect this. You certainly want to either be in the directory of the account you want execute it in or cd to it in the script.
/u2/uv/bin/uv <<start
RUNPY run_tests.py
start
Good Luck.
One thing to watch out for is if you have a LOGIN paragraph or something else that runs automatically to start your application (which is really common), then you need to find a way to bypass this for non-interactive users.
https://groups.google.com/forum/#!topic/comp.databases.pick/B2hzuXq3X9A mentions
IF OCONV(#TTY,'MCU')='PHANTOM' THEN ABORT
In UD, I kick off scripts from unix as a phantom to a) capture the log output in PH and b) end the process if extra input is requested, rather than hanging around. In UD that's
$echo "PHANTOM COUNT VOC" | udt
UniData Release 8.1 Build: (2008)
Current UniData home is /unidata/ud81/.
Current working directory is /usr/ud81/demo
:PHANTOM COUNT VOC
PHANTOM process 18743448 started.
COMO file is '_PH_/dsiroot45172_18743448'.
:
Critical abort condition found.
$cat _PH_/dsiroot45172_18743448
COUNT VOC
14670 record(s) counted.
PHANTOM process 18743448 has completed.
Van Amburg's answer is the most correct for handling multiple lines of input. The variant I used was instead of the << command for multi-line strings I just added quotes around a single command (single and double quotes both work):
/u2/uv/bin/uv "RUNPY run_tests.py"

bash commands to remote hosts - errors with writing local output files

I'm trying to run several sets of commands in parallel on a few remote hosts.
I've created a script that constructs these commands, and then writes the output in a local file, something along the lines of:
ssh <me>#<ip1> "command" 2> ./path/to/file/newFile1.txt & ssh <me>#<ip2>
"command" 2> ./path/to/file/newFile2.txt & ssh <me>#<ip2> "command" 2>
./path/to/file/newFile3.txt; ...(same repeats itself, with new commands and new
file names)...
My issue is that, when my script runs these commands, I am getting the following errors:
bash: ./path/to/file/newFile1.txt: No such file or directory
bash: ./path/to/file/newFile2.txt: No such file or directory
bash: ./path/to/file/newFile3.txt: No such file or directory
...
These files do NOT exist but will be written. That being said, the directory paths are valid.
The strange thing is that, if I copy and paste the whole big command, then it works without any issue. I'd rather have it automated tho ;).
Any ideas?
Edit - more information:
My filesystem is the following:
- home
- User
- Desktop
- Servers
- Outputs
- ...
I am running the bash script from home/User/Desktop/Servers.
The script creates the commands that need to be run on the remote servers. First thing first, the script creates the directories where the files will be stored.
outputFolder="./Outputs"
...
mkdir -p ${outputFolder}/f{fileNumb}
...
The script then continues to create the commands that will be called on remotes hosts, and their respective outputs will be placed in the created directories.
The directories are there. Running the commands gives me the errors, however printing and then copying the commands into the same location works for some reason. I have also tried to give the full path to directory, still same issue.
Hope I've been a bit clearer.
If this is the exact error message you get:
bash: ./path/to/file/newFile1.txt: No such file or directory
Then you'll note that there's an extra space between the colon and the dot, so it's actually trying to open a file called " ./path/to/file/newFile1.txt" (without the quotes).
However, to accomplish that, you'd need to use quotes around the filename in the redirection, as in
something ... 2> " ./path/to/file/newFile1.txt"
Or the first character would have to something else than a regular space. A non-breaking space perhaps, possible something that some editor might create if you hit alt-space or such.
I don't believe you've shown enough to correctly answer the question.
This doesn't look like a problem with ssh, but the way you are calling the (ssh) commands.
You say that you are writing the commands into a file... presumably you are then running that file as a script. Could you show the code you use to do that. I believe that's your problem.
I suspect you have made a false assumption about the way the working directory changes when you run a script. It doesn't. You are listing relative paths, so its important to know what they are relative to. That is the most likely reason for it working when you copy and paste it... You are executing from a different working directory.
I am new to bash scripting and was building my script based on another one I had seen. I was "running" the command by simply calling the variable where the command was stored:
$cmd
Solved by using:
eval $cmd
instead. My bad, should have given the full script from the start.

Why ./script/generate is needed instead of script/generate in some Rails instruction?

Inside of Bash or Windows (or any other shell), is it needed to do
./script/generate scaffold foo name:string
instead of just using
script/generate ...
? I do see the first form sometimes, but the second form always works for me, on Mac OS X or Ubuntu, even if the PATH doesn't include the . (current directory)
So can the second form always work, so the first form is really not needed? I think for executable, we sometimes use ./a.out to run it... but seems like maybe script/generate doesn't need the ./ in front?
They mean exactly the same thing.
Starting from the current directory, select a subdirectory called 'script' and in it an executable called 'generate' and run it.
The difference is that with ./ you're explicitly specifying the current directory and without it, it's implicit.
There are 2 syntaxes of invocations in POSIX shell:
Running a program by specifying a name and then searching it in PATH enviornment variable - this one is used when program's name has no slashes (/).
Running a program by specifying full path to it manually - absolutely (path starting with /) or relatively (path starting with any other symbol). This one is chosen when program's name includes at least one / - thus it's a path, not just a name of file.
In your case, both ways to invoke - script/generate or ./script/generate are executed using variant #2 - by specifying a path to the program. ./ is an alias to current directory and in some cases it's required to be present (for example, when using cd command, you can't just say cd without argument and expect to change into current directory - cd reserves call without arguments to change to $HOME directory - but you may call cd ./ if you want to cd into current directory), but it's not required in this case of invocation.
you might want to have a look at 4 Ways of Executing a Shell Script and Shell Script Execution Guidlines. The main difference between both styles is:
script/generate ...
won't work if the parent directory of script does not lie in your current PATH environment. (Well this sure depends on how the shell's lookup method is implemented. There might be implementations that - to a last resort - are looking within your current working directory).
EDIT
Ok, I've done some research on this as I myself didn't seem to be knowing what the difference is. So, this is what I've arrived at:
The ./ (dot slash) syntax is an alias for the absolute path of the current working direcotry, so that - with e.g. /home/peter/script being the cwd -
peter#linux:/home/peter/script$./myscript
is expanded to /home/peter/script/myscript. The slash dot alias basically gives the shell a hint at where to find the executable/script.
That hint is what's essential, and that's the reason why
peter#linux:/home/peter$script/myscript
works as well whereas
peter#linux:/home/peter/script$myscript
won't. The former aids the shell in finding the right executable/script by providing some sort of reference point (namely the script directory). The latter, on the other hand, leaves the shell with a possibly ambiguous command, as there could be a homonymous script within the user's $PATH.
So, to come to an end, both of the styles you've asked the difference for do basically the same - giving the shell a hint at where to look for the executable/script. The shell then is able to unambiguously resolve the correct file and will happily execute it.
Have a nice day.
Nothing wrong with those answers except that they are too long - it's just about your PATH. If your path includes '.' then either way would workThat said, it's a bad habit to put '.' in your PATH for security reasons, so stick with './'

not able to run .sh file using java

I have a .sh file which i am trying to run using runtime api.
It runs perfectly if .sh file is under main project folder, but I want it to be accessed from outside the project folder.
example: /home/test/test.sh.
When i try to run this I get /home/test/test.sh not found error
Can anyone tell me how to execute .sh file using runtime accessing the file from local system?
is the .sh file chmoded to be executable?
if its not you could either:
chmod +x /home/test/test.sh
or
when you call the script pass it through sh so:
sh /home/test/test.sh
Runtime.exec() is not a command line
One pitfall to cover with Runtime.exec() is mistakenly assuming that exec() accepts any String that your command line (or shell) accepts. Runtime.exec() is much more limited and not cross-platform. This pitfall is caused by users attempting to use the exec() method to accept a single String as a command line would. The confusion may be due to the fact that command is the parameter name for the exec() method. Thus, the programmer incorrectly associates the parameter command with anything that he or she can type on a command line, instead of associating it with a single program and its arguments.

how to invoke ruby script containing system command with cron job?

I have a ruby script containing system command like http://gist.github.com/235833, while I ran this script from shell, it works correctly, but when I added it to my cron job list, it doesn't work any more, the cron job is like:
10/* * * * * cd /home/hekin; /usr/bin/ruby my_script.rb
any idea what's going wrong with what i've done? Thank you.
Thank you all for your answers.
It's my mistake.
Since I'm using ssh key forwarding on the local machine, while I executed the script from the shell, the ssh key forwarding related environment variables are all sitting there, but from cron job context, those environment variables are missing.
Try to separate the things that might go wrong. The ones I can think of are:
The cron syntax - is the time value given legal and fitting your shell?
Permissions - execute permissions and read permissions for the relevant directory and file
Quoting - what scope does cron cover? Does it run only the first command?
In order to dissect this, I suggest you first run a really simple cron job, like 'ls'. Next run a single-liner script. Next embed your commands in a shell-script file. Somewhere along these lines you should find the problem.
The problem is your environment. While testing in your shell its fully equipped and boosted by your shell environment. While running under cron its very, very stripped down.
Where is the destination "." for your script? I guess it will be "/" and may not "$HOME" thus your script won't be able to write at that location and fails. Try using an absolut path for the destination.

Resources