2013-10-01 16 views
22

Często interakcyjnie przechodzę przez pętlę np. moje pliki i chcę wykonać konkretną operację na nich wszystkich, załóżmy, że chciałbym zmienić nazwę wszystkich plików:Pokaż polecenia bez ich wykonywania

for file in $(ls); do mv "$file" "${file}_new"; done 

To działa dobrze. Ale przed wywołaniem tego polecenia, chciałbym zobaczyć, co faktycznie robi, więc chciałbym dodać echo przed

for file in $(ls); do echo mv "$file" "${file}_new"; done 

to wtedy pokazuje mi wszystkie polecenia by ją wywołać. Jeśli jestem z nich zadowolony, usuwam echo i uruchamiam go.

Jednak, gdy polecenia są nieco bardziej subtelne, może obejmować rury lub więcej niż jedno polecenie, to już nie działa. Oczywiście mógłbym użyć ', więc znaki specjalne nie zostaną zinterpretowane, ale wtedy nie mam rozszerzenia parametrów. Mógłbym także uciec od specjalnych postaci, ale stałoby się to bardzo nudne.

Moje pytanie brzmi, jaki jest najlepszy sposób na zrobienie tego? Przeczytałem w man bash o opcji -n, która wykonuje polecenie "Odczytaj komendy, ale ich nie wykonuj." Może to być użyte do sprawdzenia skryptu powłoki pod kątem błędów składni. Jest to ignorowane przez powłoki interaktywne. " Dokładnie tego potrzebuję, ale potrzebuję go do interaktywnej powłoki. Zauważ, że opcje -x lubnie pomagają, ponieważ nie tylko pokażą komendę, ale także wywołają ją, a wtedy może być już za późno.

+1

Technicznie rzecz biorąc, nie ma sposobu, aby to osiągnąć. – devnull

+0

Alternatywnie możesz * alias-opróżnić * każde polecenie w coś takiego jak 'alias = 'bash -c" "'', aby parametry zostały zaakceptowane, ale nic nie zostanie wykonane. Możesz uruchomić pętlę * alias-emptifier *, wykonać żądany proces, a później * alias-restore * polecenia - przywracając ich funkcjonalność. – Rubens

+2

Nawiasem mówiąc, użycie 'for file in $ (ls)' poświęca dziecko (proces) bez ważnego powodu. Dlaczego nie użyć 'dla pliku w *'? – cdarke

Odpowiedz

21

This wątek powie ci dlaczego opcja pokazywania poleceń zamiast wykonania tych (a.k.a sucho) nigdy nie będą realizowane za bash.

Patrz odpowiedź z Eric Blake:

> Moje pytanie brzmi, dlaczego nie może taka opcja lub być dostarczane,

Trochę myśl by pokazać, dlaczego to nigdy nie będą realizowane. Co Czy takie wyjście rozwiązaniem dla następujących elementów:

if complex_command; then 
    foo=command1 
else 
    foo=command2 
fi 
$foo args 

na linii $foo args, nie ma sposobu, aby wiedzieć, co $foo rozszerza się chyba wcześniej wykonane (nie tylko skanowane) na complex_command. W związku z tym nie ma sposobu, aby wysuszyć bieg, jaki będzie wynik końcowy, bez uruchamiania elementów, ale uruchamianie przedmiotów jest przeciwne do osiągnięcia celu suchego biegu.

Powiedział, że może być zainteresowany w projekcie bashdb, który wykorzystuje bash haczyki, aby zapewnić interfejs debuggera gdzie co można jednoetapowy przez skrypt bash; nie jest to to samo, co podpowiedź, co zrobiłby skrypt , ale przynajmniej pozwala ci kontrolować, jak dużo lub mało skryptu jest faktycznie uruchamiany.

16

Nie ma opcji na „sucho”, jak explained by devnull ale istnieje proste obejście:

debug= 
#debug=echo 

$debug mv "$file" "${file}_new" 

Jeśli usunąć wpis z drugiego zadania (bez zmieniania czegokolwiek innego), włączyć " dry run "dla niebezpiecznej komendy mv.

Bardziej wyszukane podejście byłoby sprawdzić jakiś warunek (jak opcja linii poleceń):

debug= 
if [[ ...enable dry run?... ]]; then 
    debug=echo 
fi 

Uwaga: pusty zadaniem jest konieczne tylko wtedy, gdy masz możliwość -u ("leczyć zmienne nieustawione jak błąd podczas podstawiania. ") włączone.

+0

Co musi zostać przypisane, aby przywrócić debugowanie do jego ustawień początkowych, niezależnie od tego ustawienia? PS: Z jakiegoś powodu wydaje się, że debugowanie nie jest dostępne w moim bashie –

+1

@GeorgeVasiliou 'debug' jest po prostu zmienną lokalną, do której albo nie przypisuję nic, albo polecenie, które po prostu drukuje swoje argumenty (' echo'). Aby przywrócić efekt, po prostu nie przypisuj niczego ponownie: 'debug ='. –

+0

To nie zadziała, jeśli użyjesz przekierowań. –

6

Jest github pakiet nazywany może być, oto przykład:

$ maybe rm file 
> maybe has prevented rm file from performing 1 file system operations: 
> 
> delete /home/user/file 
> 
> Do you want to rerun rm file and permit these operations? [y/N] 
Powiązane problemy