1

I have been researching over the internet

like How to pass parameter to inside python code which is embedded within Unix function

Overview :

function_name()
{

python -c << END 
...... python code .....
...... python code .....
...... python code .....
END 

}

Below is the way I call above Unix function into my main.sh script and execute it

. /d/demo/function.sh

echo "Function started"
function_name 10 5 
echo "Function ended"

If parameter passed to function was a digit[number] , then I was successful in passing parameter to python script like below and got expected output : 15

function_name()
{
    get_value1="$1"
    get_value2="$2" python -c << END 
    import os 
    firstparameter=int(os.environ['getvalue1'])
    secondparameter=int(os.environ['getvalue2'])
    C=firstparameter + secondparameter
    print (C)
    END 
}

But if i want to pass string like path ='/d/demo/ABC' , How to do ?

concatenate_ABC()
{
    a="$1"
    b="$2" 
    c="$3"
    python -c << END

    import os 
    get_path=int(os.environ['a'])
    get_filename=int(os.environ['b'])
    get_nm=int(os.environ['c'])

    with open (get_path+'/'+get_filename,r) as f:
                 
        fname=get_path +'/' + get_nm 
        print (fname) 
    END 
}

Below is the way I call above Unix function into my main.sh script and trying to execute not able to achieve

. /d/demo/function.sh

echo "Function started"
concatenate_ABC "/d/demo/ABC" "Dummy.txt" "XYZ"
echo "Function ended"

The Dummy.txt file as list of path name

/d/d1
/d/d2
/d/d3
/d/d4  

So from function the parameter should be passed to python code like below

concatenate_ABC "/d/demo/ABC" "Dummy.txt" "XYZ"

The above 3 parameters should be used in code like below

    get_path="/d/demo/ABC"
    get_filename=Dummy.txt
    get_nm=XYZ

with open (get_path + '/' + get_filename,r) as f:
    fname=get_path +'/' + get_nm 
    print (fname)
codeholic24
  • 955
  • 4
  • 22
  • 1
    Maybe see https://www.tutorialspoint.com/python/python_command_line_arguments.htm or https://realpython.com/python-command-line-arguments/#the-sysargv-array . I don't know if it is possible to combine command line arguments with feeding the Python script into `python`'s standard input. That's why it would be better to write the Python code as separate Python scripts as suggested by [Raspberry PyCharm](https://stackoverflow.com/users/11720594/raspberry-pycharm) – Bodo Jun 16 '21 at 12:47
  • @Bodo I got your point but I want it without creating extra script file that is the reason i embedded into only one script within a Unix function itself , if you see it works for this `function_name()` where i am passing `function_name() 10 5` it should be working for string also – codeholic24 Jun 16 '21 at 12:51
  • Then try something like `python "$script" "arg1" "arg2" ...`, see https://stackoverflow.com/a/32239857/10622916 and the other answers . – Bodo Jun 16 '21 at 12:59
  • Not a very clean way, but you also could create templates of your scripts to populate with arguments later, using `envsubst` (see [this answer](https://serverfault.com/a/960077)). – Lenormju Jun 17 '21 at 16:41

1 Answers1

2

OP's approach will work, but casting to int while accessing environment variable is wrong since these are strings. However, there are many other types and issues:

  • OP is not exporting the environment variables, so they won't be accessible from the script.
  • The open call has a typo, the second argument should be 'r' instead of `r'.
  • The END of here document can't be indented.

Some of the above problems also exist with OP's first example that apparently worked, but I don't see anyway it could have.

Here is a function that works (note that the content inside here document is indented with a hard tab character). Also, OP is opening the file but not doing anything with the contents, so I added a loop showing its use (needed for my own test):

concatenate_ABC()
{
    read -r -d '' script <<-"----END"
    import os
    get_path=os.environ['a']
    get_filename=os.environ['b']
    get_nm=os.environ['c']
    
    with open(get_path+'/'+get_filename, 'r') as f:
        for line in f:
            fname=get_path +'/' +line.strip()+'/'+ get_nm 
            print(fname) 
----END
    export a="$1"
    export b="$2" 
    export c="$3"
    python -c "$script"
}

Considering one can also pass arguments to python -c, we don't actually need to make use of environment variables (again watch for tab chars):

concatenate_ABC()
{
    read -r -d '' script <<-"----END"
    import sys
    get_path = sys.argv[1]
    get_filename = sys.argv[2]
    get_nm = sys.argv[3]
    
    with open(get_path+'/'+get_filename, 'r') as f:
        for line in f:
            fname=get_path +'/' +line.strip()+'/'+ get_nm 
            print(fname) 
----END
    python -c "$script" $*
}
haridsv
  • 9,065
  • 4
  • 62
  • 65