2013-07-04 19 views
7

Moje urywek jest coś takiego:Jak uzyskać kod błędu, gdy wystąpi błąd w powłoce?

$msg=Remove-Item -Recurse -Force C:\users\bkp 2>&1 
if ($LASTEXITCODE -eq 1) 
{ 
    "Encountered error during Deleting the Folder. Error Message is $msg. Please check." >> $LogFile 
    exit 
} 

folderze C: \ Users \ BKP nie istnieje. Mimo że $ msg podaje mi komunikat o błędzie $ LASTEXITCODE to nadal 0. Jak przechwycić flagę?

+0

Można po prostu sprawdzić zmienną błędu $. Zawiera każdy błąd napotkany w twojej sesji, aż do punktu, ponieważ wierzę w limit alokacji pamięci. –

Odpowiedz

9

$ LASTEXITCODE jest wyłącznie dla programów linii poleceń, które zwracają ich status. Cmdlet wbudowane w PS, takie jak Remove-item, zwracają błędy na maksymalnie 3 sposoby. W przypadku ostrzeżeń piszą one wiadomości (lub inne obiekty .NET) do "strumienia ostrzegawczego". W PSv3 istnieje prosty sposób przekierowania tego strumienia do pliku: cmdlet blah blah blah 3>warning.out. Drugi to strumień błędów. Strumień ten może być przekierowywany również ... 2>error.out, lub bardziej typowo błędy są wychwytywane przy pomocy try/catch lub trap, lub zapisywane do zmiennej za pomocą parametru -ErrorVariable (patrz help about_commonparameters). Trzeci sposób polega na "wyrzucaniu" błędów. Jeśli nie zostanie złapany (spróbuj/złap lub pułapkę), zgłoszony błąd spowoduje zakończenie działania skryptu. Generowane błędy ogólnie są podklasami klasy .NET system.Management.Automation.ErrorRecord. ErrorRecord zapewnia znacznie więcej informacji o błędzie niż kod powrotu.

Jeśli element remove nie powiedzie się z powodu błędu nie znaleziono pliku, zapisuje on System.Management.Automation.ItemNotFoundException do strumienia błędów. Używając try/catch możesz filtrować dla tego konkretnego błędu lub innych określonych błędów z elementu remove. Jeśli po prostu wpisujesz polecenia PS z wiersza poleceń, możesz wpisać $error[0]|select-object *, aby uzyskać wiele informacji na temat ostatniego błędu.


Można to zrobić:

try { 
    Remove-Item -Recurse -Force C:\users\bkp 2>&1 
} catch { 
    # oops remove-item failed. Write warning then quit 
    # replace the following with what you want to do 
    write-warning "Remove-item encounter error: $_" 
    return # script failed 
} 
+0

nie ustawia żadnych flag błędów? –

+0

Wygląda na to, że chcesz tylko wiedzieć, czy polecenie zadziałało, czy nie? Jednak nie zawsze jest to decyzja tak/nie. Na przykład można powiedzieć element-usuń, aby usunąć 10 plików, ale kończy się usuwanie 8, ponieważ dwa pliki są używane przez inne programy. Czy uważasz, że sukces lub porażka? Myślę, że prawdopodobnie chcesz użyć try/catch (zobacz help about_try) i jeśli wystąpią jakiekolwiek błędy, to chcesz złapać błąd i przejść z tego miejsca. Będę edytować odpowiedź, aby podać przykładowy kod –

+2

'try..catch' nie działa, ponieważ błąd nie kończy się. Musisz dodać '-ErrorAction Stop' do' Remove-Item', aby uczynić błąd łatwym do odczytania. –

12

Można użyć $?automatic variable określić wynik ostatniego polecenia. Jeśli potrzebujesz dostępu do faktycznego błędu, możesz użyć automatycznej zmiennej $Error. Pierwszy element w tablicy to ostatni błąd:

Remove-Item -Recurse -Force C:\users\bkp 2>&1 
if(-not $?) 
{ 
    $msg = $Error[0].Exception.Message 
    "Encountered error during Deleting the Folder. Error Message is $msg. Please check." >> $LogFile 
    exit 
} 
+0

Świetne .. Pozwól mi spróbować i wrócić .. –

+1

Myślę, że byłoby lepiej dodać '-ErrorAction SilentlyContinue', więc jeśli cmdlet nie powiodło się, ponieważ nie zakończyłoby się i pominąć jeśli instrukcja. i komunikat o błędzie nie będzie drukowany do konsoli dwa razy. – Jackie

+0

@Jackie Tak, jeśli OP chce samodzielnie obsłużyć wszystkie błędy. Z pierwotnego pytania przekierowuje jednak błędy do standardowego strumienia wyjściowego, więc myślę, że nadal chce je zobaczyć. –

Powiązane problemy