mkdir call getting failed in Perl - perl

I am trying to create a directory using Perl. But this call fails.
However when I try to create the same directory structure in shell prompt, it works fine.
Could someone please let me know why I am not able to create the directory in the directory structure?
Example:
$absolutepath = "/localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata";
print $absolutepath."\n";
mkdir "$absolutepath" or die $!;
In this example, localdatafs1, Domino, mail\abhy.nsf, and Sent are directories that already exist. I want to create a directory called metadata in the directory structure /localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata using Perl. This mkdir call fails.
If I execute the command
mkdir /localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata
in shell prompt, the directory gets created successfully.
Why I am unable to create the directory in Perl using the above path?

Your shell understands a different language than Perl. In your shell, the code
/localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata
produces the string
/localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata
In Perl, the code
"/localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata"
produces the string
/localdatafs1/Domino/mail?bhy.nsf/Sent/Metadata
where the ? represents a non-printable control character. The Perl code
"/localdatafs1/Domino/mail\\abhy.nsf/Sent/Metadata"
produces the desired string. Note the escaped "\".

$path = "/localdatafs1/Domino/mail\abhy.nsf/Sent/Metadata"
^--- escape character, turning the path into
$path = "/localdatafs1/Domino/mail".chr(1)."bhy.nsf/Sent/Metadata"

Related

No such file or directory when we define the path as '~/path/to/csv' in postgres

lease=# COPY dhcpd_data (ip_address, start_time, end_time, mac_address, machine_name) FROM '~/outputcsvre.csv' DELIMITER ',' CSV HEADER;
ERROR: could not open file "~/outputcsvre.csv" for reading: No such file or directory
if i define the path as '/home/rihiraj12/outputcsvre.csv', it works fine.
Yes, that's normal.
You don't really have a directory called ~. When you execute a command on the command line, the shell will expand ~ to /home/rihiraj12 before running the program. But here you're not using the shell, so ~ is interpreted literally.
As a workaround you could say
COPY dhcpd_data (...) FROM PROGRAM 'cat ~/outputcsvre.csv' ...
But note that the COPY command is executed by the server, so this will make the server spawn a cat command and use the home directory of the PostgreSQL server.
To specify the file from your own point of view, you can (in psql) use the \copy meta-command (which has the same syntax as COPY):
\copy dhcpd_data (...) FROM PROGRAM 'cat ~/outputcsvre.csv' ...
This will use your own home directory as ~.
~ is a shortcut that unix-like shells can expand to be the home directory of your user.
i.e. if you use ~/outputcsvre.csv , the shell converts this to /home/rihiraj12/outputcsvre.csv before doing anything else with it.
Outside a shell, applications rarely implement this expansion - and neither does postgresql, so you have to provide real path to the file.
In the case of the COPY command in postgresql, it is executed by the server - so in this case you will have to provide a filename that the server can resolve and read directly. (i.e. a relative path would be relative to wherever the postgresql server is located - so use an absolute path for the file.)

Folder name with space issue

How do I handle a folder name containing spaces in Perl? For example C:\Sample Picture\Data.
I wrote this
use File::Glob ':glob';
$indir = "C:\\Sample Picture\\Data\\";
#flist = bsd_glob( $indir.'*');
This is throwing an error
The syntax of the command is incorrect.
The error message The syntax of the command is incorrect comes from the Windows command line, not from Perl
The issue is not to do with File::Glob, but with whatever you are doing with the contents of #flist. It's my guess that you're using backticks or system to rename one or more of the files or directories. This will fail if you use paths that contain spaces without enclosing the complete path in double quotes
If you need any more help then you must show the relevant part of your code

Running a script in bash

