Skrypt powłoki: każda linia wywoływana dwukrotnie?

1

Mam skrypt powłoki do konwersji obrazów na efekt haftu. To jest skrypt: skrypt haftu

Ten skrypt jest częścią aplikacji internetowej. Działa normalnie na moim komputerze Mac, jednak po wdrożeniu na moim serwerze internetowym z systemem CentOS 7 zauważyłem, że kiedy go wywołuję (wyświetla stronę podręcznika), każda linia jest duplikowana, patrz:

hafty. sh:

SPOSÓB UŻYCIA: haft [-n numcolours] [-p wzór] [-t grubość] [-g graylimit]
ZASTOSOWANIE: haft [-n numcolours] [-p wzór] [-t grubość] [-g graylimit]
[-f fuzzval ] [-b bgcolor] [-a kąt] [-r zakres] [-i intensywność] [-e zakres]
[-f fuzzval] [-b bgcolor] [-a kąt] [-r zakres] [-i intensywność ] [-e zakres]

To tylko pierwsze wiersze, ale robi to dla każdej linii pomocy. Ponadto skrypt nie działa, ponieważ gdy przesyłam obraz w celu przekonwertowania go za pośrednictwem mojej aplikacji, skrypt generuje ogromne pliki (137 Mb) z oryginalnego pliku nawet 1 Mb.

Jestem naprawdę zdezorientowany, co się tutaj dzieje. Czy masz pojęcie, co może być tego przyczyną?

Czy może to być związane z systemem operacyjnym? Czy skrypt może żyć gdzie indziej i nazywać się jednocześnie dwiema wersjami, mimo że uruchamiam go z taką ścieżką lib/embroidery/embroidery.sh?

Aktualizacja: Więc ten problem nie był związany z tym zachowaniem, co zostało dobrze wyjaśnione przez Johna, problem ze skryptem generującym ogromne pliki był jednak spowodowany starą wersją ImageMagick dostępną za pośrednictwem repozytorium CentOS, zaktualizowałem do wersji 7.0.3 i zadziałało jeszcze raz

Geoffrey Hug
źródło
Czy na pewno jest to problem ze skryptem, a nie oprogramowaniem terminalowym? Czy nadal widzisz duplikację, jeśli przekierujesz dane wyjściowe do pliku?
Zoredache,

Odpowiedzi:

3

W twoim skrypcie obserwuję, że komunikat pomocy jest generowany przez:

usage2()
    {
    echo >&2 ""
    echo >&2 "$PROGNAME:" "$@"
    sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' "$PROGDIR/$PROGNAME"
    }

Przyjrzyjmy się uważnie poleceniu sed:

sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' embroidery

Problem polega na tym, że (1) domyślnie seddrukuje wszystko , co pozostało w obszarze wzorów na końcu poleceń, ale (2) polecenie 4,$ppowoduje dodatkowy wydruk. Tak więc każda linia jest drukowana dwukrotnie.

Jednym z rozwiązań jest użycie -nopcji, aby ukryć domyślny wydruk:

sed >&2 -ne '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' embroidery

Ponieważ OSX (BSD) i CentOS (Linux) używają różnych wersji sed, mogą wystąpić pewne problemy ze zgodnością.


Nawiasem mówiąc, ta nieco prostsza komenda sed działa dla mnie:

sed >&2 -ne '/^#####/q; 1,/^####/d; s/^#* *//p' embroidery

Mini przykład

Wyodrębniając tylko niektóre kluczowe linie, skrypt wygląda mniej więcej tak:

$ cat testfile
#!/bin/bash
#
# misc info 1
# misc info 2
#
####
#
# USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
# [-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
# [-N newseed] [-M mix] infile outfile
######
#
usage2()
        {
        sed >&2 -e '1,/^####/d;  /^######/g;  /^#/!q;  s/^#*//;  s/^ //;  4,$p' "$0"
        }

if [ $# -eq 0 ]
then
        # help information
        usage2
        exit 0
fi

Jeśli uruchomimy ten skrypt, wynik wygląda następująco:

$ ./testfile 


USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-N newseed] [-M mix] infile outfile
[-N newseed] [-M mix] infile outfile

Zamieńmy powyższe polecenie sed na:

    sed >&2 -ne '/^#####/q; 1,/^####/d; s/^#* *//p' "$0"

Teraz wynik wygląda następująco:

$ ./testfile2

USAGE: embroidery [-n numcolors ] [-p pattern] [-t thickness] [-g graylimit]
[-f fuzzval] [-b bgcolor] [-a angle] [-r range] [-i intensity] [-e extent]
[-N newseed] [-M mix] infile outfile
John1024
źródło
Dzięki, to daje nieco więcej światła na ten temat. Jednak moim prawdziwym problemem jest to, że skrypt jest bezużyteczny, ponieważ tworzy bardzo duże pliki. Początkowo myślałem, że każda linia została wywołana dwa razy, co generuje ogromne pliki, ale to mówi mi, że tak nie jest. Czy widzisz coś w tym skrypcie, które może mieć inne zachowanie w CentOS w części generowania obrazu? Może coś wokół kolorów (myślę, że to byłby główny czynnik)
Geoffrey Hug
@GeoffreyHug Glad to pomogło. Wydaje mi się, że problem z generowaniem obrazu jest osobny i niezwiązany. Liczę ponad 20 wywołań convertw skrypcie. Nie wiedząc, jakich plików używasz i jakie opcje ustawiłeś, nie mogę zgadnąć, które wywołanie powoduje tworzenie zbyt dużych plików.
John1024,
@GeoffreyHug Możesz uruchomić bash -x embroidery arg1 arg2 ..., aby zobaczyć, co faktycznie zostanie wykonane, a następnie zobaczyć, która jest pierwszą instrukcją, która produkuje pliki zbyt duże. Na marginesie, istnieje wiele nienotowane zmienne powłoki, które zostaną poddane globbing i podziałowi na słowa i które mogłyby być potencjalnym źródłem problemów, jeśli któryś z nazwami plików zawierać spacji, szelki ?, *lub inne znaki powłoki aktywne.
John1024,
Ostatecznie przyczyną tego, że skrypt zachowywał się inaczej, była po prostu wersja ImageMagick. Miałem najnowszy CentOS 7, zaktualizowałem instalację ze źródłem do wersji 7.0.3 i skrypt działał zgodnie z oczekiwaniami.
Geoffrey Hug
@GeoffreyHug Excellent!
John1024