简体   繁体   中英

Call shell script from within Google Cloud function

I am trying to invoke a simple shell script in a Google Cloud Function using Python. However, for some reason the script cannot be found even though I found out that it is in the same directory on the environment.

The script of my main.py looks as it follows:

import subprocess
import os

def reload_plm(request):
    request_json = request.get_json()
    if request.args and 'message' in request.args:
        return request.args.get('message')
    elif request_json and 'message' in request_json:
        return request_json['message']
    else:
        files = [f for f in os.listdir(os.getcwd()) if os.path.isfile(f)]
        print(os.getcwd()) # output: /workspace
        print(files) # output: ['gettoken.sh', 'k.key', 'main.py', 'requirements.txt']
        load_token()
        return f'Hello World!'


def load_token():
    output = subprocess.call(["/workspace/gettoken.sh","k.key","argument1", "argument2"])
    print(output)

As you can see I tried even using the absolute path of the script after the relative path did not work, but it is the same result which is:

FileNotFoundError: [Errno 2] No such file or directory: '/workspace/gettoken.sh'

or

FileNotFoundError: [Errno 2] No such file or directory: './gettoken.sh'

I tested the script locally and it did work. What am I doing wrong here?

Edit: As pointed out by Kolban one should not assume the existence of a certain OS environment. However if you find yourself on Linux this works:

Solution : I found the reason for this. It is because I used in my script #!/bin/sh instead of bash. Apparently this shebang causes that only PATH is evaluated but not the current directory. I solved this by modifying the command to . ./gettoken.sh . ./gettoken.sh

The thinking is that maybe we want to avoid invoking shell scripts from within a Cloud Functions environment. The notion of Cloud Functions is that you are presented with an environment in which your programming language function can be executed. Executing a shell script from within makes assumptions including "Running in Linux/Unix", "Ability to fork an additional process", "Permissions to run script", "There is a shell binary to even be run". I'd suggest that if you want to own the environment, look to Cloud Run.

I tried using the same. ./sleep.sh and still get no file found File struct: main.py sleep.sh


"/opt/python3.10/lib/python3.10/subprocess.py", line 969, in init

self._execute_child(args, executable, preexec_fn, close_fds, File "/opt/python3.10 /lib/python3.10/subprocess.py", line 1845, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: '. ./sleep.sh'


main.py is same as your's as i'm testing for sample now using your code: tried "../sleep.sh" ".sleep.sh" "/workspace/.sleep.sh"

import subprocess
import os

def reload_plm(request):
    request_json = request.get_json()
    if request.args and 'message' in request.args:
      return request.args.get('message')
    elif request_json and 'message' in request_json:
       return request_json['message']
    else:
       files = [f for f in os.listdir(os.getcwd()) if os.path.isfile(f)]
       print(os.getcwd()) # output: /workspace
       print(files) # output: ['sleep.sh','main.py','requirements.txt']
       load_token()
       return f'Hello World!'


def load_token():
    output = subprocess.call([". ./sleep.sh"])
    print(output)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM