0

I am trying to automate a scanning proccess for a physical application. My script is

#!/bin/bash

i=1
file="ATLASbins.txt"
while IFS= read line 
do
    scan=$line
    cat test.sh | sed     "s/ set vchi 5000/ set vchi $scan/g" > test2.sh
    chmod +x test2.sh
    bash -x  /home/mario/Mine/test2.sh
    i=$((i + 1))
done <"$file"

Where test2.sh is another script in which I launch the application in which the scans are made. An example of what goes in the second script is

#!/bin/bash
/home/mario/mg5/bin/mg5_aMC

"import model Implementation"

"generate u++ > l+ l+"

output firstscript$i

set vchi 6500

launch firstscript$i

Where 'import model', 'output' and 'launch' are commands of the application (which runs in the terminal).

What happens is that the commands (inside the application) don't work and I get lines like

PATH/test2.sh: line 5: import model Implementation: command not found

I have no idea how to do this (which is to write a script that can write the commands to the application) and have tried various different separators, running the test2 script in a different shell and to call it in a new terminal using terminal-gnome. How can I make this work?

Another observation is that I need the variable value of i to be written inside the application. I tried this writing, for instance, 'output firstscript$i', which wouldn't work even if the command worked, I imagine.

  • 1
    So, the second scripts starts the mg5_aMC program, and you want the rest of that script sent as input to said program? Or something else? Does the first script have anything to do with the issue at hand? – ilkkachu Feb 20 at 10:31
  • 1
    The first script seems to try to change things in the second script that isn't even there (the set vchi setting). Is the application, which I presume is mg5_aMC, expecting input on its standard input or by using its command line arguments when starting it? The $i in the second script would be empty since it's an unexported shell variable in the first script only. – Kusalananda Feb 20 at 10:34
  • @ilkkachu That's exactly it. The first script changes some initial script test.sh to a new form several times, which is to run and write input (which is changing) to the program. Also, there is the fact that I need to access the shell variable $i and use it as input to the program. – GaloisFan Feb 20 at 10:38
  • @Kusalananda That was my bad: the second script is quite long and I didn't paste the part where the vchi is relevant, which made the question confusing. I edited it to correct this. And what you said lastly is exactly the problem I have, and don't know how to solve, with the $i. As for the question regarding the type of input mg5_aMC is expecting, I don't really understand. – GaloisFan Feb 20 at 10:41
  • If you ran mg5_aMC from the command line, would it expect the other commands in your second script as input from the keyboard? Would redirecting these command from a text file into mg5_aMC make the program accept them as commands? – Kusalananda Feb 20 at 10:44
1

Since you run your test2.sh as a separate shell script, the shell variable i is not available in it. This means that the expansion of $i will be empty in the test2.sh script. You can solve this in two ways:

  1. Make i an environment variable through export i in the first script. This is convenient, but not really a good solution in the general case, as the other script may well want to use its own i variable which may be independent of whatever value the variable is in the calling script.

  2. Give $i on the command line of the test2.sh script when invoking it: test2.sh "$i". This would make it possible to access the value $i in test2.sh as "$1" (the first command line argument).

The second issue is that your mg5_aMC program expects to get input, i.e. the commands that you list in the script. But the way you have entered these in test2.sh means that they would be taken as shell commands. There is nothing in the script that passes the special control commands to the program.

As you can see from the error that you get, it's the shell that complains that the commands can't be found. They are not shell commands, so this is (when you know how things will be interpreted) no surprise.


Assuming that your mg5_aMC program reads from standard input, I would not write out a shell script for each run of the program, but instead provide an input control/command file for it:

#!/bin/bash

file="ATLASbins.txt"

i=1
while IFS= read -r scan 
do
    sed -e "s/@scan@/$scan/" \
        -e "s/@i@/$i/" \
        input-template.in >input.in

    /home/mario/mg5/bin/mg5_aMC <input.in

    i=$((i + 1))
done <"$file"

Here, the file input-template.in may look something like

"import model Implementation"
"generate u++ > l+ l+"
output firstscript@i@
set vchi @scan@
launch firstscript@i@

I've chosen to use @thing@ for things I will replace with the sed call in the shell script.

This assumes that the value of $scan contains no characters that would disturb the sed command (such as /).


An alternative, if the control script for your program is reasonably short, is to use "here-document" to feed the control commands into your program:

#!/bin/bash

file="ATLASbins.txt"

i=1
while IFS= read -r scan 
do
    /home/mario/mg5/bin/mg5_aMC <<END_INPUT
"import model Implementation"
"generate u++ > l+ l+"
output firstscript$i
set vchi $scan
launch firstscript$i
END_INPUT

    i=$((i + 1))
done <"$file"

A here-document is basically a type of redirection of a piece of text which is given, not in a file, but between <<TAG and the ending TAG. The variables in the text would (if written as above) be expanded by the shell before being fed into your command.

  • I will try it as soon as I can, thank you! It is clear why calling the variable $i which did't even existed in that enviroment would not work, but can you say why the command themselves didn't work in a script like that? – GaloisFan Feb 20 at 11:12
  • @GaloisFan When you run a shell script like your test2.sh script, the commands that were supposed to be fed into your program would have been interpreted as shell commands. This is why you get those "command not found" errors. It's the shell rather than your program that receives those as commands. I will add text to the answer about this. – Kusalananda Feb 20 at 11:14
  • @GaloisFan See extra stuff just added. Note that all of this depends on your program actually reading from its standard input stream. – Kusalananda Feb 20 at 11:24
  • 1
    Your solution worked perfectly and your explanation clarified a lot. Thank you very much! – GaloisFan Feb 20 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.