-1

I'm beginning with bash and I'm executing a script :

$ ./readtext.sh ./InputFiles/applications.txt 

Here is my readtext.sh code :

#!/bin/bash
filename="$1"
counter=1
while IFS=: true; do
  line=''
  read -r line
  if [ -z "$line" ]; then
    break
  fi

  echo "$line"
  python3 ./download.py \
    -c ./credentials.json \
    --blobs \
    "$line"
done < "$filename"

I want to print the string ("./InputFiles/applications.txt") in a python file, I used sys.argv[1] but this line gives me -c. How can I get this string ? Thank you

userHG
  • 567
  • 4
  • 29
  • Show a small snippet of what is in `./InputFiles/applications.txt ` ? – han solo Feb 08 '19 at 16:32
  • It's a text file with a list of AndroidStore applications (com.ddd, com....) – userHG Feb 08 '19 at 16:35
  • Possible duplicate of https://stackoverflow.com/q/20572934/9035237. – Geno Chen Feb 08 '19 at 17:39
  • Why not just pass `"$filename"` as an additional argument when you call `./download.py`? Note that the Python script should also be using `argparse` to make argument processing easier. – chepner Feb 08 '19 at 19:18

2 Answers2

3

It is easier for you to pass the parameter "$1" to the internal command python3.

If you don't want to do that, you can still get the external command line parameter with the trick of /proc, for example:

$ cat parent.sh 
#!/usr/bin/bash

python3 child.py
$ cat child.py
import os

ext = os.popen("cat /proc/" + str(os.getppid()) + "/cmdline").read()
print(ext.split('\0')[2:-1])
$ ./parent.sh aaaa bbbb
['aaaa', 'bbbb']

Note:

  1. the shebang line in parent.sh is important, or you should execute ./parent.sh with bash, else you will get no command line param in ps or /proc/$PPID/cmdline.
  2. For the reason of [2:-1]: ext.split('\0') = ['bash', './parent.sh', 'aaaa', 'bbbb', ''], real parameter of ./parent.sh begins at 2, ends at -1.

Update: Thanks to the command of @cdarke that "/proc is not portable", I am not sure if this way of getting command line works more portable:

$ cat child.py
import os

ext = os.popen("ps " + str(os.getppid()) + " | awk ' { out = \"\"; for(i = 6; i <= NF; i++) out = out$i\" \" } END { print out } ' ").read()
print(ext.split(" ")[1 : -1])

which still have the same output.

tripleee
  • 175,061
  • 34
  • 275
  • 318
Geno Chen
  • 4,916
  • 6
  • 21
  • 39
  • 1
    `/proc` is not portable. This would work on Linux but there are many other UNIX-like systems it would not work on. – cdarke Feb 08 '19 at 17:41
  • @cdarke It's a surprise for me to know `/proc` is not portable. Thank you. I tested on my Manjaro Linux before posting, however I don't know if it works on, for example OS X, after seeing your comment. – Geno Chen Feb 08 '19 at 17:45
  • `/proc` does not exist on OS Mac (or X), it exists on SunOS but does not have the same format as on Linux, so it wouldn't work there either. All you need do is to add the caveat "*If you are using Linux:....*" – cdarke Feb 08 '19 at 17:54
  • @cdarke I am not sure if using `tail` and `awk` to find out the command line from `ps` is a more portable way, see my updated answer. Maybe the format of `ps` will hurt this one? – Geno Chen Feb 08 '19 at 18:00
  • 1
    I factored out the `tail`. You really want to use `subprocess.run` instead of `os.popen` but this is arguably too big a change to be an edit. – tripleee Feb 08 '19 at 18:15
  • 1
    @GenoChen: I would go for `psutil` module from PyPi. That's portable, even works on Windows. It has a function `get_process_cmdline()`. – cdarke Feb 08 '19 at 19:32
  • Hi @tripleee can you please take a look at my post https://stackoverflow.com/questions/54889010/get-a-string-in-shell-python-with-subprocess – userHG Feb 26 '19 at 15:33
-1

This is the python file that you can use in ur case

import sys

file_name = sys.argv[1]

with open(file_name,"r") as f:
    data = f.read().split("\n")

print("\n".join(data))

How to use sys.argv

How to use join method inside my python code