Я создал скрипт, чтобы найти самую последнюю версию кода Visual Studio, загрузить ее и установить на машину с Ubuntu с помощью dpkg.Я не нашел подходящей библиотеки Python для этого и использую subprocess.call () для вызова команды Shell.Это, конечно, не лучший способ сделать это, но это также учебный проект.
Он успешно загружает файл и помещает его в мой каталог ~ / Downloads.Когда я пытаюсь вызвать subprocess.call (), он выдает «OSError: [Errno 9] Bad file descriptor»
Я знаю, что моя командная строка верна.Я могу просто вызвать его из CLI.Но он не работает при вызове через подпроцесс.
Приветствуются любые рекомендации по более эффективному выполнению этого.
"""
Python 3 script
Downloads the latest .deb package for installing VSCode, and installs it
"""
import os # used to direct where to save downloaded file
import subprocess # used to derive filepath of CLI arg
import requests # py3 only
import platform # used to detect the OS
from urllib.request import urlopen, ContentTooShortError, urlretrieve # py3 version of 'import urllib2'
HOME = os.path.expanduser('~')
filePath = HOME + "/Downloads"
fileName = 'vs_code_most_recent_amd64.deb'
outputName = os.path.join(filePath, fileName)
alreadyDownloaded = False
# used in subprocess calls to suppress stdout or stderr
pipeToDevNull = open(os.devnull, 'w')
def IsDownloadable(url):
"""
Check of the link passed in is a downloadable file. Used to shortcut the
processing so that it doesn't attempt to download a URL that isn't
downloadable. Returns True or False.
"""
h = requests.head(url, allow_redirects=True)
header = h.headers
contentType = header.get('content-type')
if 'text' in contentType.lower():
return False
if 'html' in contentType.lower():
return False
return True
def DownloadVSCodePkg(url):
"""
Downloads the file at the specified URL, save it as the above-defined filename
"""
u = urlopen(url)
f = open(outputName, 'wb')
meta = u.info()
fileSize = int(meta.get_all("Content-Length")[0])
fileSizeDL = 0
#blockSize = 8192
blockSize = 16384
while True:
buffer = u.read(blockSize)
if not buffer:
break
fileSizeDL += len(buffer)
f.write(buffer)
status = r"%10d Bytes [%3.2f%%]" % (fileSizeDL, fileSizeDL * 100. / fileSize)
status = status + chr(8)*(len(status)+1)
print("Downloading: {0}".format(status), end="\r", flush=True)
print("Downloading: {0}".format(status))
print("Downloaded: {0}".format(fileName))
f.close()
del f
def CheckDownloadSuccess():
"""
returns bool value if the file we want is in the dir specified
"""
try:
subprocess.check_call("ls " + outputName, stdout=pipeToDevNull, stderr=pipeToDevNull, shell=True)
return True
except subprocess.CalledProcessError:
return False
def UnpackAndInstall():
"""
Invokes dpkg from the linux shell and installs VSCode.
"""
#Detect OS
linuxDistro = platform.linux_distribution()
OSType = linuxDistro[0]
if OSType == 'Ubuntu':
from apt.debfile import DebPackage
pkg = DebPackage(outputName)
command = 'sudo dpkg -i ' + outputName
#The thing that attempts to unpack:
try:
subprocess.check_call(command, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, shell=True)
except subprocess.CalledProcessError:
print("Install Failed.")
def main():
url = 'https://go.microsoft.com/fwlink/?LinkID=760868'
alreadyDownloaded = CheckDownloadSuccess()
if alreadyDownloaded is False:
if IsDownloadable(url):
DownloadVSCodePkg(url)
# check if the download succeeded, if file doesn't already exist.
if CheckDownloadSuccess():
print("Download Successful!\nFile location => " + outputName)
else:
print("Download Failed...")
else:
print('Link broken: need to update the package resource link.')
else:
print("File already exists.")
UnpackAndInstall()
if __name__ == "__main__":
main()
Вот обратная связь и ошибка от CLI:
$ python3 setupVSCode.py
Traceback (most recent call last):
File "setupVSCode.py", line 192, in <module>
main()
File "setupVSCode.py", line 189, in main
UnpackAndInstall()
File "setupVSCode.py", line 95, in UnpackAndInstall
subprocess.call(command, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, shell=True)
File "/usr/lib/python3.6/subprocess.py", line 267, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/lib/python3.6/subprocess.py", line 709, in __init__
restore_signals, start_new_session)
File "/usr/lib/python3.6/subprocess.py", line 1344, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
OSError: [Errno 9] Bad file descriptor