0

I am trying to upload a file to Azure cloud by passing the command in python which will then execute it inside terminal.

Standard syntax is

azcopy cp "path\to\file\filename.txt" "https://[azure_blob_url]"

The code I am using is,

p1 = subprocess.run(
    'azcopy cp "Desktop/pywatchdog/{}"'.format(
        os.path.basename(event.src_path) + " " + '"https://[azure_blob_url]"'
    ),
    shell=True,
)

I have tried few methods but I just cannot get the command to syntactically correct with correct concat.

Any ideas please?

Vishal Singh
  • 6,014
  • 2
  • 17
  • 33
srt243
  • 63
  • 6
  • You have an extra `)` before `shell = True` – Asocia Jun 24 '20 at 09:53
  • 1
    And it should be `.format(os.path.basename(event.src_path))` I believe. One additional `)` at the end. – Asocia Jun 24 '20 at 09:54
  • try this `subprocess.run(['azcopy', 'cp', 'path\to\file\filename.txt', 'https://[azure_blob_url]'] , shell=True)`. If you want to pass it as a string then use `subprocess.call()` – deadshot Jun 24 '20 at 09:57
  • @Asocia - Eagle eye. Thanks a lot. – srt243 Jun 24 '20 at 10:25
  • @komatiraju032 Both `subprocess.run()` and `subprocess.call()` accept either a string or a list of strings as the first argument. In the latter case `shell=True` should not be present. (It can work on Windows by a happy coincidence of how Python passes arguments to the shell on that platform, but really isn't correct.) – tripleee Jun 24 '20 at 17:04

1 Answers1

0

The double quotes protect the file name from several shell expansion mechanisms, but still won't disable interpolation of dollar signs or backticks, and will break in peculiar ways if the file name contains a literal double quote character. You could use shlex.quote(), but a much better solution is to not involve the shell at all.

p1 = subprocess.run([
    'azcopy', 'cp', "Desktop/pywatchdog/{}".format(
        os.path.basename(event.src_path)),
    'https://[azure_blob_url]'],
    shell=False
)

This also coincidentally fixes the misplaced parentheses in your attempt.

The shell=False isn't strictly necessary here, as it is the default. Notice how the first argument to subprocess.run() is now a list of strings, instead of a single string. See also Actual meaning of 'shell=True' in subprocess

tripleee
  • 175,061
  • 34
  • 275
  • 318