MatrixTXT
MatrixTXT

Reputation: 2502

Cannot use gcloud compute ssh command in python subprocess

I have a compute engine already set up, I can use ssh command in command prompt, like

gcloud compute ssh test-instance@cloud-engine-noapi --zone us-central1-f --command "rm -f test.txt"

and successfully delete the test.txt in server.

However, when I call these in python.

subprocess.call(['gcloud', 'compute', '--project', 'test-project','ssh', temp_instance, '--zone', zone, '--command', '"cd /home"'], shell=True)
subprocess.call(['gcloud', 'compute', '--project', 'test-project','ssh', temp_instance, '--zone', zone, '--command', '"ls -l"'], shell=True)
subprocess.call(['gcloud', 'compute', '--project', 'test-project','ssh', temp_instance, '--zone', zone, '--command', '"rm -f /home/test.txt"'], shell=True)

The return is always like

bash: /command : No such file or directory

and for command like ls

bash: /command : command not found

Is there any process I have to do first?

Upvotes: 1

Views: 1720

Answers (3)

roomrys
roomrys

Reputation: 194

I also ran into this, and similar to Leszek Bulawa and their answer, I was having problems with quotes in my ls command. Originally, I ran this command:

cmd = [
    "gcloud",
    "compute",
    "ssh",
    vm_name,
    "--zone",
    config.VM_ZONE,
    f"--command='ls {remote_dir.as_posix()}'",
]
print(f'Running command: {" ".join(cmd)}')
result = subprocess.run(cmd, shell=True, check=True, capture_output=True)

And received the returncode 127 error:

No such file or directory

But, after removing the quotes from the command:

cmd = [
    "gcloud",
    "compute",
    "ssh",
    vm_name,
    "--zone",
    config.VM_ZONE,
    f"--command=ls {remote_dir.as_posix()}",
]
print(f'Running command: {" ".join(cmd)}')
result = subprocess.run(cmd, shell=True, check=True, capture_output=True)

I received the output I was looking for in result.stdout!

Upvotes: 0

Leszek Bulawa
Leszek Bulawa

Reputation: 33

I know that this is quite old but it took me some time to figure it out. In my case helped avoiding double quotes (despite it's recommended by gcloud cli help).

Example:

subprocess.call(['gcloud', 'compute', f'--project={test-project}','ssh', temp_instance, f'--zone={zone}, '--command=cd /home'], shell=True)

Upvotes: 0

MatrixTXT
MatrixTXT

Reputation: 2502

Though, probably no one has this problem... but I finally come up with a method to solve it.

As the problem only occurs when using subprocess, I bypass it by writing a (bat/sh) file to temporarily save the commands.

Like,

with open(os.path.join(__location__, 'gcloud_command.bat'), 'w') as bat:
            command_arr = []
            for instance in all_instances_name:
                temp_instance = user_name + "@" + instance
                temp_file_path = '/home/' + user_name + '/'
                command_arr.append('call gcloud compute ssh ' + temp_instance + ' --zone ' + zone + ' --command "cd ' + temp_file_path + '; rm -rf ' + temp_file_path + projectname.split('.')[0] + '; rm -f ' + temp_file_path + projectname.split('.')[0] + '*"\n')
                command_arr.append('call gcloud compute scp "' + fullpath_projectname + '" ' + instance + ':' + temp_file_path + '\n')
                if is_zip:
                    command_arr.append('call gcloud compute ssh ' + temp_instance + ' --zone ' + zone + ' ' + ' --command "cd ' + temp_file_path + '; unzip ' + temp_file_path + projectname + '"' + '\n')
            bat.writelines(command_arr)

And execute with

subprocess.Popen(os.path.join(__location__, 'gcloud_command.bat'))

Upvotes: 3

Related Questions