1

I am trying to run a shell script from python by exporting the python variable to the shell script instead of directly reading them from the user. A question regarding passing array values as variable to shell script was answered successfully earlier and helped me to pass the values in an array as a input variable to the shell script. I want to export multiple variables such as FLUID, TTYPE and FLIBRARY from the following python script:

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE])

to the following shell script named testfile1:

#!/bin/bash
echo "$FLUID, $FLIBRARY" | ./vls.exe
for i; do
awk 'NR==8 {$1="     " a }1'  a=$i  spacingcontrol.vls > tmp.vls && mv tmp.vls spacingcontrol.vls 
awk 'NR==8 {$2="  " b "      "}1'     b=$i spacingcontrol.vls > tmp.vls && mv tmp.vls spacingcontrol.vls 
done
Community
  • 1
  • 1
Aspro
  • 45
  • 2
  • 7
  • Do you have an idea of how you might be able to do this? Have you written any code to explore that idea? – Tom Karzes May 25 '16 at 23:45
  • @TomKarzes In the piece of python code you see above, I am able to send the HSPACE as a variable to shell script, however, I do not know how to send multiple variables at the same time. – Aspro May 25 '16 at 23:47
  • @Arya, ...when you asked, in the other question, how to do that with multiple variables, I thought you meant multiple *arrays*. It's easier to the point of being trivial if there's only one array -- you just put the other values first, and pop them off the list with `shift`. – Charles Duffy May 26 '16 at 14:41

3 Answers3

1

You could set them as environment variables within the Python script:

import os 
import subprocess

os.environ['FLUID'] ="MDM"
os.environ['TTYPE'] = str(0)
os.environ['FLIBRARY'] = "RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE])
bmb21
  • 86
  • 1
  • 8
  • The variables are exported successfully using this, however how can I call them in the shell script? – Aspro May 26 '16 at 13:20
  • @Arya, `$FLUID`, `$TTYPE` and `$FLIBRARY`; the only reason you couldn't do this in your other question is that there you needed an array. If this doesn't work precisely as-is, see the `env` argument to `subprocess.call`. – Charles Duffy May 26 '16 at 14:02
  • @Arya, ...btw, there's also a separate argument to `subprocess.Popen` for the environment, so such arguments can be passed that way. – Charles Duffy May 26 '16 at 14:02
  • (now, as another aside, the names for these shouldn't be all-caps -- see fourth paragraph of the POSIX standard at http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html) – Charles Duffy May 26 '16 at 14:03
0

Is it an option for you to pass the variables as parameters?

subprocess.call(['./testfile1 %s %s' % (FLUID, FLIBRARY)] + [str(n) for n in HSPACE])

and in the bash script

#!/bin/bash
FLUID=$1
FLIBRARY=$2
echo "$FLUID, $FLIBRARY" | ./vls.exe
Kevin Grant
  • 591
  • 6
  • 15
  • %d requires an integer to work and does not work with a string, if I am not wrong? – Aspro May 26 '16 at 00:01
  • @Arya Sorry, that is what I meant to write. My mistake. Edited the answer to represent this – Kevin Grant May 26 '16 at 00:02
  • I tried this methond and I get the following error : OSError: [Errno 2] No such file or directory – Aspro May 26 '16 at 13:57
  • Using string-substitution to put your arrays on the command line is a recipe for shell injection vulnerabilities. Pass a literal argv array instead. – Charles Duffy May 26 '16 at 14:01
  • ...also, this doesn't work at all since it's passing a first argument that requires a shell to parse it, but isn't using `shell=True`. And if you tried to fix it by adding `shell=True`, then the `HSPACE` entries would no longer be present on argv. – Charles Duffy May 26 '16 at 14:06
0

Through the environment

#!/usr/bin/env python
import subprocess

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]
subprocess.call(['./testfile1'] + [str(n) for n in HSPACE],
  env={'fluid': FLUID, 'ttype': str(TTYPE), 'flibrary': FLIBRARY})

...thereafter, in shell:

#!/bin/bash
hspace=( "$@" )
declare -p fluid ttype flibrary hspace # print values

...output being:

declare -x fluid="MDM"
declare -x ttype="0"
declare -x flibrary="RefProp"
declare -a hspace='([0]="0.01" [1]="0.009" [2]="0.008" [3]="0.007")'

On the command line

Another approach is to use positional arguments.

#!/usr/bin/env python
import subprocess

FLUID="MDM"
TTYPE=0
FLIBRARY="RefProp"
HSPACE=[0.01, 0.009, 0.008, 0.007]

subprocess.call(['./testfile1', str(FLUID), str(TTYPE), str(FLIBRARY)] + [str(n) for n in HSPACE])

...and, in shell:

#!/bin/bash
fluid=$1; shift
ttype=$2; shift
flibrary=$3; shift
hspace=( "$@" )
declare -p fluid ttype flibrary hspace # print values

...output being:

declare -- fluid="MDM"
declare -- ttype="RefProp"
declare -- flibrary="0.009"
declare -a hspace='([0]="0.01" [1]="0.009" [2]="0.008" [3]="0.007")'

Note:

  • Use of awk -v var="$val" is the correct way to pass variable values from bash to awk; other approaches risk code injection vulnerabilities.
  • Use of lower-case names for user-defined environment variables is compliant with POSIX convention to avoid namespace collisions; see relevant spec.
Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
  • Thanks for the insight on namespace collision, will keep in mind ! – Aspro May 26 '16 at 14:59
  • I tried running both these methods and end up getting an error where the code is unable to execute vls.exe. However when I run the shell script as standalone from the terminal and take FLUID, FLIBRARY, etc as user inputs, it works fine. – Aspro May 26 '16 at 15:01
  • @Arya, when trying these methods, did you use the *exact* code given in my answer? I can test the code here to work; I can't test 3rd-party adaptations. – Charles Duffy May 26 '16 at 15:05
  • @Arya, ...I've updated the code samples to be complete standalone, so you can copy-and-paste them straight into otherwise-empty files and have them work -- and am now showing output for each. – Charles Duffy May 26 '16 at 15:10
  • @Arya, ...the only place where I could see things being broken is if you're running on Windows -- passing `env=...` will override default environment variables like PATH there (and the way the argv works is different as well -- it's all-round a screwy platform). But your question isn't *tagged* for Windows... – Charles Duffy May 26 '16 at 15:14
  • Im running everything in Linux itself. Thanks, this works as far as importing the variables is concerned. Although I am still not sure why the vls.exe is not running as a part of the shell script after these variables are imported. I am trying now to fix that issue. – Aspro May 26 '16 at 16:36
  • "is not running" is pretty vague. While it might be beyond the scope of this question, care to describe exactly what occurs? – Charles Duffy May 26 '16 at 16:39