Выполняющемуся подпроцессу не удается найти указанный файл в Windows

#python #subprocess #jython-2.5

#python #подпроцесс #jython-2.5

Вопрос:

Я работаю в системе с Jython2.5, но мне нужно иметь возможность вызывать некоторые API Google, поэтому я написал автономный скрипт, который я хотел вызвать из своей среды Jython и возвращать мне небольшие фрагменты данных. Например, JobID, URL-адрес листа или что-то еще из Google.

Я перепробовал несколько способов, но я всегда получаю сообщение об ошибке от Windows, в котором говорится, что он не может найти указанный файл.

Путь выполняется двумя способами.

Первый способ с использованием строки

 stringPath = r"‪C:GooglePipesScriptsfiletobq.py C:GooglePipesKeysDEV-BigQueryKey.json nofile C:GooglePipesBQ_DowntimeTESTFILE.CSV dataset1 table1"
  

И второй способ, в виде последовательности (согласно документам, используя shell=false укажите последовательность)

 seqPath = [r"‪C:GooglePipesScriptsfiletobq.py",r"C:GooglePipesKeysDEV-BigQueryKey.json","nofile",r"C:GooglePipesBQ_DowntimeTESTFILE.CSV","dataset1","table1"]
  

Вызывается с

 data, err = Popen(seqPath, shell=True, stderr=PIPE, stdout=PIPE).communicate()


#Read values back in
print data
print err
  

Заменив seqPath на stringPath , чтобы попробовать в любом случае.

Я занимался этим все выходные, каждый раз, когда я запускаю его, я получаю из Windows

 The system cannot find the path specified.
  

из err печати. Мне не удалось выполнить дальнейшую отладку. Я не совсем уверен, что происходит. Когда я вставляю stringPath переменную непосредственно в командное окно моего компьютера, она выполняется.

Я также позвонил subprocess.list2cmdline(seqPath) , чтобы посмотреть, что он выводит. Это дает мне? перед строкой, но я не смог выяснить, что это значит. Я могу вставить оставшуюся часть строки, начинающуюся после вопросительного знака, в командное окно, и она выполняется.

 ?C:GooglePipesScriptsfiletobq.py C:GooglePipes...
  

Я перепробовал несколько различных комбинаций true и false в shell, передавая разные аргументы в Popen , двойные косые черты, и у меня открыто не менее 30 вкладок из stack overflow и других справочных форумов. Я просто понятия не имею, что делать на данный момент, и любая помощь приветствуется.

Редактировать

Что? в начале sting фактически нулевой символ, когда я выполнял некоторые дополнительные протоколирования. Похоже, это корень моей проблемы. Я не могу понять, почему он появляется, но он присутствовал в моих копиях вставок. Я начал вводить текст вручную, и у меня все заработало. Когда я указываю путь в своей программе Jython, он снова присутствует.

Комментарии:

1. shell=False совершенно неправильно, когда одна строка имеет несколько аргументов (в UNIX; Windows имеет свои собственные правила) — оболочка выполняет работу по разделению строки на список элементов argv, передаваемых системному вызову семейства OS execv .

2. Аналогично, в UNIX вы не должны использовать shell=True при передаче многоэлементный список, если только первый элемент этого списка не является сценарием оболочки, а остальные элементы не являются аргументами этого сценария. Но это все просто информация в сторону, поскольку это не ваша фактическая платформа под рукой.

3. @CharlesDuffy: Почему это должен быть сценарий оболочки (при условии, что у него была ошибка)?

4. @DavisHerring, subprocess.Popen([arg1, arg2, ...], shell=True) в UNIX, arg1 ожидается, что это будет не имя сценария оболочки, а фактический встроенный текст самого сценария оболочки. Он расширяется до ['sh', '-c', arg1, arg2, ...] и sh требует, чтобы аргумент, следующий непосредственно -c за ним, был текстом скрипта для выполнения. (В контексте этого выполнения arg2 становится $0 , следующий за ним аргумент становится $1 и т.д.).

5. @DavisHerring, … если вы не будете следовать этому правилу, ваши дальнейшие аргументы просто исчезнут, не будучи выполненными: Considered subprocess.Popen(['ls', '/tmp'], shell=True) ; /tmp передается в $0 , но сценарий оболочки ls не проверяет $0 , поэтому программе ls , которая запускается, никогда не передается /tmp аргумент.

Ответ №1:

В конечном итоге ошибка заключалась в символе ? / NULL.

Я вернулся к исходному значению, где программа захватывала путь, и оно присутствовало там. После того, как я вручную перенастроил его, все начало работать.

Если вы скопируете и вставьте то, что я ввел в вопрос, вы можете увидеть нулевой символ в строке, если вы запустите его через string-> ASCII converter.

 >C:
>NULL 67 58 
  

Что за чушь собачья ***.