Casting Command Line Arguments? - command-line

i have a command line executable program that accepts a configuration file as it's one argument for launch. the configuration file contains only 2 lines of code:
#ConfigFile.cfg
name=geoffrey
city=montreal
currently, the wrapper program that i'm building for this command line executable program writes the configuration file to disk and than sends that written file as the argument to launch the program on the command line.
> myProgram.exe configFile.cfg
is it possible to cast these configuration file entries as the configuration file, allowing me to bypass having to write the configuration file to disk but still allow the program to run as if it's reading from a configuration file?
perhaps something like the following:
> myProgram.exe configFile.cfg(name=geoffrey) configFile.cfg(city=montreal)

If you don't control the source for the program you're wrapping, and it doesn't already provide a facility to receive input in another way, you're going to find it difficult at best.
One possibility would be to intercept the file open and access calls used by the program though this is a horrible way to do it.
It would probably involve injecting your own runtime libraries containing (for C) fopen, fclose, fread and so on, between the program and the real libraries (such as using LD_LIBRARY_PATH or something similar), and that's assuming it's not statically linked. Not something for the faint of heart.
If you're worried about people being able to see your file, there's plenty of ways to avoid that, such as by creating it with rwx------ permissions in a similarly protected directory (assuming UNIX-like OS). That's probably safer than using command line arguments which any joker logged in could find out with a ps command.
If you just don't want the hassle of creating a file, I think you'll find the hassle of avoiding it is going to be so much more.
Depending on what you're really after, it wouldn't take much to put together a program that accepted arguments, wrote them to a temporary file, called the real program with that temporary file name, then deleted the file.
It would still be being written to disk, but that would no longer be the responsibility of your wrapper program. Something along the lines of (a bit rough, but you should get the idea):
#include <stdio.h>
#define PROG "myProgram"
int main (int argCount, char *argVal[]) {
char *tmpFSpec;
FILE *fHndl;
int i;
char *cmdBuff;
tmpFSpec = getTempFSpec(); // need to provide this.
cmdBuff = malloc (sizeof(PROG) + 1 + strlen (tmpFSpec) + 1);
if (cmdBuff == NULL) {
// handle error.
return 1;
}
fHndl = fopen (tmpFSpec, "w");
if (fHndl == NULL) {
// handle error.
free (cmdBuff);
return 1;
}
for (i = 1; i < argCount; i++)
fprintf (fHndl, "%s\n", argVal[i]);
sprintf (cmdBuff, "%s %s", PROG, tmpFSpec);
system (cmdBuff);
return 0;
}

Related

Create new system-call in xv6 that returns data about an open files for all running processes

Im started to learn about xv6.
And I'm trying to add a new system call that will print the list of open files for all running processes.
It has to print pid of each process, its file descriptor number (0,1,2- for each pid), if the file is regular or piped and if the file is readable of writable.
So I know is how to get the pid. Here is an example of a code:
struct proc *p;
sti();
acquire(&ptable.lock);
cprintf("name \t pid \t type \t \n");
for (p=ptable.proc; p<&ptable.proc[NPROC]; p++){
cprintf("%s \t %d \n", p->name, p->pid);
}
}
release (&ptable.lock);
What I don't know and couldn't find on the internet is how to check if file named by file descriptor is writable\riadable\both
And I don't know how to check if the type of the file named by file descriptor is pipe\regular.
I looked at file.h and there are fields like type(FD_NONE, FD_PIPE, FD_INODE), char readable,char writable.
But I dont understand how to get them...
If you have any resources with subtitle info to share with me or if you can help, I would be happy to hear.
Thanks a lot!
Check out
struct proc in proc.h
functions in file.c
You should be able to get a pointer to the beginning of the open files array like this:
struct file* fp = (struct file*) &p->ofile;
From there, you can copy the same syntax from the ptable loop to loop through the files. And to check if a file is readable, functions in file.c just check the readable flag:
if(fp->readable && fp->type == FD_PIPE)
// do some logic

perl memory usage when processing a file inline

I have a CGI script that's used by our employees to fetch logs from servers that they don't have direct access to. For reasons I won't go into, after a recent update to our app some of these logs now have characters like linefeeds, tabs, backslashes, etc. translated into their text equivalents. As such, I've modified the CGI script to invoke the following to convert these back to their original values:
perl -i -pe 's/\\r/\r/g && s/\\n/\n/g && s/\\t/\t/g && s/\\\//\//g' $filename
I was just informed that some people are now getting out of memory errors when they try to fetch logs that are fairly large (a few hundred MB).
My question: How does perl manage memory when an inline command like this is invoked? Is it reading the whole file in, processing it, then writing it out, or is it creating a temporary file, processing the lines from the input file one at a time then replacing the file once complete?
This is using perl 5.10.1 on a 64-bit Amazon linux instance.
The -p switch creates a while(<>){...; print} loop to iterate on each “line” in your input file.
If all of your newlines have been converted into "\\n", then your file would just be a single very long line. Therefore, your command would be loading the entire file into memory to perform your fix.
To avoid that, you'll have to intentionally buffer the file using either sysread or $/.
It would probably be easiest to create an actual script instead of a one-liner to do the work. However, if you know that all of your newlines are converted, then one simple fix would be to use $/ = "\\n"
As a secondary note, your regex is flawed. You're currently listing out your translations s/// using a shortcut operator. If any one of the earlier regexes doesn't match for a particular line, then no other translations would be attempted. You should instead use simple semicolons to separate your regexes:
's/\\r/\r/g; s/\\n/\n/g; s/\\t/\t/g; s|\\/|/|g'

