LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   [bash] re-use script for variation (https://www.linuxquestions.org/questions/programming-9/%5Bbash%5D-re-use-script-for-variation-4175694646/)

tvc457 05-03-2021 08:30 AM

[bash] re-use script for variation
 
I'm having a simple issue with this Bash-script I have, and I can't come up with an elegant solution for it.

So, I have a script, which is working and all, no problem.
Now, I need to run a similar thing now, the difference is: some parts of the code don't need to be run for this variation. Obviously I'm not copying the script, and just removing the unneeded lines, because the rest of the code will be duplicate code - and that is a no-go.

Lets say my initial script (script1.sh) is this:

#!/bin/bash

<code section A>
<code section B>
<code section C>
<code section D>
<code section E>
<code section F>
<code section G>
<code section H>
<code section I>


But for this variation, I just want to run :

<code section A>
<code section B>
<code section D>
<code section F>
<code section G>
<code section I>

I could use IF statements, either for the sections of code I want to run, or the other way round, but I feel that solution is not very nice. If it was just one section being different, it would be an option, but it's repeating through the whole script.

shruggy 05-03-2021 08:37 AM

Put common sections into a different file, making each section a separate function. Source that library file from the main script, and you'll have all the functions defined there.

boughtonp 05-03-2021 09:18 AM

Quote:

Originally Posted by tvc457 (Post 6247526)
I could use IF statements, either for the sections of code I want to run, or the other way round, but I feel that solution is not very nice. If it was just one section being different, it would be an option, but it's repeating through the whole script.

That sounds like there may already be a problem with the code.

As Shruggy says, create a library of functions then call those from your script(s) - but spend some time to think it through; you want to convert the right functionality into functions with the appropriate input+output, rather than blindly segmenting the code.

Put another way: you might need to slice different parts at different angles to get the cleanest structure.


tvc457 05-03-2021 02:05 PM

Quote:

Originally Posted by shruggy (Post 6247534)
Put common sections into a different file, making each section a separate function. Source that library file from the main script, and you'll have all the functions defined there.

I still need to use IF statements to call the functions, or not, depending the segment of the main script I'm at.

Functions are great, but in this case it doesn't really solve the issue I'm seeing. Actually,

I'm changing a script that is working 100% already, and then I still have the same question.
I then have a library file that is called by one script, and one script only. That's not what a library file is for. I'm not even calling any function twice. It's spreading code, without any good reason. Technically, it will work however.

tvc457 05-03-2021 02:08 PM

Quote:

Originally Posted by boughtonp (Post 6247548)
That sounds like there may already be a problem with the code.

The code not, but the way it is used, yes.

Until now, I copied the script (because it's all working just fine), and I remark the segments I don't need to run, use that script, then scrap it.
( Because the main script will get newer versions, not for bugs, but for functionality expansion. )

shruggy 05-03-2021 02:18 PM

Quote:

Originally Posted by tvc457 (Post 6247648)
I still need to use IF statements to call the functions, or not, depending the segment of the main script I'm at.

No. You only need to call those functions that are used in the main script.

Quote:

Originally Posted by tvc457 (Post 6247648)
I then have a library file that is called by one script, and one script only.

AFAIUI, at least by two scripts: your original script that uses the full set of functions, and by your new script that uses a subset of them.

tvc457 05-03-2021 02:38 PM

Quote:

Originally Posted by shruggy (Post 6247655)
AFAIUI, at least by two scripts: your original script that uses the full set of functions, and by your new script that uses a subset of them.

That's an option, but it's even worse. The main script is not just calling segments, or functions. It has additional code (like parameter check and error handling).
So, then I have exactly what I don't want : duplicate code in 2 similar scripts.

shruggy 05-03-2021 02:55 PM

Then that's exactly how boughtonp told in #3: you should redesign the script so that parameter check and error handling are done by functions.

michaelk 05-03-2021 03:02 PM

Without knowing anything about how your script works its a bit difficult to make suggestions.

Since you posted "for this variation" I am guessing that you want to modify your script so that you can easily run different sections of your script without editing it every time.

It may not be the nicest and it does not have to be but using if then might be the quickest and with a command line option you can select which sections to run.

danielbmartin 05-03-2021 09:29 PM

This is the way I do it. Might not be the best way but it works for me.

The distinction is made on the basis of a program's name. A "Master" version performs all functions; a "Clone" version performs a subset of functions.

As the programmer you write only one version, the Master. Copy that program into a different .bin file with no changes whatsoever. That copy is, by definition, a Clone.

This Master program ...
Code:

#!/bin/bash  Daniel B. Martin  May21
#
# This program inspired by ...
# https://www.linuxquestions.org/questions/programming-9/
#  [bash]-re-use-script-for-variation-4175694646/

# File identification
    Path=${0%%.*}
 OutFile=$Path"out.txt"

rm $OutFile

PgmName=$0
echo "Executing Program <"$PgmName">"; echo

if [[ $PgmName == '/home/daniel/Desktop/LQfiles/dbm2266.bin' ]];
  then
    echo 'This is the MASTER version.  All program steps will be executed.'
  else
    echo 'This is the CLONE version.  Optional program steps will not be executed.'
fi

# Always perform step #M-1.
echo "Mandatory step #M-1" >>$OutFile

# Conditionally perform step O-1.
if [[ $PgmName == '/home/daniel/Desktop/LQfiles/dbm2266.bin' ]]; then
  echo "Optional step #O-1" >>$OutFile
fi

# Always perform step #M-2.
echo "Mandatory step #M-2" >>$OutFile

# Conditionally perform step O-2.
if [[ $PgmName == '/home/daniel/Desktop/LQfiles/dbm2266.bin' ]]; then
  echo "Optional step #O-2" >>$OutFile
fi

# Always perform step #M-3.
echo "Mandatory step #M-3" >>$OutFile

echo; echo 'This is the OutFile...'; cat $OutFile

echo; echo "Normal end of job."; echo; exit

... produced this OutFile ...
Code:

Executing Program </home/daniel/Desktop/LQfiles/dbm2266.bin>

This is the MASTER version.  All program steps will be executed.

This is the OutFile...
Mandatory step #M-1
Optional step #O-1
Mandatory step #M-2
Optional step #O-2
Mandatory step #M-3

Normal end of job.


The Clone program ...

... produced this OutFile ...
Code:

Executing Program </home/daniel/Desktop/LQfiles/dbm2268.bin>

This is the CLONE version.  Optional program steps will not be executed.

This is the OutFile...
Mandatory step #M-1
Mandatory step #M-2
Mandatory step #M-3

Normal end of job.

To reiterate: two copies of the identical program.

If this method is used there is a maintenance advantage. If it becomes necessary to change the InFile or OutFile formats it is done in only the Master, and after testing the Master is copied into the Clone file.


Daniel B. Martin

.

shruggy 05-04-2021 01:38 AM

@danielbmartin. I probably would do it like this
Code:

[...]
PgmName=${0##*/}
echo "Executing Program <"$PgmName">"; echo

optional=false
case $PgmName in
  *2266*) optional=true;;
esac

if $optional
  then
    echo 'This is the MASTER version.  All program steps will be executed.'
  else
    echo 'This is the CLONE version.  Optional program steps will not be executed.'
fi

# Always perform step #M-1.
echo "Mandatory step #M-1" >>$OutFile

# Conditionally perform step O-1.
$optional && {
  echo "Optional step #O-1" >>$OutFile
}

# Always perform step #M-2.
echo "Mandatory step #M-2" >>$OutFile

# Conditionally perform step O-2.
$optional && {
  echo "Optional step #O-2" >>$OutFile
}
[...]



All times are GMT -5. The time now is 09:30 AM.