Wdrożenie suchobiegu w skryptach bash

15

Jak zaimplementować opcję suchobiegu w skrypcie bash?

Mogę wymyślić albo zawinięcie każdego polecenia w if i powtórzenie polecenia zamiast uruchamiania go, jeśli skrypt działa na sucho.

Innym sposobem byłoby zdefiniowanie funkcji, a następnie przekazanie każdego wywołania polecenia przez tę funkcję.

Coś jak:

function _run () {
    if [[ "$DRY_RUN" ]]; then
        echo $@
    else
        $@
    fi
}

`_run mv /tmp/file /tmp/file2`

`DRY_RUN=true _run mv /tmp/file /tmp/file2`

Czy to po prostu źle i istnieje na to znacznie lepszy sposób?

Andrei Serdeliuc
źródło
Więc chcesz wydrukować, co zrobi polecenie (w tym wartości $ VARIABLES) bez faktycznego wykonania polecenia. Używam czegoś takiego jak twoja _run()funkcja, czasami z 'set -xv', ale chciałbym lepszy sposób.
Stefan Lasiewski
tak, dokładnie to. Zastanawiam się, czy nie ma wewnętrznej zmiennej, którą można ustawić w bash, więc polecenia nie są tak naprawdę wykonywane, zamiast przekazywania ich przez funkcję
Andrei Serdeliuc
2
Nie ma powodu, dla którego to pytanie powinno zostać oznaczone jako wiki społeczności.
Wstrzymano do odwołania.
Bash jest powłoką. Nie ma powodu, aby robić to na sucho. Nie sądzę, że istnieje lepszy sposób na zrobienie tego niż wcześniej.
d -_- b

Odpowiedzi:

2

Zobacz BashFAQ / 050: Próbuję umieścić polecenie w zmiennej, ale złożone przypadki zawsze zawodzą! do dyskusji na ten temat.

Chociaż teraz usunięty, sekcja Jak dodać możliwość testowania do programów może być nadal przydatna.

Dennis Williamson
źródło
Nie jest to alternatywa, ale wygląda na doskonały zasób do testowania i pracy z dłuższymi programami bash.
Andrei Serdeliuc
Cofnąłem edycję, która dodała kotwicę do określonej części połączonej strony, ponieważ celem mojej odpowiedzi, jak wspomniano, jest przeczytanie dyskusji jako całości, a nie wskazanie jednej konkretnej części poradnika. Celem połączonej strony jest na ogół próba unikania wstawiania poleceń do zmiennych, ponieważ istnieje wiele gotchas.
Wstrzymano do odwołania.
Byłoby o wiele bardziej użyteczne, gdyby ta odpowiedź podsumowała najważniejsze punkty tego artykułu. Odpowiedzi w jednym wierszu są nadal słabymi odpowiedziami.
Mark Booth,
4

Chciałem zagrać z odpowiedzią @Dennis Williamson's. Oto co mam:

Run () {
    if [ "$TEST" ]; then
        echo "$*"
        return 0
    fi

    eval "$@"
}

Jest eval "$@"to ważne tutaj i jest lepsze niż po prostu robienie $*. $@zwraca wszystkie parametry i $*zwraca wszystkie parametry bez białych znaków / cudzysłowów.

$ mkdir dir
$ touch dir/file1 dir/file2
$ FOO="dir/*"
$ TEST=true Run ls -l $FOO
ls -l dir/file1 dir/file2
$ Run ls -l $FOO
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file1
-rw-r--r--  1 stefanl  stefanl  0 Jun  2 21:06 dir/file2
Stefan Lasiewski
źródło