check file for corruption and fallback to golden image if necessary - grub2

How can I check in the grub.cfg file the sha1sum of a file and compare it with a stored number?
If it is equal the image can loaded, if not it should switch back to the golden image
I tried following
myLinuxBin='(hd0,msdos2)/bzImage.bin'
myLinuxBinSha1Sum='d15e1a64c0f5dd24052f0cb38b88c9f5d4c30a6c'
if [ "$(sha1sum ${myLinuxBin})" -eq "${myLinuxBinSha1Sum} ${myLinuxBin}" ]; then
set default="myRunImage"
else
set default="myGoldenImage"
fi
But I get the error message
error: syntax error.
error: Incorrect command.
error: syntax error.
Any idea where the error is or how I can handle file check?
Thanks

this might be better if it is moved to the linux/unix forum since it's BASH scripting, and GRUB.
your problem seems primarily BASH syntax scripting.
it looks like starting with your "$(sha1sum ${myLinuxBin})" is where you want to execute the program that will return the SHA1 hash of whatever you tell it. I believe your syntax here is wrong.
And it may be easier to dump the resulting hash value into a variable, then do a simple BASH if statement such as if [ $hash_value -e $myLinuxBinSha1Sum ]
You would need the correct BASH syntax for executing the sha1sum executable and dumping the output string into a bash variable named hash_value

Related

ns: 217: invalid command name "217" while executing "217"

I am simulating Wireless Sensor Network using NS2.35 and I get an error saying
ns: 217: invalid command name "217"
while executing
"217"
I have no where used such command throughput my tcl file. Can any one help why I get this error?
You've probably used a variable containing a numeric value as a command name, perhaps by putting it at the start of a line or by placing [brackets] around it (because brackets do command substitution). The brackets can be even embedded in a string:
This example demonstrates what I mean:
set xyz 217
puts "This is [$xyz] in brackets"
If you want to print some literal brackets out around a variable, you have to add some backslashes:
set xyz 217
puts "This is \[$xyz\] in brackets"
The problem could also be if you've got a command that returns 217 and you've put brackets around it at the start of a line (or in other places where a command is expected):
proc xyz {} {
return 217
}
[xyz]
You've not shown us your code so which exact possibility it is… we can't tell. But I bet it'll be one of these problems. Tcl cares about its syntax characters, and is very exacting about making sure they do what they say they do.
invalid command name "217" :
"217" is an internal command in your 'ns' executable.
Please tell which changes you made to ns-2.35/, if any. (WSN ?)
And please upload your "wsn.tcl" file to e.g. 'Google Docs'.
ns2

Perl issues regarding mysql:Can't locate object method "connect" and Can't use string ("") as a HASH

I'm currently trying to run NERVE a vaccine development program that is made up of Perl scripts and have trouble getting it to run properly. I've downloaded and installed all prerequisites but every time I reach the mysql step of the code, it crashes, and an error message says: Can't locate object method "connect" via package "Mysql" (perhaps you forgot to load "Mysql"?) at ./NERVE line 340, line 5. I took a look at the code and changed "use mysql" to "use DBI" and "use DBD:mysql" but then I get the error: Can't use string ("") as a HASH ref while "strict refs" in use at /usr/local/lib/perl/5.14.2/DBI.pm line 604, line 5.
I would appreciate if anyone could look the code over for the mysql section and give me advice on how to fix it so I can run the program properly. I tried emailing the developers but no response so I'm hoping you guys can help me.
Below is the perl code for NERVE for the mysql section.
use mysql;
$db=Mysql->connect("$host","$database","$user","$password");
if(!$db || (!$host || !$database || !$user || !$password)){
print "\nAttention: mysql connection parameters are missing or not correct!\n";
print "I need you to specify: host, database, user, password;\n";
print "You can do it now typing them right in that order and separeted only by comma;\n";
print "For example:localhost,Pathogens,sandro,xvzhs\n";
print "So, your Mysql connection settings are (type q to quit):";
while (!($db && $mysql =~ /,/) & $mysql ne "q"){
chomp($mysql = <STDIN>);
die "Ok,let's quit this work! Call me when your mind is clearer about Mysql parameters! Bye :-)\n" if $mysql eq "q";
($host,$database,$user,$password) = split (',',$mysql);
$db=Mysql->connect("$host","$database","$user","$password");
last if($db && $mysql =~ /,/);
print "\nMysql connection settings still not correct!\n";
print "Remember: host, database, user, password, separeted only by comma.\n";
print "For example:localhost,Pathogens,sandro,xvzhs\n";
print "Please, try again:";
}
print "Ok, Mysql connection to \"$database\" database was successful!\n";
}
The error message is correct. You are attempting to use a module named , but you never loaded it. Change
use mysql;
to
use Mysql;
to use that module. In the comments, you mention that results in
Can't locate Mysql.pm in #INC
Unless you have reason to believe the module is installed, that indicates it needs to be installed[1]
That module used to be part of the DBD-mysql distribution, but it's obsolete. It's so ancient it was removed from DBD some years ago. To obtain it, you will need to downgrade your DBD-mysql distribution to version 3.0008.
That's pretty awful thing to do. The script should have DBI instead.
cjm points
since the Mysql.pm in 3.0008 is just a compatibility layer using DBI under the hood, you should be able to install Mysql.pm & Mysql/Statement.pm from that old dist along with a current DBD-mysql.
So if you extract Mysql.pm from the distro I linked above as /usr/lib/perl5/Mysql.pm and Mysql/Statement.pm as /usr/lib/perl5/Mysql/Statement.pm, you should have an easy pain-free solution.
In newer versions of Perl, the error message has been improved. It now reads as follows:
Can't locate Mysql.pm in #INC (you may need to install the Mysql module)

