Why do OpenShift action hook scripts fail with strange errors? - openshift

I renamed an action_hook from a non-cartridge-specific action hook (such as post_restart) to be cartridge-specific (such as post_restart_cron) and then encountered strange new errors such as:
/var/lib/openshift/${USER}/app-root/runtime/repo/.openshift/action_hooks/post_restart_cron: line 5: `firstcron-secondcron': not a valid identifier
The script file post_restart_cron is:
#!/bin/bash
function firstcron-secondcron {
echo in function
}

The issue is that non-cartridge-specific action hooks apparently run bash in non-POSIX mode which allows hyphens in function names, but cartridge-specific action hooks run bash in POSIX mode which does not allow hyphens in function names.
Why do cartridge-specific action hooks run bash in POSIX mode? I'm not 100% sure, but I think the following occurs:
v2_cart_model.rb:cartridge_hooks remembers the hook as source <hook filepath>.
v2_cart_model.rb:do_control_with_directory creates a command string set -e; <path to control script> <action> <other args>; source <hook filepath>.
It probably passes that string to sh -c which runs in POSIX mode and because it uses source, it reads the script directly instead of running it in a new process (which would read the #!/bin/bash line and run /bin/bash which is by default non-POSIX mode).
There must be something different about the non-cartridge-specific codepath in v2_cart_model.rb that avoids the steps above.
My solution was to use unset POSIXLY_CORRECT in my script which disabled POSIX mode.
I debugged this issue by running the set command in my script which showed a variety of bash variables leading to investigations that I used the process of elimination on.

Related

Tcl: Get stdout from exec bash

Within tclsh I can run the following and get the expected output:
% exec bash -c "ulimit -v"
50331648
However within a Tcl script nothing is returned. No error, no output, nothing. There's clearly some gotcha with exec'ing 'bash -c' that I can't work out.
Alternatively, is there a native way in Tcl that I can get the system's memory limit to avoid having to do it this way in the first place?
In an interactive tclsh session, the REPL helpfully prints the output of commands/expressions. That's not the case in a non-interactive program.
exec returns the output of the command: you just need to capture it with the usual command substitution:
set output [exec bash -c "ulimit -v"]
puts $output
The code that you wrote should work; I can't identify why bash would silently fail to run ulimit -v. Even if the script was running in an environment where that was privileged information (why!?) one would still expect to get an error message of some form. That's a very weird problem!
Tcl's base command set doesn't expose any access to memory limits, whether for reading or writing. The simplest workaround that doesn't call an external program is the tclbsd package (apparently it mostly works on most other Unixes as well), which exposes a command that should help:
package require BSD
set limit [bsd::rlimit get soft virtual]

How to launch Sublime and define the file syntax in one go?

Sound as lazy as it is I was wondering if it's possible to open a file with sublime using (command line) and in the same command define the expected syntax.
Lets say on a mac we have the subl command installed, so running $ subl .bash_something will open the .bash_something then we have to chose the "shel script(bash)" syntax from the list. what would be really nice (for laze me) is to include the syntax to the command as an argument. i.e.
$ subl -x bash .bash_something
or something like that. this obviously doesn't work but I was wondering if there is similar solution or if its possible to include one
Unfortunately, there is no way that I can find to dynamically set the syntax from the command line. subl has the --command option, which allows you to run a Sublime command while loading the file, directory, or project indicated. However, the command to change the syntax of a view - set_file_type - takes an argument of the form ("syntax": "Packages/PackageName/SyntaxName.sublime-syntax") (or SyntaxName.tmLanguage). As far as I've been able to tell, you simply can't pass arguments to commands run via the command line. I've opened an issue to request an enhancement.
Now, this doesn't mean that all is lost. If you have just a few filetypes that are unknown to Sublime, open them, then select View -> Syntax -> Open all with current extension as... and select the syntax you want. If for some reason this isn't sufficient, or would like finer-grained control over exactly which filenames (not just which extensions) get opened as what, check out the ApplySyntax plugin. It allows you to use regexes to open exactly which file patterns you define as what syntax.
Commands can take arguments in Sublime 3 now. I was able to achieve this functionality with a bash function.
You can pass arguments to the --command option with inline JSON and escaped quotes. This command will change the syntax to Bash for the current active file in Sublime:
subl --command "set_setting {\"setting\": \"syntax\", \"value\": \"Packages/ShellScript/Shell-Unix-Generic.sublime-syntax\"}"
I created a simple bash function and sourced it in my .bash_profile to wrap these two commands together to activate/open a file then change the synax:
function subl_bash() {
subl "$1" && subl --command "set_setting {\"setting\": \"syntax\", \"value\": \"Packages/ShellScript/Shell-Unix-Generic.sublime-syntax\"}"
}

InstallShield 2014, Custom Actions and executing sql files into MySQL

I am building an installer for our product which works well. I've managed to build custom actions to install our services including a MySQL server.
The problem I have is executing a sql file to build the schema structures.
I have a custom action which uses mysql.exe and the command line arguments:
--port=### --user=### --password=### < "[INSTALLDIR]db\EmptyStruct.sql"
It tries to execute this ok but the cmd window which pops up, during the install, just runs through the mysql.exe command line options, which says to me that the command line it gets passed is not correct. However if I run the command manually after the install, it works perfectly.
Does anyone has any ideas please.
I'm making a few assumptions here:
You have a Windows Installer exe custom action that specifies mysql.exe and a command line as you showed
You are expecting the contents of [INSTALLDIR]db\EmptyStruct.sql to be redirected to mysql.exe's standard input
This will not happen. Behind the scenes, Windows Installer's exe custom action support uses the CreateProcess API and this API will interpret command lines literally. However the redirect < needs special handling to actually perform redirection.
To get that behavior, you must use a layer of indirection. For example, you could run cmd.exe as the exe, and give it a command line that will make it interpret and run the command line mysql.exe --port= ... < "[INSTALLDIR]...". However, if you didn't already have a command prompt showing, this would cause one to show up. If you want to avoid that, you could write a custom wrapper that performs the redirection for you, either as a C++ DLL or, say, InstallScript action.
Alternately, if there is a parameter that tells mysql.exe to run a script from a file, you could pass that instead of using redirection. I wasn't able to find evidence of such a parameter in a quick web search.
Thanks for your comments Michael and I used cmd.exe /k AddStruct.bat to accomplish the task!

No syntax highlighting with org-html-export-to-html when executing with systemd service

I have a bash script that finds and exports emacs .org files to html in a given directory. I understand that org-mode makes use of htmlize.el to color the output of text in SRC blocks, which seems to work fine when executed from the command line, both as root and normal user. However, when using systemd timers to automate this task the output is no longer colored.
for i in `find /home/user/dir -name '*.org'`
do
emacs $i --batch -l /home/user/.emacs org-html-export-to-html --kill
done
I previously had problems with getting the syntax highlighting to work when executing the script directly, which was solved when -l /home/user/.emacs was added as shown in the excerpt above (publishNotes.sh).
Everything apart from the syntax highlighting seems to be working fine, which indicates that both the systemd service and the executed script itself runs according to the timer.
Service:
[Unit]
Description=Update website
[Service]
Type=simple
ExecStart=/home/user/bin/publishNotes.sh
Timer:
[Unit]
Description=Run every hour
[Timer]
OnCalendar=hourly
Unit=publishNotes.service
[Install]
WantedBy=multi-user.target
Thanks!
I would guess that this is because something is loading differently when run as root than when run under your user account. Exactly what is hard to say from the information given. However, my first suggestion would be to try running the service as your user. Try adding the User=<username> key to the [Service] section of the service, and check to see if it behaves as you expect.

Why tcl script runs as shell script?

I don't program in TCL but I do use them such as tkcvs and tkdiff. I notice that they declare themselves as shell script
#!/bin/sh
#-*-tcl-*-
What's more, running them through tclsh doesn't work either and I get error like this:
Initialization failed
The second line in the header baffles me too because AFAIK, shell only looks at the #! line. How's this working?
Tcl scripts are normally setup to run using slightly more than you have shown. It is typically and most robustly done like the following:
#!/bin/sh
# \
exec tclsh "$0" ${1+"$#"}
They use the shell initially because there was no standard installation location for tcl so the location could not be relied on. Instead, by starting the system shell and using that to start the tclsh executable you could be certain to run the installed tclsh as long as it was present on the PATH. The shell evaluates the script and sees the exec tclsh "$0" which causes it to execute the installed tclsh binary and pass it $0 (the script file name) as the first argument, which re-runs the script using the tcl interpreter.
The second line in my example comments out the third line when the script is evaluated by the tcl interpreter. The backslash causes the second and third lines to be treated as a single comment when read by tclsh so that tcl doesn't try and run the exec again.
In your snipped the # -*-tcl-*- is marker to indicate the mode to be used by emacs when editing the file. See the documentation.
There is not really enough to go on for the error message. It doesn't seem to be from the Tcl interpreter itself. (That is 'git grep' in the tcl sources does not match that string).