Passing Variables from a Shell-Script to a Fortran 90 Program - bash

I'm stuck on this little problem. I was wondering if it is possible to pass a variable of a bash-shell script to a f90 code?

I am pretty sure it was discussed here before, but I cannot find an exact duplicate.
You can pass arguments directly as arguments to the program
./program arg1 arg2
you can retrieve the values in the program as character strings in Fortran 2003 using subroutines GET_COMMAND ARGUMENT and COMMAND_ARGUMENT_COUNT. Click on the links to get useful examples.
In older Fortran you have to use non-standard extensions, such as the subroutines GETARG and IARGC.
You can also read an environment variable which was set in the script
VAR1 = ...
VAR2 = ...
./program
using Fortran 2003 subroutine GET_ENVIRONMENT_VARIABLE. In older Fortran you have to use some non-standard extension, such as the subroutine GETENV.
You can also redirect a file to the standard input of the program and read the data using the READ statement.

You can choose between the following possibilities:
In bash use export of the variable
myvar="example"; export myvar
Add them as argument to the fortran call
myFortran "${myvar}"
Write them to a file and read the file
Worst solution, just to mention them all
Write it to stdin of fortran program
echo "${myvar}" | myFortran

And you can use the following procedures to read an environment variable: get_environment_variable
https://gcc.gnu.org/onlinedocs/gfortran/GET_005fENVIRONMENT_005fVARIABLE.html
Or read the number and value of the command argument: command_argument_count,get_command_argument. See:
https://gcc.gnu.org/onlinedocs/gfortran/Intrinsic-Procedures.html#Intrinsic-Procedures

Related

Why a C file name can be saved in a variable just right after writing a bash script?

In today's class, we were asked to write a script that runs a C file through the preprocessor and save the result into another file, with the following conditions:
The C file name will be saved in the variable $NAMEFILE
The output should be saved in the file NAME
One my classmates fastly wrote the following code as the solution:
#!/bin/bash
gcc -E -o NAME $NAMEFILE
I understand all of the code above, except the last part where the variable $NAMEFILE is written, it seems tricky, why can you simply store the C file name in that variable without even declaring it? the GCC manual doesn't seem to explain that, so I just want to get the logics behind this.
Based on the feedback provided in comment section of my post, the $NAMEFILE variable was a environment variable. I was suggested to read the docs related to environment variables, which I will in the following hours.
My problem was solved.
You are conflating gcc operation / features with the behavior of a shell. The gcc manual would not say anything about "storing the filename in a variable" because that's part or the environment where gcc would be run.
in windows, it would look like this:
gcc -E -o NAME %FILENAME%
You're not going to find any explanation of that in the gcc manual.
The shell (bash) is like "the windows explorer". It's what you use to give the computer (OS) instructions. instead of clicking folders you do cd folder and instead of "double click" you type "./foo/command" or just "gcc".
So just keep that in mind and you'll be fine.

Why won't an external executable run without manual input from the terminal command line?

I am currently writing a Python script that will pipe some RNA sequences (strings) into a UNIX executable, which, after processing them, will then send the output back into my Python script for further processing. I am doing this with the subprocess module.
However, in order for the executable to run, it must also have some additional arguments provided to it. Using the subprocess.call method, I have been trying to run:
import subprocess
seq= "acgtgagtag"
output= subprocess.Popen(["./DNAanalyzer", seq])
Despite having my environmental variables set properly, the executables running without problem from the command line of the terminal, and the subprocess module functioning normally (e.g. subprocess.Popen(["ls"]) works just fine), the Unix executable prints out the same output:
Failed to open input file acgtgagtag.in
Requesting input manually.
There are a few other Unix executables in this package, and all of them behave the same way. I even tried to create a simple text file containing the sequence and specify it as the input in both the Python script as well as within the command line, but the executables only want manual input.
I have looked through the package's manual, but it does not mention why the executables can ostensibly be only run through the command line. Because I have limited experience with this module (and Python in general), can anybody indicate what the best approach to this problem would be?
The Popen() is actually a constructor for an object – that object being a "sub-shell" that directly runs the executable. But because I didn't set a standard input or output (stdin and stdout), they default to None, meaning that the process's I/O are both closed.
What I should have done is pass subprocess.PIPE to signify to the Popen object that I want to pipe input and output between my program and the process.
Additionally, the environment variables of the script (in the main shell) were not the same as the environment variables of the subshell, and these specific executables needed certain environment variables in order to function (in this case, it was the path to the parameter files in its package). This was done in the following fashion:
import subprocess as sb
seq= "acgtgagtag"
my_env= {BIOPACKAGEPATH: "/Users/Bobmcbobson/Documents/Biopackage/"}
p= sb.Popen(['biopackage/bin/DNAanalyzer'], stdin=sb.PIPE, stdout=sb.PIPE, env=my_env)
strb = (seq + '\n').encode('utf-8')
data = p.communicate(input=strb)
After creating the Popen object, we send it a formatted input string using communicate(). The output can now be read, and further processed in whatever way in the script.

