Programowanie > Bash, skrypty powłoki
3 skrypty bash prośba o pomoc
www0_0:
Witam
Zwracam się do was forumowicze z prośbą o pomoc.
Na zaliczenie kolokwium dostałem takie zadanie:
--- Cytuj ---Zadanie za 2 pkt
Utworzyć skrypt archiwum.sh:
1. Zarchiwizuj wszystkie pliki z drzewa katalogu domowego (/home/nazwa-usera), które zostały
zmodyfikowane w ciągu ostatnich 24 godzin.
2. Plik archiwalny ma być spakowany do tar.gz.
3. Skrypt ma sprawdzać czy jakieś pliki się zmieniły. Jeżeli żadnego nie ma to ma wypisać
komunikat, a jeżeli są to zarchiwizować do pliku.
4. Nazwa pliku archiwalnego ma być zadana przez użytkownika jako parametr skryptu.
Zadanie za 2 pkt
Utworzyć skrypt kosz.sh:
1. Wykonujący kopię pliku przed usunięciem (nie używaj w nazwach * i ?).
2. Skrypt pobierze tylko jeden argument w wierszu poleceń. Wypisuje komunikat o błędzie,
jeśli nie podano żadnego argumentu lub więcej niż jeden argument.
3. Utwórzy katalog .kosz w bieżącym katalogu, jeśli nie został jeszcze utworzony.
4. Skopiuje plik wskazany przez pierwszy argument do .kosz.
5. Usunie podany plik w bieżącym katalogu roboczym.
Zadanie za 1 pkt
Opisać skrypt z załączonego listingu.
1. Napisać do czego służy skrypt i podać 3 przykłady jego wywołania
2. Uzupełnić wszystkie puste polecenia echo wpisując odpowiednie komentarze
3. Dodać komentarz opisujący co się dzieje w blokach (warunkowych, pętlach czy funkcjach)
--- Koniec cytatu ---
--- Kod: ---
1 #!/ bin/ bash
2 valid ()
3 {
4 var1 ="$1"; var2 ="$2"; var3 ="$3"
5
6 if [ -z $var1 ] ; then
7 echo " " >&2 ; return 1
8 fi
9
10 if [ "${ var1 %${ var1 #?}} " = "-" ] ; then
11 test ="${ var1 #?} "
12 else
13 test =" $var1 "
14 fi
15
16 result ="$( echo $test | sed ’s /[[: digit :]]//g ’)"
17
18 if [ ! -z $result ] ; then
19 echo " " >&2
20 return 1
21 fi
22
23 if [ ! -z $var2 ] ; then
24 if [ " $var1 " - lt " $var2 " ] ; then
25 echo "" >&2
26 return 1
27 fi
28 fi
29
30 if [ ! -z $var3 ] ; then
31 if [ " $var1 " - gt " $var3 " ] ; then
32 echo " " >&2
33 return 1
34 fi
35 fi
36
37 return 0
38 }
39
40 if valid "$1" "$2" "$3" ; then
41 echo " "
42 fi
--- Koniec kodu ---
I teraz tak po kilku godzinach udało mi się stworzyć w pełni działający skrypt kosz.sh
w skrypcie archiwum.sh udało mi sie opanować rzeczy zaznaczone podkreśleniem, jednak napotkałem pewne problemy dalej.
Spróbowałem skrypt napisać w taki sposób:
--- Kod: ---
#!/bin/bash
# archiwum
a=$1
zmienna=$#
if [ $zmienna = 1 ]
then
if [ -e $a.tar.gz ] ; then #Sprawdzam czy istnieje archiwum z nazwą podaną w parametrze
echo "Archiwum $a.tar.gz istnieje "
mkdir aktualne #tworze katalog aktualne na potrzeby skryptu
find /home/user -type f -mtime -1 -exec mv {} ~/aktualne \; #Wyszukuje pliki w katalogu domowym które w ostatnich 24 godzina były modyfikowane a następnie przenosze je do katologu aktualne
tar -uvf $a.tar.gz aktualne #pakuje katalog aktualne do arhiwum tar.gz o nazwie parametru
find /home/user/aktualne -type f -mtime -1 -exec mv {} ~ \;#Przenosze pliki z powrotem do katalogu domowego
rm -rf aktualne #usuwam katalog aktualne stworzony na potrzeby skryptu.
else
echo "Tworze nowe archiwum o nazwie $a.tar.gz"
mkdir aktualne #tworze katalog aktualne na potrzeby skryptu
find /home/user -type f -mtime -1 -exec mv {} ~/aktualne \; #Wyszukuje pliki w katalogu domowym które w ostatnich 24 godzina były modyfikowane a następnie przenosze je do katologu aktualne
tar -czvf $a.tar.gz aktualne #pakuje katalog aktualne do arhiwum tar.gz o nazwie parametru
find /home/user/aktualne -type f -mtime -1 -exec mv {} ~ \;#Przenosze pliki z powrotem do katalogu domowego
rm -rf aktualne #usuwam katalog aktualne stworzony na potrzeby skryptu.
fi
else
echo "Wywołaj skrypt jeszcze raz podając nazwe archiwum w pierwszym parametrze."
fi
--- Koniec kodu ---
aby zachować parametr z datą i godziną modyfikacji. Niestety sposób ten wywala wiele błędów. Natomiast jak wykonuje kopiowanie plików to tracę parametr daty, gdyż po skopiowaniu to już są zupełnie nowe pliki z datą i godziną w momencie kopiowania.
Myślę teraz aby wykonać to z koncepcji zapisywania wyników polecenia find do pliku, a następnie pakowania plików odczytując je z pliku. ale nie bardzo wiem jak listę wyników z find przesłać do pliku.
No i w tym trzecim zadaniu już wiem że pierwszy if odpowiada za sprawdzanie czy skrypt odpaliłem z pierwszym parametrem.
natomiast pokonały mnie wyrażenia regularne z lini 10,11 i 16 przez to nie bardzo wiem jak jeszcze można odpalić skrypt i co dokładnie ma robić.
obecnie opanowałem go w takim stopniu:
--- Kod: ---
#!/bin/bash
valid()
{
var1="$1"; var2="$2"; var3="$3"
if [ -z $var1 ] ; then #Sprawdzamy czy istnieje pierwszy parametr skryptu
echo "Skrypt wywołany bez parametrów" >&2 ; return 1
fi
if [ "${var1%${var1#?}}" = "-" ] ; then
test="${var1#?}"
else
test="$var1"
fi
result="$(echo $test | sed ’s/[[:digit:]]//g’)"
if [ ! -z $result ] ; then
echo "Odpowiedz po drógim IF " >&2
return 1
fi
if [ ! -z $var2 ] ; then
if [ "$var1" -lt "$var2" ] ; then #Porównanie czy parametr 1 jest mniejszy od paramertu 2
echo "Pierwszy parametr jest mniejszy od drógiego parametru" >&2
return 1
fi
fi
if [ ! -z $var3 ] ; then
if [ "$var1" -gt "$var3" ] ; then # Porównanie czy parametr 1 jest większy od parametru 3
echo " Odpowiedz po czwartm IF" >&2
return 1
fi
fi
return 0
}
if valid "$1" "$2" "$3" ; then
echo "Skrypt zakończył działanie z spełnioną funkcjią valid "
fi
--- Koniec kodu ---
Dziękuje za jakiekolwiek wskazówki które naprowadzą mnie na rozwiązanie moich problemów.
Paweł Kraszewski:
#1/3 Polecenie find z odpowiednimi parametrami plus polecenie wc udzielą potrzebnej odpowiedzi.
#3 Linijki o których piszesz to nie regexpy a podstawianie zmiennych. Może ten tekst coś rozjaśni.
Co do błędów:
* Zainstaluj sobie VSCode (matko, do czego doszło, polecam soft od Microsoftu). W nim zainstaluj metapakiet lizebang.bash-extension-pack . To powinno pomóc przy pisaniu i sprawdzaniu skryptów. Po zainstalowaniu podpowie, jakie dodatkowe pakiety doinstalować do pełnej funkcjonalności. Twój najlepszy przyjaciel to będzie zakładka "problems" pod edytorem.
* Na szybko: w find fragmenty \;#Blabla oraz \; #Blabla są inaczej interpretowane - znajdź różnicę. Poprawny jest drugi zapis.
* Zawsze umieszczaj zmienne w cudzysłowach, zwłaszcza te pochodzące od użytkownika.
1709:
Na linuxie można używać shellcheck. To narzędzie do analizowania skryptów.
" Podpowiada " gdzie można łatwiej znaleźć np. brakującego cudzysłowia lub gdzie go lepiej użyć.
Wiem że to trudne, bo nie zadaje się pytań, jeśli nie zna się problemów.
Ale swoją drogą jeśli jest to możliwe to zadawaj nauczycielowi jak najwięcej pytań, bo to on powinien uczyć.
Bo tak to już jest, że nauczyciel czasami nie informuje że można się go spytać. Uczeń nie pyta.
A potem zamiast następnej lekcji jest godzina wyjaśniania problemów z zadania domowego.
I to nie u każdego, bo niektórzy "szanują" swój czas. Więc potem trzeba sobie radzić samemu z zaległościami w nauce.
Paweł Kraszewski:
--- Cytuj ---Na linuxie można używać shellcheck. To narzędzie do analizowania skryptów.
" Podpowiada " gdzie można łatwiej znaleźć np. brakującego cudzysłowia lub gdzie go lepiej użyć.
--- Koniec cytatu ---
Jednym z pluginów, które instaluje wspomniany przeze mnie metapakiet jest m.in. obsługa shellcheck-a. ;)
www0_0:
Panowie to takie pytanko jeszcze na szybko bo nie mogę pojąć co jest nie tak z tą linią:
--- Kod: ---
result="$(echo $test | sed ’s/[[:digit:]]//g’)"
--- Koniec kodu ---
wywołuje skrypt przez
./skrypt.sh 1k
i spodziewam się że w tej lini sed podmieni mi 1 na pusty znak. Bynajmniej ja to tak rozumiem.
Natomiast po takim wywołaniu dostaje taką odpowiedz:
sed: -e expression #1, char 1: unknown command:
i zupełnie jej nie rozumiem dlaczego ??
Nawigacja
[#] Następna strona
Idź do wersji pełnej