Call shell script from within Google Cloud function

Question:

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

Asked By: finisinfinitatis

||

Answers:

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.

Answered By: Kolban

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)
Answered By: techd