(Tcl?) Script for running modelsim with testbench as parameter from shell

I want to make a script, which can be executed from shell like:
./myscript -test1 or tclsh myscript.tcl -test1
I want it to open ModelSim, compile units, load a desired testbench, run simulation. Name of the test would be a parameter. I've already made macro files (.do) containing modelsim commands to compile & simulate desired units (+adding signals to waveform). I'm asking because scripting isn't my area of expertise.
So here's my questions:
How to ,,tell'' Modelsim (at startup) to do the commands in specified file?
Is TCL the language i'm looking for // is it doable in TCL? If so, which commands should i make familiar with?
Or maybe shell script is sufficient and i should look for specific Modelsim commands in reference manual?
Thanks for you time!
EDIT: Posting little example i've made for everyone to use. Usage: ./foo.tcl testname
#!/usr/bin/tclsh
# params
set testname [lindex $argv 0]
set testlist {test1 test2 test3}
# run vsim test $testname
if { [ lsearch $testlist $testname ] >= 0 } {
puts "Test found. Executing..."
open "|vsim -do $testname "
} else { puts "Test not found on the list!" }
You can launch vsim with arbitrary commands using the -do <arg> command line option. The argument can either be a filename of a .do file containing arbitrary Tcl code or a string of Tcl commands ("run -all; quit" is useful for non-interactive command line mode with -c).
Tcl is a full featured scripting language. It can handle any automation task you need to accomplish. Ultimately you cannot escape Tcl with Modelsim since almost everything runs through it internally. I would recommend you piece together what you need in a .do file and run that using the -do option.
If you create a .tcl script (.do files can run QuestaSim/ModelSim commands and tcl commands), you can do everything you want to do, include running other .do/.tcl files. For example:
ModelSim/QuestaSim Command Line:
just like what you are used to...
$: do MyDoFile.do
...instead use a Tcl file, which could call out your .do files:
$: source ./MyDirectory/MyTCLScript.tcl
Within that MyTCLScript.tcl you can have literally the following:
Within MyTCLScript.tcl:
...
#Use tabs for aliases
source ./MyDirectory/OtherDirectory/OtherTCLScript.tcl
MyAlias1
MyAlias2
do ./MyDoFile.do
...
Finally, to let you use commands to run single testbenches and the sort, I suggest looking at Tcl documentation on aliases. Here is an example though:
Within OtherTCLScript.tcl:
...
alias MyAlias1 {
eval <command><command flags>
}
alias MyAlias2 {
eval <command><command flags>
}
...
Sources:
1. Experience
2. Questa SIM User's Manual

How do I write a shell script that repeats a java program a specific number of times?

Essentially I am looking to write a shell script, likely using a for loop, that would allow me to repeat a program call multiple times without having to do it by hand (I don't know exactly how to explain this, but i want to perform the java TestFile.java command in the cmd window multiple times without doing it by hand).
I am trying to write it for the UNIX shell in bash, if that helps at all.
My program outputs a set of numbers that I want to look at to analyze end behavior, so I need to perform many tests for many different inputs and I want to streamline the process. I have a pretty basic understanding of shell scripting - i tried to teach myself today but I couldn't really understand the syntax of the for loop or the syntax of how to write a .java file call, but I would be able to write them in shell script with a little help.
This will do:
#!/bin/bash
javac Testfile.java # compile the program
for((i=1;i<=50;i++))
do
echo "Output of Iteration $i" >> outfile
java Testfile >> outfile
done
This will compile your java program and run it for 50 times and store the output in a file named outfile. Likewise, you can change the 50 for the number of iterations you want.
#!/bin/bash
for i in {1..10}
do
#insert file run command here
done
#!/bin/bash
LOOPS=50
for i IN {1 .. LOOPS}
do
java TestFile >> out.log
done

Help with aliases in shell scripts

I have the following code, which is intended to run a java program on some input, and test that input against a results file for verification.
#!/bin/bash
java Program ../tests/test"$#".tst > test"$#".asm
spim -f test"$#".asm > temp
diff temp ../results/test"$#".out
The gist of the above code is to:
Run Program on a test file in another directory, and pipe the output into an assembly file.
Run a MIPS processor on that program's output, piping that into a file called temp.
Run diff on the output I generated and some expected output.
I made this shell script to help me automate checking of my homework assignment for class. I didn't feel like manually checking things anymore.
I must be doing something wrong, as although this program works with one argument, it fails with more than one. The output I get if I use the $# is:
./test.sh: line 2: test"$#".asm: ambiguous redirect
Cannot open file: `test0'
EDIT:
Ah, I figured it out. This code fixed the problem:
#!/bin/bash
for arg in $#
do
java Parser ../tests/test"$arg".tst > test"$arg".asm
spim -f test"$arg".asm > temp
diff temp ../results/test"$arg".out
done
It turns out that bash must have interpreted a different cmd arg for each time I was invoking $#.
enter code here
If you provide multiple command-line arguments, then clearly $# will expand to a list of multiple arguments, which means that all your commands will be nonsense.
What do you expect to happen for multiple arguments?

Resources