1

As part of a BASH-script I need to launch some python-code with an input-parameter. I also want to avoid creating an temporary *.py-files.

This is what I have so far:

input=123
output=$(
python - <<'END_SCRIPT'
print("$input")
END_SCRIPT
)
echo $output

This snippet writes the output of the python-call into an output-variable. But instead of returning "123" it returns "$input", because the variable with not be interpreted during the piping into python. Is there any way to forward the input variable as a parameter to python while reading from StdIn?

Carsten
  • 1,612
  • 14
  • 21

3 Answers3

7

I guess you are looking for

input=123
output=$(python - "$input" <<'END_SCRIPT'
import sys
print(sys.argv[1])
END_SCRIPT
)
echo "$output"

(Notice also When to wrap quotes around a shell variable.)

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • 1
    As a stylistic choice, you can also put the here document outside the command substitution: `output=$(python - "$input") << 'END_SCRIPT'`, as Python will inherit its standard input from the assignment. – chepner Dec 10 '20 at 16:44
  • @chepner I dont get that comment. How to make this into a solution or to improve the given solution? – Carsten Dec 10 '20 at 19:05
  • @Peter Literally, you just move the `)` to just before the `<<`. Like I said, it's a style choice, not an improvement, as I'm not aware of any significant difference between putting the quoted here-document inside the command substitution versus leaving it outside. – chepner Dec 10 '20 at 19:19
  • @chepner I tried moving the bracket, but that does not run at all on MacOS with BASH. – Carsten Dec 13 '20 at 15:21
  • I can confirm - contrary to my expectation - that Bash 3.2 on MacOS Catalina starts an interactive Python interpreter if you move the redirection outside the command substitution. – tripleee Dec 13 '20 at 16:10
  • Also the more reason to avoid `bash` 3.2; this is a bug, or at the very least non-POSIX behavior, that was corrected in `bash` 4. – chepner Dec 13 '20 at 16:48
0

Just get rid of the single quotes around END_SCRIPT

input=123
output=$(
python - << END_SCRIPT
print("$input")
END_SCRIPT
)
echo $output
prithajnath
  • 2,000
  • 14
  • 17
  • 2
    This is problematic if the real Python script needs to contain literal backticks or dollar signs anywhere in it. – tripleee Dec 10 '20 at 15:30
  • @tripleee good call. I edited my answer. I assumed OP has some control over `input` in which case they could escape those characters before passing them to Python – prithajnath Dec 10 '20 at 15:44
  • 2
    Making the caller responsible for adapting the input is just asking for mistakes. – chepner Dec 10 '20 at 16:33
0

At the end I decided to skip passing any input variable to python at all and better set an environment variable as needed. Here my final result:

input='<123!>'
output=$(python3 - <<'END_SCRIPT'
import os
print(os.environ['input'])
END_SCRIPT
)
echo "$output"
Carsten
  • 1,612
  • 14
  • 21