#python #linux #bash #shell
#python #linux #bash #оболочка
Вопрос:
Я хочу установить на свой zsh с помощью скрипта Python, поэтому я следую автоматической установке с github. Он используется sh -c
для загрузки сценария установки и выполнения его с помощью sh:
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended
Я хочу сделать это в python
using subprocess
, поэтому я пишу это:
args = [
"sh",
"-c",
"$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
"",
"--unattended"
]
p = subprocess.run(args, check=True)
Однако я получил ошибку, и в ней говорится:
sh 1: #!/bin/sh: Not such file or directory
Я думаю, это означает, что sh интерпретирует строку shebang как команду.
Как это может произойти и как этого избежать?
Большое спасибо!!!!
Комментарии:
1. Вам нужно выполнить скрипт с помощью sh -c ‘/home/foo/test, sh’? Где /home/foo представляет фактический путь к скрипту
2. Я редактирую свое описание. Не могли бы вы перепроверить это?
3. Вы пропустили
$
раньше(curl…
. Вы также должны использоватьshell=True
for subprocess.run .4. @CyrillePontvieux Извините, что пропущенный $ — это просто опечатка. В документе подпроцесса python shell=True просто означает sh -c, поэтому я не думаю, что это суть.
Ответ №1:
Что на самом деле делает ваша команда;
- он выполняется
curl
в текущей оболочке - затем он передает заключенный в кавычки вывод из
curl
вsh -c
То есть строка внутри двойных кавычек — это текст скрипта, который curl
уже был извлечен.
На самом деле ваш код на Python делает что-то другое.
Я бы реорганизовал ее просто
import requests
import subprocess
r = requests.get('https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh')
subprocess.run(['sh'], input=r.text, text=True)
или, возможно, более буквально копирует существующую команду,
subprocess.run(['sh', '-c', r.text, '', '--unattended'])
( requests
здесь нет строгой необходимости, если вы не хотите использовать стороннюю библиотеку.
from urllib3 import PoolManager as u3
r = u3().request('GET', 'https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh')
subprocess.run(['sh', '-c', r.data, '', '--unattended'])
но, как вы можете видеть, использование только стандартной библиотеки Python немного более громоздко.)
Ответ №2:
Проблема в том, что вам потребовалось два раунда оценки: один для расширения подстановки команды, затем второй для обработки ее как кода оболочки. Если бы вы использовали одинарные кавычки в своей командной оболочке, вы бы столкнулись с той же проблемой.
Вы можете явно добавить eval
:
args = [
"sh",
"-c",
"eval "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)""
"",
"--unattended"
]
p = subprocess.run(args, check=True)