Celem poniższej listy zadań jest zapoznanie się z mechanizmami shella uniksowego takimi jak: zmienne, wyrażenia warunkowe i pętle, operacje na wektorze argumentów. Postaraj się używać tylko programów wymienionych w zadaniu, i konstrukcji shella. W szczególności, postaraj się nie używać programów: grep, sed, awk, tr.

  1. [3p] W pliku tekstowym adresy.txt istnieje wiele adresów email firm świadczących pewne usługi (np. instalacji okien PCV). W pliku tresc.txt wpisana została treść maila zawierającego zapytanie ofertowe do takiej firmy. W plikach spec*.pdf mamy szereg dokumentów zawierających dokładną specyfikację, rysunki, itp. dotyczące zamawianej usługi. Chcemy automatycznie rozesłać kompletne zapytanie ofertowe (treść+załączniki) do wszystkich firm.

    Znajdź program klienta poczty elektronicznej pozwalającego wysyłać maile z wiersza poleceń w trybie nieinterakcyjnym (np. mail/mailx, pine/alpine, mutt, itp). Przeczytaj jego opis i opracuj wyrażenie shella pozwalającego automatycznie rozesłać zapytanie ofertowe do wszystkich adresów w pliku.

    Dołącz opracowany skrypt do raportu z zadania.

    Ważne: emaile muszą być rozesłane indywidualnie do wszystkich adresatów. Niedopuszczalne jest wysłanie jednego emaila do listy zawierającej wszystkie adresy.

    Wskazówka: istotą tego zadania nie jest wysyłanie emaili, ale czytanie w pętli kolejnych wierszy z pliku. Najprościej to wykonać ustawiając dla polecenia pętli while skierowanie wejścia stdin z pliku, dzięki czemu w kolejnych przebiegach pętli czytanie z pliku/stdin będzie kontynuowane.

  2. [3p] Napisz skrypt myls opakowujący wywołanie programu ls w taki sposób, żeby można mu było zadać nazwę pliku bez końcówki, np. można było pisać `myls main' zamiast `ls main.c'. Skrypt powinien najpierw sprawdzić, czy istnieje plik dokładnie o podanej nazwie, i jeśli tak, to wywołać program ls bezpośrednio z tą nazwą.

    Gdyby plik nie istniał, skrypt powinien próbować uzupełnić jego nazwę kolejno o końcówki z predefiniowanej listy EXTENSIONS=".c .java .html", i jeśli któraś dopasuje się do istniejącego pliku, wywołać ls z odpowiednio uzupełnioną nazwą.

    W żadnym przypadku nie należy wywoływać ls z nazwą nieistniejącego pliku. Jeśli dla danej nazwy nie został znaleziony żaden plik, to należy wyświetlić komunikat informacyjny (na stderr).

    Dołącz opracowany skrypt do raportu z zadania.

  3. [3p] Napisz skrypt, przetwarzający dowolnie długą listę argumentów, traktowanych jako nazwy plików (z bezwzględną lub względną ścieżką katalogów), w następujący sposób. Dla pierwszego argumentu program powinien wyświetlić dwa słowa: nazwę katalogu i nazwę pliku bez ścieżki katalogów (użyj programów dirname i basename). Dla kolejnych plików, o ile ich ścieżka katalogów jest identyczna do poprzedniego pliku, skrypt wyświetla w tym samym wierszu tylko nazwę pliku bez ścieżki, a jeśli ścieżka się różni od poprzedniego pliku, to od nowego wiersza wyświetla znów ścieżkę katalogów oraz nazwę pliku. Na przykład, dla wektora argumentów:
    *.c /etc/passwd /etc/shadow
    
    powinniśmy otrzymać wynik podobny do następującego:
    . fun1.c fun2.c main.c
    /etc passwd shadow
    

    Dołącz opracowany skrypt do raportu z zadania.

  4. [3p] W tym zadaniu należy zbudować skrypt nieco podobny w działaniu do uniksowego programu make. Najpierw wybierz dowolny program „kompilacji” pliku źródłowego do wynikowego. Na przykład, javac tworzy plik .class ze źródłowego .java, cc -c tworzy plik wynikowy .o ze źródłowego .c, albo, dla odmiany, pdflatex tworzy wynikowy .pdf ze źródłowego .tex.

    Następnie napisz skrypt, który otrzymawszy jako argument nazwę pliku wynikowego, rozpocznie powtarzalnie, w nieskończonej pętli, obserwację odpowiedniego pliku źródłowego, i ilekroć okaże się, że plik źródłowy został wygenerowany później, wykona kompilację. Pętla powinna zawierać małe, np. 1-sekundowe opóźnienie, aby nie obciążać zbytnio systemu gdy nic się nie dzieje. Do porównania plików wykorzystaj opcję -nt/-ot programu test.

    Efekt powinien być taki, że po uruchomieniu skryptu w terminalu, wystarczy w edytorze okresowo zapisać nową wersję pliku źródłowego, by kompilacja została przeprowadzona automatycznie z niewielkim opóźnieniem.

    Dołącz opracowany skrypt do raportu z zadania.

    Uwaga: jeśli spodoba Ci się to narzędzie i chciałbyś/chciałabyś używać go w praktyce, to warto poszukać na komputerze programu generującego krótkie sygnały dźwiękowe, i dodać na zakończenie kompilacji dźwiękowe potwierdzenie wyniku. Np. krótki cichy dźwięk jeśli kompilacja była poprawna, i głośniejszy, ostry dźwięk, gdy wygenerowała błędy. Wtedy uruchomiony skrypt kompilacji można zminimalizować, by działał w tle i nie zajmował miejsca na ekranie. W braku innych dźwięków, można wykorzystać „dzwonek” terminala tekstowego (tput bel) dla potwierdzenia, i np. potrójny dzwonek w przypadku błędu kompilacji.