LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   General source versus scripting question (https://www.linuxquestions.org/questions/programming-9/general-source-versus-scripting-question-337733/)

R00ts 06-27-2005 02:35 PM

General source versus scripting question
 
I have a multi-file C++ program I wrote that takes a single input file, process the data in that file, and spits out multiple output files into a user-named directory. I was wondering if others often use support/wrapper scripts for these types of programs. For example, when the user specifies the output directory first I want to check that the directory exists, has the proper permissions, if it doesn't exist create it, etc. So there are two solutions I thought of here:

1) Use a wrapper script which does the following
- Checks directory existence, permissions, etc.
- Passes the program the rest of the arguments (but not the directory arg)
- Assuming that the program always spits the output files in /somedir/program_dir/output, the script performs a move on the files when the program finishes to put them all in the correct directory


2) Do everything mentioned in 1 in the program itself


Problem is, I don't know how to do #2 (but I think there should be a way?), but it's easier to manage than #1 and people might get confused into thinking that they should just run the program natively without the script. So what would you do? Script, or no script? This is more a question out of curious inquiry rather than a "help me" question mind you. :)

lowpro2k3 06-27-2005 02:45 PM

If your just doing simple checks like "does the directory exist" and all that, I would not even tell the users about the C++ executable, and instead write a simple shell script to launch the C++ executuble after passing the shell script "checks".

I would write the wrapper in bash, assuming thats your environment, the things you mentioned are all doable, and relatively easy to accomplish in Bash - probably easier than performing the same task in C++ I might add.

Matir 06-27-2005 03:01 PM

I agree with lowpro2k3. You could add an argument to your C++ program (like --checks-passed) that the C++ program will not run without to prevent users directly executing it.

R00ts 06-27-2005 03:16 PM

Yeah I have a bash script half-written to do all this already.

Quote:

Originally posted by Matir
I agree with lowpro2k3. You could add an argument to your C++ program (like --checks-passed) that the C++ program will not run without to prevent users directly executing it.

That's a great idea. :D Thanks!

Matir 06-27-2005 08:16 PM

Quote:

Originally posted by R00ts
Yeah I have a bash script half-written to do all this already.

That's a great idea. :D Thanks!

No problem. Obviously, if someone reads the script, they'd be able to figure it out (if they understand the script) but I think we're going a bit beyond your average user there. :)

R00ts 06-29-2005 03:07 PM

Ok, here's a somewhat related question. How do you handle the balance when you're not necessarily in the scripts native PWD? For example, the structure of my program is like so:

program_dir (where the bash script for running the prog is)
program_dir/bin (where the actual program executable is)
program_dir/output (where the output files should temporarily be placed before moving)



I want to be able to execute the run script from anywhere so I made a symbolic link to it in my personal ~/bin directory. So let's say I'm in a directory ~/data where a file my_data.dat resides. I want to do the following:

runprog -i my_data.dat -o ../results/my_data

Where -i specifies that I want to use the data in my PWD (~/data) and -o specifies that I want the output files to be located in ~/results/my_data/ when finished. But then things get screwy. The script looks for the executable at program_dir/bin/my_prog, but obviously it wouldn't be there in this case. So for a quick fix I wrote the script to call the program with it's absolute path prepended and that's fine and all, but the actual program stores its output files in "../output/" temporarily until the script regains control and moves them, but i this case my PWD is still ~/results/my_data/ where there is no "../output" directory.