I have a script in one of my application folders.Usually I just cd into that locatin in Unix box and run the script e.g.
UNIX> cd My\Folder\
My\Folder> MyScript
This prints the required result.
I am not sure how do I do this in Bash script.I have done the following
#!/bin/bash
mydir=My\Folder\
cd $mydir
echo $(pwd)
This basically puts me in the right folder to run the required script . But I am not sure how to run the script in the code?
If you can call MyScript (as opposed to ./MyScript), obviously the current directory (".") is part of your PATH. (Which, by the way, isn't a good idea.)
That means you can call MyScript in your script just like that:
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
As I said, ./MyScript would be better (not as ambiguous). See Michael Wild's comment about directory separators.
Generally speaking, Bash considers everything that does not resolve to a builtin keyword (like if, while, do etc.) as a call to an executable or script (*) located somewhere in your PATH. It will check each directory in the PATH, in turn, for a so-named executable / script, and execute the first one it finds (which might or might not be the MyScript you are intending to run). That's why specifying that you mean the very MyScript in this directory (./) is the better choice.
(*): Unless, of course, there is a function of that name defined.
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
I would rather put the name in quotes. This makes it easier to read and save against mistakes.
#!/bin/bash
mydir="My Folder"
cd "$mydir"
echo $(pwd)
./MyScript
Your nickname says it all ;-)
When a command is entered at the prompt that doesn't contain a /, Bash first checks whether it is a alias or a function. Then it checks whether it is a built-in command, and only then it starts searching on the PATH. This is a shell variable that contains a list of directories to search for commands. It appears that in your case . (i.e. the current directory) is in the PATH, which is generally considered to be a pretty bad idea.
If the command contains a /, no look-up in the PATH is performed. Instead an exact match is required. If starting with a / it is an absolute path, and the file must exist. Otherwise it is a relative path, and the file must exist relative to the current working directory.
So, you have two acceptable options:
Put your script in some directory that is on your PATH. Alternatively, add the directory containing the script to the PATH variable.
Use an absolute or relative path to invoke your script.

Can't exec No such file or directory

Merry Christmas to everybody. I'm having a dilemma with a perl script. In my script, I call another program with a system call, but I got this error:
Can't exec "./Classificador/svm_classify": No such file or directory at Analise_de_Sentimentos_mudanca.pl line 463.
I don't know if there is a problem in having my program in a different directory than the called program.
Another curious thing is that this script used to run normally in Ubuntu 10.10. But now I've changed to Mint 14. Is it missing some library?
Best wishes,
Thiago
The relative pathname ./Classificador/svm_classify is interpreted relative to the user's current directory, not the directory containing the perl script. You need to do one of the following:
The user must cd to the directory containing the perl script before running it.
The perl script should call chdir() to set the current directory to the directory where it's stored.
Put the absolute pathname in the script, instead of ./.
Does this "./Classificador/svm_classify" exists ?
Check the following :
1) to go the directory where this file lays - Analise_de_Sentimentos_mudanca.pl
2) run :
ll Classificador/svm_classify
3) show us the results

STAF automation framework

I am trying to list a directory on remote machine 10.31.236.56
I am using staf for it .the staf document says the command as
LIST DIRECTORY <Name> [RECURSE] [LONG [DETAILS] | SUMMARY] [TYPE <Types>]
[NAME <Pattern>] [EXT <Pattern>] [CASESENSITIVE | CASEINSENSITIVE]
[SORTBYNAME | SORTBYSIZE | SORTBYMODTIME]
so i am using it as
system("staf 10.31.236.56 FS LIST DIRECTORY c:\\RMT\\Log ");
i get the result but when i try t match particular files like
system("staf 10.31.236.56 FS LIST DIRECTORY c:\\RMT\\Log NAME /latest*.*/");
i dont get any response can some one help me ??
Most likely the shell is interpreting the wildcard before it gets passed on to STAF. I'd recommend putting all of the arguments to STAF in quotes so that the shell wouldn't interfere.
For best results, perhaps avoid using system(string) to launch the command, and instead use either qx{} or system(LIST) so that a subshell isn't called.
Perhaps something like this:
my $cmd = "staf 10.31.236.56 FS LIST DIRECTORY c:\\RMT\\Log NAME /latest*.*/";
system(split ' ', $cmd);
When you pass system a single string, it launches a shell, and passes that string as the command to execute. The shell, then, parses that string (including any wildcards), and runs the command. Since you don't want this to happen (as you don't want "latest*.*" to be parsed by the shell), you can pass system a list, which would tell it to just launch staf directly.