GNU make call function with multiple arguments and multiple commands

I am trying to write a GNU make call function (example below) which has multiple shell commands to execute, such that it can be called with different arguments.
shell_commands = $(shell echo $(1); ls -ltr $(2))
try:
$(call shell_commands,$(FILE1),$(FILE2))
1) Is above the correct way to write a call function with multiple commands? By using a semi-colon to separate them? To make it readable, I write my targets as shown below. Is there a similar way to write a call function?
shell_commands:
echo $(1)
ls -ltr $(2)
2) I get this error from make when I execute make -B try. It looks like it is trying to execute /home/user/file1. But why?
make: execvp: /home/user/file1: Permission denied
make: *** [try] Error 127
3) Is it possible to pass variable number of parameters to a call function? Like pass in just the second parameter and not the first one.
$(call shell_commands,,$(FILE2))
I tried google-ing, searching on SO, and looking on gnu.org but I did not get any solutions. Will appreciate any answers or pointers to any resources which document call function with multiple optional arguments and commands.
Question 1: No, this is not right. The shell make function should NEVER be used inside a recipe: the recipe is already running in the shell, so why would you run another shell? It's just confusing. Second, it's generally recommended to use && between multiple commands in a recipe, so that if the first command fails the entire command will immediately fail, rather than continuing on and perhaps succeeding. Of course, that is not always correct either, it depends on what you're trying to do.
Question 2: This happens because the shell make function is like backticks in the shell: it expands to the output printed by the shell command it runs. Your shell command that make runs is:
echo $(1); ls -ltr $(2)
(where, one assumes, $1 expands to /home/user/file1) which prints the string /home/user/file1. After the expansion, that string is substituted into the recipe and make tries to run that recipe, giving the error you see above.
You want this, most likely:
shell_commands = echo $(1) && ls -ltr $(2)
try:
$(call shell_commands,$(FILE1),$(FILE2))
Now the call expands to the actual text, not an invocation of make's shell function, and then that text is run as the recipe.
Question 3: Sure, just using empty parameters means that the variable $1 (in this case) expands to the empty string.

IF and ! = ns2 error

I have a problem with path in a tcl file. I tried to use
source " /tmp/mob.tcl "
and this path in bash file :
/opt/ns-allinone-2.35/ns-2.35/indep-utils/cmu-scen-gen/setdest/setdest -v 1 -n $n -p 10 -M 64 -t 100 -x 250 -y 250 >> /tmp/mob.tcl
The terminal give me this output:
..."
(procedure "source" line 8)
invoked from within
"source "/tmp/mob.tcl" "
(file "mobilita_source.tcl" line 125)
How I can do this?
Firstly, this:
source " /tmp/mob.tcl "
is very unlikely to be correct. The spaces around the filename inside the quotes will confuse the source command. (It could be correct, but only if you have a directory in your current directory whose name is a single space. That's really unlikely, unless you're a great deal more evil than I am.)
It really helps a lot if you stop making this error.
Secondly, the error message is both
Incomplete, with just an ellipsis instead of a full error on the first line
Really worrying, with source claimed to be a procedure (second line of that short trace).
It's legal to make a procedure called source, and sometimes the right thing to do, but if you're doing it then you have to be ever so careful to duplicate the semantics of the standard Tcl command or odd things will happen.
Thirdly, you've got a file of what is apparently generated code, and you're hitting a problem in it, and you're not telling us what is on/around line 125 of the file (the error trace is pretty clear on that front) or in the contents of the source procedure (which is non-standard; the standard source is implemented in C) and you're expecting us to guess what's going wrong for you??? Seriously?
Tcl error traces are usually quite clear enough for you to figure out what went wrong and where. If there's an unclear error, and it didn't come from user code (by calling error or return -code error) then let us know; we'll help (or possibly even change Tcl to make things clearer in the future). But right now, there's a complete shortage of information.
Here's an example of what a normal source error looks like:
% source /tmp/foo/bar/boo
couldn't read file "/tmp/foo/bar/boo": no such file or directory
% puts $errorInfo
couldn't read file "/tmp/foo/bar/boo": no such file or directory
while executing
"source /tmp/foo/bar/boo"
If a script generates an error directly, it's encouraged to be as clear as that, but we cannot enforce it. Sometimes you have to be a bit of a detective yourself…

In Tcl, what is the equivalent of "set -e" in bash?

Is there a convenient way to specify in a Tcl script to immediately exit in case any error happens? Anything similar to set -e in bash?
EDIT I'm using a software that implements Tcl as its scripting language. If for example I run the package parseSomeFile fname, if the file fname does't exist, it reports it but the script execution continues. Is there a way that I stop the script there?
It's usually not needed; a command fails by throwing an error which makes the script exit with an informative message if not caught (well, depending on the host program: that's tclsh's behavior). Still, if you need to really exit immediately, you can hurry things along by putting a trace on the global variable that collects error traces:
trace add variable ::errorInfo write {puts stderr $::errorInfo;exit 1;list}
(The list at the end just traps the trace arguments so that they get ignored.)
Doing this is not recommended. Existing Tcl code, including all packages you might be using, assumes that it can catch errors and do something to handle them.
In Tcl, if you run into an error, the script will exit immediately unless you catch it. That means you don't need to specify the like of set -e.
Update
Ideally, parseSomeFile should have return an error, but looks like it does not. If you have control over it, fix it to return an error:
proc parseSomeFile {filename} {
if {![file exists $filename]} {
return -code error "ERROR: $filename does not exists"
}
# Do the parsing
return 1
}
# Demo 1: parse existing file
parseSomeFile foo
# Demo 2: parse non-existing file
parseSomeFile bar
The second option is to check for file existence before calling parseSomeFile.