I can probably come up with a quick and dirty solution, like taking the $PWD when my script first starts up and prepending that onto both the -i and -o arguments so that everything uses the absolute path, and I'd have to modify the actual source code of my program to output the files in an absolute path and not a local one. But that's evil hacking! :( This program (and it's file structure) needs to be able to reside anywhere and be called from anywhere without requiring all this evil absolute path hacking, but I don't know how to go about solving that problem. Any ideas?

Matir 06-29-2005 03:11 PM

Code:

OLDDIR=`pwd`
cd /path/to/programsdir
./program -options
cd $OLDDIR
cp /path/to/programsdir/output .


R00ts 06-29-2005 03:21 PM

Quote:

Originally posted by Matir
Code:

OLDDIR=`pwd`
cd /path/to/programsdir
./program -options
cd $OLDDIR
cp /path/to/programsdir/output .


Yeah, I started doing something like that. But then if the user is in some other PWD, naturally if the input file they want to use is in the PWD they're just going to type "my_data.dat" and not "/home/me/data/my_data.dat", and same with the output directory. So I'd have to do all this checking of whether the user specified a relative or absolute path name, add the path name if needed, etc. etc. I know it would work, it just seems really messy and I was wondering if there wasn't another quick hack to tackle this kind of problem that I don't know about... :study:

Tinkster 06-29-2005 03:37 PM

Quote:

Originally posted by R00ts
Yeah, I started doing something like that. But then if the user is in some other PWD, naturally if the input file they want to use is in the PWD they're just going to type "my_data.dat" and not "/home/me/data/my_data.dat", and same with the output directory. So I'd have to do all this checking of whether the user specified a relative or absolute path name, add the path name if needed, etc. etc. I know it would work, it just seems really messy and I was wondering if there wasn't another quick hack to tackle this kind of problem that I don't know about... :study:
Not really ... if the file the users file is where you start the
script from just invoke the compiled program like this ...


./program -options $OLDDIR/$1


Cheers,
Tink

R00ts 06-29-2005 04:04 PM

Ok, yeah I fixed it up so I don't think I'll have these issues anymore. It was simple really. I just decided to initally output the files to the PWD instead of to ../output (since they are moved by the script after the program finishes anyway and it looks like everything works ok now. I've just been working too much lately and I'm burnt out so my brain is not working as good as it should be. :cry: Here's the script source for anyone interested, although I had to change the name of the program to something generic for......reasons. ;)

Code:

#!/bin/bash

###########################################################
# This script is what you should call to run MyProg!!! #
###########################################################

# This is a wrapper script for MyProg. It's only purpose is to handle the
# creation of an output directory and to move the output files to that directory.

# MyProg base directory
MyProg_dir=/home/olsen/dev/MyProg/

# Constants
readonly FALSE=0
readonly TRUE=1

# output_dir: The full directory path where the output files will be relocated to
output_dir=""
# output_name: The output directory sans path, also the first part of the output filenames
output_name=""
# orig_args: The original argument list passed to this script
orig_args=$*
# full_args: The argument list after post-processing that MyProg actually evaulates
full_args=""

####################################################
# (1) Grab arguments that need to be pre-processed #
####################################################

lastarg=""
for arg in "$@"
do
if [[ "$lastarg" == -o ]] # Grab the output directory argument
  then
    output_dir=$arg
  fi
  if [[ "$arg" == -h ]] # Run MyProg -h if user gave the help argument and exit
  then
    eval $MyProg_dir/bin/MyProg -h
    exit 0
  fi
  lastarg=$arg
done

# Remove path information from output_dir and save to output_name
if [[ "${output_dir:(-1)}" == "/" ]]
then
  output_dir=${output_dir%/*} # Get rid of that ending slash!!!
fi
output_name=${output_dir##/*/}

# Replace the -o $output_dir with -o $output_name
full_args=$(echo ${orig_args/$output_dir/$output_name})

# Check for output directory existence and proper permissions. Create if necessary
if [ -d $output_dir ]
then
  if [ ! -w $output_dir ]
  then
    echo "ERROR: you do not have write permissions for directory $output_dir"
    exit 1
  fi
else
  mkdir $output_dir
  if (( $? != 0 )) # Check for failure
  then
    echo "ERROR: could not create directory $output_dir, check your permissions"
    exit 1
  fi
fi

########################################################
# (2) Call MyProg and pass the argument list via -z #
########################################################
eval $MyProg_dir/bin/MyProg $full_args -z "$orig_args"
if (( $? != 0 )) # Something went wrong while executing MyProg
then
  exit 1
fi


#####################################################
# (3) Move output files to user-specified directory #
#####################################################
mv $output_name.* $output_dir/.
if (( $? != 0 )) # Could not move output files for some reason
then
  echo "WARNING: could not move output files to specified directory, $output_dir"
  exit 1
fi

exit 0



All times are GMT -5. The time now is 01:23 PM.