opening a batch file that opens a text file in python

I am writing a script that can execute a batch file, which needs to open a file in the same folder first. My current code is:
from subprocess import Popen
p = Popen("Mad8dl.bat <RUNTHISTO.txt>", cwd=r"C:\...\test")
stdout, stderr = p.communicate()
where the ... is just the path to the folder. However, everytime I run it I get the syntax error:
The syntax of the command is incorrect
Any help regarding the syntax would be greatly appreciated.
First, you should probably remove the < and > angle brackets from your code; just pass the filename, without any brackets, to your batch file. (Unless your filename really does contain < and > characters, in which case I really want to know how you managed it since those characters are forbidden in filenames in Windows).
Second, your code should look like:
from subprocess import Popen, PIPE
p = Popen(["Mad8dl.bat", "RUNTHISTOO.txt"], cwd=r"C:\...\test", stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
Note the list containing the components of the call, rather than a single string. Also note that you need to specify stdout=PIPE and stderr=PIPE in your Popen() call if you want to use communicate() later on.

Using a .fasta file to compute relative content of sequences

So me being the 'noob' that I am, being introduced to programming via Perl just recently, I'm still getting used to all of this. I have a .fasta file which I have to use, although I'm unsure if I'm able to open it, or if I have to work with it 'blindly', so to speak.
Anyway, the file that I have contains DNA sequences for three genes, written in this .fasta format.
Apparently it's something like this:
>label
sequence
>label
sequence
>label
sequence
My goal is to write a script to open and read the file, which I have gotten the hang of now, but I have to read each sequence, compute relative amounts of 'G' and 'C' within each sequence, and then I'm to write it to a TAB-delimited file the names of the genes, and their respective 'G' and 'C' content.
Would anyone be able to provide some guidance? I'm unsure what a TAB-delimited file is, and I'm still trying to figure out how to open a .fasta file to actually see the content. So far I've worked with .txt files which I can easily open, but not .fasta.
I apologise for sounding completely bewildered. I'd appreciate your patience. I'm not like you pros out there!!
I get that it's confusing, but you really should try to limit your question to one concrete problem, see https://stackoverflow.com/faq#questions
I have no idea what a ".fasta" file or 'G' and 'C' is.. but it probably doesn't matter.
Generally:
Open input file
Read and parse data. If it's in some strange format that you can't parse, go hunting on http://metacpan.org for a module to read it. If you're lucky someone has already done the hard part for you.
Compute whatever you're trying to compute
Print to screen (standard out) or another file.
A "TAB-delimite" file is a file with columns (think Excel) where each column is separated by the tab ("\t") character. As quick google or stackoverflow search would tell you..
Here is an approach using 'awk' utility which can be used from the command line. The following program is executed by specifying its path and using awk -f <path> <sequence file>
#NR>1 means only look at lines above 1 because you said the sequence starts on line 2
NR>1{
#this for-loop goes through all bases in the line and then performs operations below:
for (i=1;i<=length;i++)
#for each position encountered, the variable "total" is increased by 1 for total bases
total++
}
{
for (i=1;i<=length;i++)
#if the "substring" i.e. position in a line == c or g upper or lower (some bases are
#lowercase in some fasta files), it will carry out the following instructions:
if(substr($0,i,1)=="c" || substr($0,i,1)=="C")
#this increments the c count by one for every c or C encountered, the next if statement does
#the same thing for g and G:
c++; else
if(substr($0,i,1)=="g" || substr($0,i,1)=="G")
g++
}
END{
#this "END-block" prints the gene name and C, G content in percentage, separated by tabs
print "Gene name\tG content:\t"(100*g/total)"%\tC content:\t"(100*c/total)"%"
}

How to verify normal termination of R scripts executed from Perl?

I have written a shebang R script and would like to execute it from a Perl script. I currently use system ($my_r_script_path, $r_script_arg1, $r_script_arg2, ...) and my question is how can I verify the R script terminates normally (no errors or warnings).
guess I should make my R script return some true value at the end, only if everything is OK, then catch this value in Perl, but I'm not sure how to do that.
Thanks!
You can set the return value in the command quit(), eg q(status=1). Default is 0, see also ?quit. How to catch that one in Perl, is like catching any other returning value in Perl. It is saved in a special variable $? if I remember right. See also the examples in the perldoc for system, it should be illustrated there.
On a sidenote, I'd just use the R-Perl interface. You can find info and examples here :
http://www.omegahat.org/RSPerl/
Just for completeness :
At the beginning of your script, you can put something like :
options(
warn=2, # This will change all warnings into errors,
# so warnings will also be handled like errors
error= quote({
sink(file="error.txt"); # save the error message in a file
dump.frames();
print(attr(last.dump,"error.message"));
sink();
q("no",status=1,FALSE) # standard way for R to end after errors
})
)
This will save the error message, and break out of the R session without saving, with exit code 1 and without running the .Last.
Still, the R-Perl interface offers a lot more possibilities that are worth checking out if you're going to do this more often.