unikanie używania shell=True w subprocess

unikanie używania shell=True w subprocess
SY
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 25
0

Witam
Czytam że rekomendacją jest używanie unikania shell=True ale nie rozumiem jak tego uniknąć jak bez tego nie działa np. ta komenda. Jak nie dasz shell=True to jest błąd "No such file directory, file not found". To to zależy od kontekstu kiedy unikać a kiedy nie? Jak z shella coś wywołujemy to nie unikać? Działam na linuksie jakby to miało znaczenie.

Kopiuj
result = subprocess.run('''/usr/bin/python -c "print('This is directly from a subprocess.run() function')" ''', capture_output = True, text = True, shell = True)
overcq
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 402
0

Ale to działa:

Kopiuj
import subprocess
result = subprocess.run( [ "/usr/bin/python", "-c", "print('This is directly from a subprocess.run() function')" ], capture_output = True, text = True )
Riddle
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 10227
2

Chodzi o to że jak uruchamiasz program, to przekazujesz do niego parametry uruchomieniowe - często to się nazywa argv (czasami dostajesz też argc).

Kiedy wpisujesz polecenie w terminalu:

Kopiuj
/usr/bin/python -c "print('This is directly from a subprocess.run() function')"

To powłoka (np. /bin/bash) interpretuje to polecenie. Gdyby miało jakieś specjalne instrukcje jak if albo nawiasy to dodatkowo by je ewaluowało. Powłoka rozpoznaje że ma uruchomić program /usr/bin/python, a pozostałą część inputu parsuje i przekazuje jako tablicę stringów, podobnie jak @overcq napisał wyżej:

"/usr/bin/python" - ten program uruchom
["-c", "print('This is directly from a subprocess.run() function')"] - to przekaż jako argv

Więc rada żeby nie używać shell=True jest dobra, bo wtedy możesz sam dokładnie sprecyzować jakie parametry wejściowe mają być przekazane do programu. Kiedy korzystasz z shell=True, to tak na prawdę konstruujesz polecenie, które ma być zinterpretowane przez powłokę, po to żeby wyszły parametry uruchomieniowe jakie chcesz - tylko po co to robić, skoro możesz po prostu przekazać te parametry uruchomienione. W takim prostym przykładzie to może nie mieć aż takiego znaczenia, ale gdybyś chciał przekazać parametry które mają jakieś znaki specjalne, np. $, ', ", (, etc. to mogłoby być trudno skonstruować taki skrypt basha, żeby wyszły parametry które chcesz - bo bash sobie je zinterpretuje dodatkowo. A w Pythonie jest to stosunkowo proste.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.