Python: Sprawdź istnienie polecenia powłoki przed wykonaniem [zamknięte]

3

Próbuję znaleźć sposób, aby sprawdzić istnienie polecenia powłoki przed jego wykonaniem.

Na przykład wykonam polecenie ack-grep. Więc próbuję zrobić:

importuj podproces
z podprocesu import PIPE

cmd_grep = subprocess.Popen ([„ack-grep”, „--no-color”, „--max-count = 1”, „--no-group”, „def run_main”, „../cgedit/”], stdout = PIPE, stderr = PIPE)

Niż jeśli wykonam

cmd_grep.stderr.read ()

Otrzymuję „jak wyjście”. Ale na mojej ścieżce nie ma polecenia ack-grep. Dlaczego więc Popen nie wyświetla komunikatu o błędzie w mojej zmiennej .stderr?

Czy jest też łatwiejszy sposób na robienie tego, co próbuję?

Gabriel L. Oliveira
źródło
3
Prawdopodobnie powinieneś o to zapytać na stackoverflow
trolle3000

Odpowiedzi:

3

Możesz użyć modułu podprocesu w Pythonie 3 lub modułu poleceń dla Pythona 2 w następujący sposób:

status, wynik = subprocess.getstatusoutput („ls -al”)

status, wynik = komendy.getstatusoutput („ls -al”)

Następnie sprawdź wartość status.

Przykłady ze strony:

>>> importuj podproces
>>> subprocess.getstatusoutput ('ls / bin / ls')
(0, „/ bin / ls”)
>>> subprocess.getstatusoutput („cat / bin / junk”)
(256, „cat: / bin / junk: Brak takiego pliku lub katalogu”)
>>> subprocess.getstatusoutput ('/ bin / junk')
(256, „sh: / bin / junk: not found”)
Studer
źródło
2

nie możesz jakoś użyć polecenia „który”? które polecenie automatycznie wykonuje wyszukiwanie aplikacji na ścieżkach. Myślę, że wystarczy wywołać to polecenie i podać nazwę polecenia, które chcesz wyszukać, a następnie przeanalizować wyniki.

djmc
źródło
1

Do takich sytuacji używam:

def find_program(prog_filename, error_on_missing=False):
    bdirs = ['$HOME/Environment/local/bin/',
             '$HOME/bin/',
             '/share/apps/bin/',
             '/usr/local/bin/',
             '/usr/bin/']
    paths_tried = []
    for d in bdirs:
        p = os.path.expandvars(os.path.join(d, prog_filename))
        paths_tried.append(p)
        if os.path.exists(p):
            return p
    if error_on_missing:
        raise Exception("*** ERROR: '%s' not found on:\n  %s\n" % (prog_filename, "\n  ".join(paths_tried)))
    else:
        return None

Następnie możesz zrobić coś takiego:

grep_path = find_program('ack_grep', False)
if grep_path is None:
    # default to standard system grep
    grep_path = 'grep'
Jeet
źródło
0

W końcu zostawiłem to działające w ten sposób:

próbować:

    cmd_grep = ["ack-grep", "--no-color", "--max-count=1", "--no-group", function_definition, file_path]

    first_exec = Popen(cmd_grep,stdout=PIPE)

    execution = Popen(cmd_sed, shell=True, stdin=first_exec.stdout, stdout=PIPE)

except:

    #use grep instead

    cmd_grep = cmd_grep = r'grep -R -n "' + function_definition + '" ' + file_path

    execution = Popen(cmd_grep + '|' + cmd_sed,shell=True,stdout=PIPE)

output = execution.stdout.read()
Gabriel L. Oliveira
źródło
-1

To powinno Ci pomóc:

import subprocess 
from subprocess import PIPE
import shutil 

cmd = ["ack-grep", "--no-color", "--max-count=1", "--no-group", "def run_main", "../cgedit/"]
path_to_cmd = shutil.which(cmd[0])    
if path_to_cmd is None:
     print(f"There is no {cmd[0]} on the path!")
else:
    cmd_grep = subprocess.Popen(cmd,  stdout=PIPE, stderr=PIPE) 

Proces myślowy ......... Użyłem tego rozwiązania, aby rozpocząć:

import subprocess
status, response = subprocess.getstatusoutput('which ack-grep')
print(f'Exitcode: {status}, Output: {response}')

Ale to spowodowało konkretną odpowiedź tylko z systemów Linux.

import shutil
shutil.which(cmd[0])

Zwraca ścieżkę do pliku wykonywalnego po wywołaniu „ack-grep” lub None, jeśli nic nie jest wywoływane.

jjisnow
źródło
To byłaby lepsza odpowiedź, gdybyś (1) użył bardziej prawdopodobnego (użytecznego) przykładu poleceń, takiego jak przykład OP w ack-grepporównaniu z grep, a (2) pokazał kod do użycia polecenia, którego chcesz użyć, w porównaniu z użyciem kreacji zastępczej.
Scott