Showing posts with label Scripting. Show all posts
Showing posts with label Scripting. Show all posts

Monday, February 25, 2013

echoing bash and mysql commands when running in "batch mode"

I was working on doing some migrations on a Linux machine.

Those migrations required me to execute some Unix commands (using a bash script file) and running some SQL statements to make some changes to my MySql DB.

The entire set of commands was to be called from the console after executing a script -t 2>~/mylog.time -a ~/mylog.script command so that the execution output would be saved to a file.

The problem was that the log file did not show the actual commands that where executing, only their output and on the MySql script not even the output was displayed.

So I was looking fro something like the old dos "Echo On" command.

After doing some reading I found the following:
As the first command within my bash script (after the #!/bin/bash) I added the command set -vx.

  •  -v Prints shell input lines as they are read. 
  •  -x Print command traces before executing command. (so that variables names are replaced with their values). 
To disable this echoing set +vx at the end of the bash script.

As previously stated, in my shell script I also wanted to execute some SQL statements on my DB.

So I created a do_sql.sh file that had the following single line:
mysql -u rewardy --password=mypass --database=mydb --default-character-set=utf8.

Redirecting of stdin to this file like ./do_sql.sh < sql_statements.sql got the statements in sql_statements.sql to execute on the DB but I didn't even see the output of the SQL commands (and obviously not the commands themselves either).

To make this work I modified the file do_sql.sh by adding two parameters at the end of the original line: mysql -u rewardy --password=mypass --database=mydb --default-character-set=utf8 -vvv -t


  • -vvv Causes the echoing I wanted
  • -t      forces printing to use the same formatting as used on interactive console sessions
I hope this helps.

Wednesday, July 20, 2011

The function parameter for javascript Array.Sort

I guess If you are reading this you already know that javascript's Array.sort function can take a function parameter.

Did yo ever wander what exactly should this function return ?

well its simple:
This function (which should take two elements from your array) f(e1,e2) should return:
  • any negative number to indicate that its first parameter should appear before (have a smaller index) the second parameter in the sorted array .
  • zero if you are indifferent to the order in which those two elements will appear in the sorted Array
  • any positive number to indicate that its first parameter should appear after (have a larger index) the second parameter in the sorted array .
Using this info you could even sort mixed type arrays and do multilevel sorting (e.g. sort by date and alphabetically within the date).


Monday, July 12, 2010

Beware of javascript String.replace

Here is a problem I encountered a few days ago:

What would you expect the result of the following expression be:

'abc'.replace('b','someUserInput')

Well its easy to guess that it will be the string 'asomeUserInputb', and indeed it will.

however what would happen if instead 'someUserInput' we realy had some some user input?

you would expect it to return the actual user input with 'a' prefixing it and 'c' as its suffix.

I Also guess some of you knew that if instead of 'b' you used a regular expression then some tokens in the replacement string will have a special meaning as in the following table:


Characters  Replacement text
$$ $
$& The matched substring.
$‘The portion of string that precedes the matched substring.
$’The portion of string that follows the matched substring.
$nThe nth capture, where n is a single digit in the range 1 to 9 and $n is not followed by a decimal digit. If n≤m and the nth capture is undefined, use the empty String instead. If n>m, the result is implementation-defined.
$nnThe nnth capture, where nn is a two-digit decimal number in the range 01 to 99. If nn≤m and the nnth capture is undefined, use the empty String instead. If nn>m, theresult is implementation-defined.



What I did not know / expect is for this behavior to occur even when I was using a plain sting as the search value.

In my case I had to do some length based truncation of a user input string, append an ellipsis to it and inject it into a string instead of some place holder.

e.g.
Template string: '<div>$userInputAfterElipsis</div>'
Original User input: 'some long string that said something and a price like 1M$ isideIt'

"luckly" for me, it turned out that the truncation logic truncated the user's input string right after the $ sign and so when I appended an &hellip; (…) to it I ended up with 'some long string that said something and a price like 1M$&helli;' as the new value for the string replacement.
i.e.

'<div>$userInputAfterElipsis</div>'.replace('$userInputAfterElipsis','some long string that said something and a price like 1M$&helli;')

which returns:
'<div>some long string that said something and a price like 1M$userInputAfterElipsishelli;</div>
having replaced the $& in the new value with $userInputAfterElipsis.

so that was the problem. but how should this be resolved? and why should you care?

I will start with the second Q:
You should care because if you use JavaScript you probably also use String.replace and if you do then it might fail to do what you expect in those scenarios where the replacement string is not a fixed string that you know.

As for what can/should be done, well the first thing that comes to mind is that you need to escape those $'s
so how about:
s.replace(original,replacement.replace('$','$$'))
This will not work for two reasons, the first on is that the $ replacement will only replace the first occurrence of a $ sign in the replacement string and the second is that here also the $$ will be interpreted as a single $ so what we do need is actually:
s.replace(original,replacement.replace(/[$]/g,'$$$$'))
now this will work BUT, IMHO, performance-wise it is not such a great solution.

what I ended up doing was using the following:
s.split(original).join(replacement)
this is o.k. as long as you want all the occurrences of original to be replace with replacement. If you want to replace only the first one you should use:
s.replace(original,replacement.replace('$','$$$$'))

As always I hope this will help some one out there in the sea of bits and bytes...

Monday, June 07, 2010

Solution to: Powershell never exists when executed from a batch file / fdbuild

The short story: use <NUL

More details:

I have been using Powershell as part of a build script for a
FlashDevelop project.

The problem was that the Powershell process did not terminate
and so fdbuild.exe did not continue to run.

I searched the web quite a lot until I found the following
two:


They deals with a similar problem that happens when executing
Powershell from WScript.

The explanation given that was that Powershell is waiting for
its STDIN stream to close before it exists and a workaround is
suggested there that fits WScript.

This got me to the following solution for running Powershell
from Flashdevelop/fdbuild/batch:

since IMHO Powershell in those cases does not need any input
from STDIN I assigned NUL as its input stream.

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
-Noninteractive -Command "& {$postbuild = (get-item ((get-item
%1).parent.parent.Fullname + '/postbuild.ps1')); & $postbuild
-outputDir %1 -outputName %2; exit $lastexitcode}" <NUL

I use this in a batch file that is called from the post-build
event using the following command line


$(ProjectDir)\..\postbuild.bat $(OutputDir)
$(OutputName)


I guess I could call Powershell directly from the post-build
command line but this will have to wait.

As far as I know I am the first to suggest this workaround,
please add a link to this post if youare quoting it. Thanks.

 
Clicky Web Analytics