How to print variable inside function - perl

I'm using RRDs::Simple function and it needs bunch of parameters.
I have placed these parameters in a special variable (parsing, sorting and calculating data from a file) with all quotes, commas and other stuff.
Of course
RRDs::create ($variable);
doesn't work.
I've glanced through all perl special variables and have found nothing.
How to substitute name of variable for the data that contained in that variable?
At least could you tell me with what kind of tools(maybe another special variables) it can be done?

Assuming I'm understanding what you're asking:
You've build the 'create' data in $variable, and are now trying to use RRDs::create to actually do it?
First step is:
print $variable,"\n"; - to see what is actually there. You should be able to use this from the command line, with rrdtool create. (Which needs a filename, timestep, and some valid DS and RRA parameters)
usually, I'll use an array to pass into RRDs::create:
RRDs::create ( "test.rrd", "-s 300",
"DS:name:GAUGE:600:U:U", )
etc.
If $variable contains this information already, then that should be ok. The way to tell what went wrong is:
if ( RRDs::error ) { print RRDs::error,"\n"; }
It's possible that creating the file is the problem, or that your RRD definitions are invalid for some reason. rrdtool create on command line will tell you, as will RRDs::error;

Related

use a variable with whitespace Perl

I am currently working on a project but I have one big problem. I have some picture with a whitespace in the name and I want to do a montage. The problem is that I can't rename my picture and my code is like that :
$pic1 = qq(picture one.png);
$pic2 = qq(picture two.png);
my $cmd = "C:\...\montage.exe $pic1 $pic2 output.png";
system($cmd);
but because of the whitespace montage.exe doesn't work. How can I execute my code without renaming all my pictures?
Thanks a lot for your answer!
You can properly quote the filenames within the string you pass to system, as #Borodin shows in his answer. Something like: system("montage.exe '$pic1' '$pic2'")
However, A more reliable and safer solution is to pass the arguments to montage.exe as extra parameters in the system call:
system('montage.exe', $pic2, $pic2, 'output.png')
Now you don't have to worry about nesting the correct quotes, or worry about files with unexpected characters. Not only is this simpler code, but it avoids malicious injection issues, should those file names ever come from a tainted source. Someone could enter | rm *, but your system call will not remove all your files for you.
Further, in real life, you probably are not going to have a separate scalar variable for each file name. You'll have them in an array. This makes your system call even easier:
system('montage.exe', #filenames, 'output.png')
Not only is that super easy, but it avoids the pitfall of having a command line too long. If your filenames have nice long paths (maybe 50-100 characters), a Windows command line will exceed the max command length after around 100 files. Passing the arguments through system() instead of in one big string avoids that limitation.
Alternatively, you can pass the arguments to montage.exe as a list (instead of concatenating them all into a string):
use strict;
use warnings;
my $pic1 = qq(picture one.png);
my $pic2 = qq(picture two.png);
my #cmd = ("C:\...\montage.exe", $pic1, $pic2, "output.png");
system(#cmd);
You need to put quotes around the file names that have spaces. You also need to escape the backslashes
my $cmd = qq{C:\\...\\montage.exe "$pic1" "$pic2" output.png};
In unix systems, the best approach is the multi-argument form of system because 1) it avoids invoking a shell, and 2) that's the format accepted by the OS call. Neither of those are true in Windows. The OS call to spawn a program expects a command line, and system's attempt to form this command line is sometimes incorrect. The safest approach is to use Win32::ShellQuote.
use Win32::ShellQuote qw( quote_system );
system quote_system("C:\\...\\montage.exe", $pic1, $pic2, "output.png");

use fprinft with an unknown format in matlab

I would like to save the output of several evals ( don't know the input of those ) in a file. Now I don't know the tpye of those evals They could be arrays or strings or integer or anything, so I can not really write fprinft(fileID, '%s\n', eval(somethingsomething)); since I don't know what the second parameter should be. Is there a way a for me to save those in a file?
You can save the results of the eval in a local variable and check the resulting type with class(v) and use printf accordingly.
I believe you can just save result of eval with fwrite(), why would you use fprintf?

save svm models to file matlab

I have 31 models an I want to save each one in a specific file
this is my matlab function
formatspec='model%d'
for k = 1:length(libsvmFiles)
baseFileName = libsvmFiles(k).name;
fullFileName = fullfile(myFolder, baseFileName);
[labels train]=libsvmread(fullFileName);
model=svmtrain(labels,train, '-t 2 -h 0');
file=sprintf(formatspec,k);
save file model;
but the problem is only the first file is saved and its name is 'file' tha's mean the value of the variable file is not evaluated
how can I solve this problem ?
As many Matlab functions, save can be used in function form (save(...)) or in command form (save ...). In the command form that you use, all the arguments are interpreted as strings. That means
save file model
is equivalent to
save('file', 'model')
For the second argument that is correct, because you want to refer to the variable with the name "model". For the first argument it is wrong, because you want to refer to the file name contained in the variable file. The correct syntax to use is therefore
save(file, 'model')
You're missing the parens for the save function. The model variable also needs to be listed as a string since you need to tell the save function the name of the variable, not the variable itself. See Matlab's documentation.
save(file, 'model');
Additionally you don't have an end to your for loop shown, which normally would just throw an error -- however later code might cause this loop to instead only run once. Otherwise you should check your libsvmFiles variable as it might be only length 1 or not be an array.

How do I send a value that starts with a dash to Getopt::Long?

I've got a client-side script I'm making that communicates with GNU-FTP. I want to be able to send it a custom argument on the command line, so I've created an argument --ftp-args
This is what it looks like
GetOptions(
.. redacted stuff..
"ftp-args=s%" => \$FTP_ARGS
) or die("Error in command line arguments\n");
However, whenever I try to call it I get an error,
$ ./script/dm-ftp360 --ftp-args="-E"
Option ftp-args, key "-E", requires a value
Error in command line arguments
Is it possible to get around this, and make this possible?
You've specified s% - defining an option that specifies hash entries. That implies a form key=value for each argument to the option. But you've only specified -E. The error message is about the missing =value part, not the leading -.
Perhaps use s# instead to ingest a set of simple options? Or give an empty value using "-E=" if you need to separate the keys and values before passing them to ftp.

Print in a log file the line number

I'm trying to manage some non-standard error in my functions (like a wrong input text), and I want to track those errors by writing a sort of log in a variable. I'm trying to write also the line number, and this is my code
$someVar = "line $($MyInvocation.ScriptLineNumber): at least 2 arguments needed, function has been called with only $args.Count arguments"
Sometimes it returns the correct number and sometimes it doesn't. Is this the correct way? Is there another method?
EDIT: I found that this problem could be related to an unconventional way to execute scripts that I use in order to bypass a permission problem on a specific the machine. I'll post a more detailed example as soon as I can
Any reason why you're not using param in your functions and making them mandatory?
Function A()
{
Param
(
[Parameter(Mandatory=$true)][String]$Arg1,
[Parameter(Mandatory=$true)][String]$Arg2
)
Write-Host "$Arg1 $Arg2"
}
If you run this function without any arguments then it will throw an error asking for the mandatory arguments.
try wrapping in $(). For example:
$someVar = "line $($MyInvocation.ScriptLineNumber): at least 2 arguments needed, function has been called with only $($args.Count) arguments"