uni

University stuff
git clone git://git.christosmarg.xyz/uni-assignments.git
Log | Files | Refs | README | LICENSE

commit 7a5653aded5380a4b75c94b7140d30d3a9eaaae6
parent 71fe6d09c17d127d2943c4ae67bc31b34999c59f
Author: Christos Margiolis <christos@margiolis.net>
Date:   Thu, 26 Nov 2020 15:56:51 +0200

new assignments

Diffstat:
Dc-parallel-computing/ex1/Makefile | 0
Mc-parallel-computing/ex1/doc.pdf | 0
Mc-parallel-computing/ex1/doc.tex | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Mc-parallel-computing/ex1/ex1.c | 16+++++++++-------
Ac-parallel-computing/ex1/res/exmpl1.png | 0
Ac-parallel-computing/ex1/res/exmpl2.png | 0
Ac-parallel-computing/ex1/res/exmpl3.png | 0
Ac-parallel-computing/ex1/res/exmpl4.png | 0
Dsh-os1/ex1.txt | 658-------------------------------------------------------------------------------
Ash-os1/ex1/ex1.txt | 709+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ash-os1/ex2/searching | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Ash-os1/ex2/teldb | 86+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 files changed, 989 insertions(+), 668 deletions(-)

diff --git a/c-parallel-computing/ex1/Makefile b/c-parallel-computing/ex1/Makefile diff --git a/c-parallel-computing/ex1/doc.pdf b/c-parallel-computing/ex1/doc.pdf Binary files differ. diff --git a/c-parallel-computing/ex1/doc.tex b/c-parallel-computing/ex1/doc.tex @@ -7,6 +7,14 @@ \usepackage{mathtools} \usepackage{xcolor} \usepackage{biblatex} +\usepackage[left=2cm,right=2cm]{geometry} + +\lstset { + basicstyle=\ttfamily, + columns=fullflexible, + breaklines=true, + keepspaces=true +} \title{Εργαστήριο Παράλληλου Υπολογισμού - Εργασία 1} \author{Χρήστος Μαργιώλης} @@ -18,9 +26,126 @@ \maketitle \end{titlepage} -%\renewcommand{\contentsname}{Περιεχόμενα} -%\tableofcontents +\renewcommand{\contentsname}{Περιεχόμενα} +\tableofcontents + +\section{Τεκμηρίωση} +Το πρόγραμμα εν ολίγοις έχει την εξής επαναληπτική δομή: +\begin{itemize} + \item Διαβάζονται στον επεξεργαστή 0 τα δεδομένα από τον χρήστη + \item Διαμοιράζει στους υπόλοιπους επεξεργαστές τα δεδομένα που δώθηκαν + \item Γίνονται οι κατάλληλες συγκρίσεις και έλεγχοι + \item Ο επεξεργαστής 0 συλλέγει όλα τα αποτελέσματα και εμφανίζει + αν ο πίνακας εν τέλει είναι ταξινομημένος ή όχι, και αν όχι, σε + ποιο στοιχείο χάλασε η ταξινόμηση + \item Εμφανίζει ένα μενού επιλογών ώστε να συνεχίσει ή να τερματιστεί το + πρόγραμμα +\end{itemize} + +Είναι σημαντικό να εξηγηθεί το πώς ισοκατανέμεται ο υπολογιστικός φόρτος σε όλους +τους $p$ επεξεργατές. Αφού διαβαστεί το $N$, δηλαδή το πόσα στοιχεία +έχει η ακολουθία $T$, το διαιρούμε δια όσους επεργαστές έχουμε. Αρχικά, ας +υποθέσουμε ότι το $N$ ειναι ακέραιο πολλαπλάσιο του $p$, και ότι +έχουμε - αν το $N$ για παράδειγμα είναι 10 και οι επεξεργαστές 2, τότε +$N / p = 10 / 2 = 5$ στοιχεία από τον συνολικό πίνακα για κάθε επεξεργαστή. + +Πρέπει όμως να καλύψουμε και την περίπτωση που το $N$ δεν είναι ακέραιο πολλαπλάσιο του +$p$, για παράδειγμα $N = 7$ και $p = 2$. Στην περίπτωση αυτή θα πάρουμε το αποτέλεσμα +της πράξης $N \mod p$ η οποία θα μάς δώσει τον αριθμό των περισσευούμενων στοιχείων που +πρέπει να κατανεμηθούν. + +Όταν ξεκινάει το loop για την διαμοίραση του υπολογιστικού φόρτου, πρέπει κάθε φορά +να υπολογίζουμε το μέγεθος του buffer που θέλουμε να σταλεί στον εκάστοτε επεξεργαστή. +Έπειτα υπολογίζουμε το offset - δηλαδή από ποιά θέση του αρχικού πίνακα και μετά - θα +στείλουμε, παίρνοντας πάντα υπόψη τα τυχόν περισσευούμενα στοιχεία (αν υπάρχουν). Αν τύχει +και υπάρχουν περισσευούμενα, κάποιοι επεργαστές θα παραπάνω στοιχεία μέχρι να έχει +καλυφθεί ο αριθμός τον περισσευούμενων στοιχείων. Πρέπει να τονιστεί ότι έχω φροντίσει +οι επεξεργατές να έχουν διαφορά εώς ενα στοιχείο όσο αφορά την διαμοίραση, δηλαδή +αν υποτοθεί ότι $N = 5$ και $p = 2$ πρέπει να αποφύγουμε για παράδειγμα το να έχει +ο $p_0$ 4 στοιχεία και ο $p_1$ 1 στοιχείο - θέλουμε ο $p_0$ να έχει 3 στοιχεία +και ο $p_1$ 2. + +Αφού υπολογίσουμε το offset, βρίσκουμε ποιό είναι το τελευταίο στοιχείο του +προηγούμενου επεξεργαστή ώστε να μπορούμε να το συγκρίνουμε με το πρώτο στοιχείο +του επόμενου. Για να γίνει κατανοητό το γιατί χρειάζομαστε αυτόν τον επιπλέον έλεγχο, +ας υποθέσουε ότι έχουμε την ακολουθία +\[1, 2, 6, 3, 4, 5, 1, 2, 4, 1, 2, 3\] + +Για $p = 4$ αυτή η ακολουθία θα μοιραστεί ως εξής +\[p_0 = 1, 2, 6\] +\[p_1 = 3, 4, 5\] +\[p_2 = 1, 2, 4\] +\[p_3 = 1, 2, 3\] + +Στην περίπτωση που δεν πάρουμε υπόψη το τελευταίο στοιχείο του προηγούμενου +επεξεργαστή, βλέπουμε ότι όλοι οι επεξεργαστές θα μάς επιστρέψουν πως οι υπο-ακολουθίες +τους είναι ταξινομημένες, ενώ στον γενικό πίνακα, προφανώς, δεν είναι. Όμως, με τον +τρόπο που προανέφερα, μπορούμε να είμαστε σίγουροι ότι ο κάθε επεξεργαστής έχει +εις γνώσην του τί υπάρχει πριν από αυτόν, και χρειάζεται να γνωρίζει μόνο το τελευταίο +στοιχείο του προηγούμενού του, εφόσον μονο στις θέσεις $p_n[end]$ με $p_{n+1}[0]$ μπορεί να +υπάρξει λάθος ταξινόμηση και να μην το κατάλαβει το πρόγραμμα. + +Αφού ο επεξεργαστής 0 στείλει στους υπόλοιπους επεξεργαστές τα κατάλληλα δεδομένα, +θα ξεκινήσουν από όλους τους $p$ επεξεργαστές οι συγκρίσεις ώστε να δούμε +αν η κάθε ακολουθία ήτανε ταξινομημένη. Η μία περίπτωση στην οποία η ακολουθία δεν θα +είναι ταξινομημένη είναι να ισχύει η συνθήκη $T_i > T_{i+1}$. Η άλλη περίπτωση +είναι να ισχύει ότι $T_i < prev$, δηλαδή το τελευταίο στοιχείο του προηγούμενου +επεξεργαστή να είναι μεγαλύτερο από το τρέχον στοιχείο στην ακολουθία. +Σημείωση ότι αυτή η περίπτωση ελέγχεται μόνο στην περίπτωση που \textit{δεν} είμαστε +στον επεξεργαστή 0, εφόσον αυτός δεν έχει κάποιον προηγούμενο επεξεργαστή. + +Τα αποτελέσματα συλλέγονται όλα στον επεξεργαστή 0, ο οποίος έχει μερικές επιπλέον +μεταβλητές που θα καθορίσουν τα τελικά αποτελέσματα. Η πιο σημαντική είναι η +\lstinline{f_sorted} - αυτή η μεταβλητή θα μάς πει στο τέλος αν ο γενικός πίνακας ήτανε +ταξινομημένoς. Για να υπολογιστεί κάτι τέτοιο, ενώνουμε με AND όλες τις \lstinline{sorted} +flags που προέκυψαν από τις συγκρίσεις προηγούμενως. Ο λόγος που επέλεξα την πράξη +AND είναι γιατί αν έστω και μία από τις \lstinline{sorted} έτυχε να είναι 0, τότε και +η \lstinline{f_sorted} θα γίνει 0, ασχέτως του αν όλες οι άλλες \lstinline{sorted} ήτανε +1 ή όχι. + +Τέλος, αφού βρεθεί αν ο πίνακας είναι τελικά ταξινομημένoς ή όχι, ο επεξεργαστής 0 +θα τυπώσει ένα κατάλληλο μήνυμα. Αν ο πίνακας δεν είναι ταξινομημένος, θα τυπώσει +και ποιο είναι το πρώτο στοχείο που χάλασε την ταξινόμηση. Έπειτα θα εμφανιστεί το +μενού επιλογών. + +\section{Κώδικας} +\lstinputlisting[language=C]{ex1.c} + +\section{Προβλήματα} +Επειδή έκανα την ανάπτυξη του κώδικα κατά βάση σε FreeBSD, αλλά έκανα και tests +σε Arch Linux, παρατήρησα ότι στα Linux υπάρχει πιθανότητα η \lstinline{printf()} +να μην βγάζει output, ή αν βγάζει, να μην εμφανίζεται με την σωστή σειρά, ή ακόμα +και να κρεμάει όλο το πρόγραμμα. Σε διάφορες αναζητήσεις είδα ότι αρκετοί πρότειναν +την συνάρτηση \lstinline{fflush(stdout)} αλλά δεν είχα ιδιαίτερη τύχη με αυτή. +Αυτό που δούλεψε ήτανε να βάλω \lstinline{getchar()} όπου έβλεπα ότι χρειαζόταν, +και να προσθέσω newlines σε όλες τις \lstinline{printf()} που κανονικά δεν είχανε. + +Ένα άλλο πρόβλημα που αντιμετώπισα ήτανε ότι όταν πρωτοέφτιαξα το menu επιλογών, δεν +έστελνα στους υπόλοιπους επεξεργαστές την επιλογή που έδινα στον επεξεργαστή 0, +το οποίο σήμαινε ότι οι υπόλοιποι επεξεργατές δεν ήξεραν τί είχα όντως απαντήσει, +οπότε μπορεί να εκτελούσαν και αυτοί το μενού, και γενικώς υπήρχε περίεργη +συμπεριφορά. Το διόρθωσα αυτό βάζοντας ένα απλό \lstinline{MPI_Send()} και +\lstinline{MPI_Recv()} αφού δώσω την επιλογή στον επεξεργαστή 0, ωστέ όλοι οι +υπόλοιποι να γνωρίζουν ότι δώθηκε απάντηση, καθώς και ποια ήτανε αυτή. + +Δεν κατάφερα να βρω έναν καλό τρόπο ώστε να μπορώ να υπολογίσω την θέση του +στοιχείου που χαλάει την ταξινόμηση στον γενικό πίνακα. Δηλαδή, για παράδειγμα +αν τύχαινε στον επεξεργαστή 2 να χαλάσει το στοιχείο 1, θα έπρεπε να υπολογίσω +γενικώς στον συνολικό πίνακα ποια θέση έχει αυτό το στοιχείο. Οπότε, αντ'αυτού +έβαλα να εμφανίζεται η τιμή του στοιχείου που χαλάει την ταξινόμηση, και όχι την +θέση του. Βέβαια, κάτι τέτοιο γνωρίζω ότι δεν έχει ιδιαίτερο νόημα. + +\section{Ενδεικτικά τρεξίματα} +Τα παρακάτω τρεξίματα έγιναν σε Arch Linux, εξ'ού και τα newlines που ανέφερα +στα προβλήματα και χαλάνε την εμφάνιση του πρόγραμματος. + +\includegraphics[width=\textwidth]{exmpl1.png} +\includegraphics[width=\textwidth]{exmpl2.png} +\includegraphics[width=\textwidth]{exmpl3.png} -Hello world +\includegraphics[width=\textwidth]{exmpl4.png} +Σε αυτό το τρέξιμο έδωσα την λίστα που έφερα ως παράδειγμα πιο πάνω +και ανέφερα ότι αν δεν ο κάθε επεξεργαστής δεν ξέρει ποιο είναι το προηγούμενο από +αυτόν στοιχείο, δεν μπορούμε να έχουμε σωστό αποτέλεσμα. \end{document} diff --git a/c-parallel-computing/ex1/ex1.c b/c-parallel-computing/ex1/ex1.c @@ -18,9 +18,9 @@ main(int argc, char *argv[]) int nproc, rank, rc; int *t, n, prev; int bufsize, offset, remaining; - int val, sorted; /* results from each process */ - int f_val, f_sorted; /* final results */ - int found = 0; /* indicates that the first unsorted element has been found */ + int val, sorted; /* results from each process */ + int f_val, f_sorted; /* final results */ + int found = 0; /* indicates that the first unsorted element has been found */ int i, ch = 1; /* just in case an error occurs during initialization */ @@ -36,7 +36,7 @@ main(int argc, char *argv[]) /* main loop */ while (ch != 2) { if (rank == 0) { - printf("Enter N: "); + printf("Enter N: \n"); scanf("%d", &n); getchar(); @@ -44,7 +44,7 @@ main(int argc, char *argv[]) /* read whole array */ for (i = 0; i < n; i++) { - printf("t[%d]: ", i); + printf("t[%d]: \n", i); scanf("%d", &t[i]); } getchar(); @@ -123,6 +123,8 @@ main(int argc, char *argv[]) /* collect results from proc 0 first */ f_sorted = sorted; f_val = val; + /* if f_sorted is false already, don't bother searching below */ + found = f_sorted == 0; /* receive results from the rest */ for (i = 1; i < nproc; i++) { @@ -147,7 +149,7 @@ main(int argc, char *argv[]) if (f_sorted) puts("Array is sorted."); else - printf("Array is not sorted (val: %d)\n", f_val); + printf("Array is not sorted: first unsorted element: %d\n", f_val); puts("Press [ENTER] to continue. . ."); getchar(); @@ -160,7 +162,7 @@ main(int argc, char *argv[]) /* menu */ if (rank == 0) { system("clear || cls"); - printf("1. Continue\n2. Exit\nYour choice: "); + printf("1. Continue\n2. Exit\nYour choice: \n\n"); scanf("%d", &ch); /* everyone has to know what the choice is */ for (i = 1; i < nproc; i++) diff --git a/c-parallel-computing/ex1/res/exmpl1.png b/c-parallel-computing/ex1/res/exmpl1.png Binary files differ. diff --git a/c-parallel-computing/ex1/res/exmpl2.png b/c-parallel-computing/ex1/res/exmpl2.png Binary files differ. diff --git a/c-parallel-computing/ex1/res/exmpl3.png b/c-parallel-computing/ex1/res/exmpl3.png Binary files differ. diff --git a/c-parallel-computing/ex1/res/exmpl4.png b/c-parallel-computing/ex1/res/exmpl4.png Binary files differ. diff --git a/sh-os1/ex1.txt b/sh-os1/ex1.txt @@ -1,658 +0,0 @@ -Eργαστήριο ΛΣ 1 / Άσκηση 1 / 2020-21 -Ονοματεπώνυμο: Χρήστος Μαργιώλης -ΑΜ: [REDACTED] -==================================== - -Ερώτηση 1: ----------- -Δημιουργήστε στον τρέχοντα κατάλογο το αρχείο 'ask1.txt' με τα ακόλουθα -περιεχόμενα(όνομα, επώνυμο, username, ΤΚ, περιοχή, τηλ.), και εμφανίστε -το στησυνέχεια στην οθόνη, με αριθμημένες τις γραμμές του. - -Απάντηση: -Προκειμένου να δημιουργήσουμε ένα αρχείο χρησιμοποιούμε την εντολή 'touch [FILE...]', -όπου FILE είναι το όνομα του αρχείου και ... ότι μπορούμε να δώσουμε όσα ορίσματα -θελουμε. Στην προκειμένη περίπτωση - - touch ask1.txt - -Έπειτα με τον κειμενογράφο μας θα γράψουμε τα πεδία που δίνονται στην -εκφώνση. Για να εμφανίσουμε τα περιεχόμενα του αρχείου με αριθμημένες σειρές, -θα χρησιμοποιηθεί η εντολή 'nl', η οποία αριθμεί σειρές, δέχοντας ως -input το αρχείο με τα περιεχόμενα. - - nl ask1.txt - -Αποτέλεσμα εκτέλεσης εντολής: - - 1 George Pappas george2 12136 Peristeri------- - 2 Nick Nikolaoy nick23 12232 Aigaleo 5314555 - 3 George Georgioy george583 11132 Athens------- - 4 Helen Georgioy helen3 12136 Peristeri 5748456 - 5 Nick Pappas nick4 11223 Aigaleo 5324123 - 6 Helen Ioannoy helen367 13222 Athens ------- - 7 Helen Thanoy helen36 11132 Peristeri9718345 - 8 Vasilis Mamalis vas32 12345 Dafni 9738383 - -Ερώτηση 2: ----------- -Τρέξτε την εντολή cal -3 > calfile.txt και εξηγείστε τι ακριβώς κάνει. - -Απάντηση: -Η εντολή 'cal' αρχικά εμφανίζει ημερολόγιο του τρέχοντος μήνα. Με την -εντολή - - cal -3 > calfile.txt - -Θα εμφανιστεί ο προηγούμενος, τρέχων και επόμενος μήνας, και στην συνέχεια -το output της εντολής θα γραφτεί στο αρχείο calfile.txt - -Ερώτηση 3: ----------- -Συνενώστε τα αρχεία calfile.txt και ask1.txt σε ένα αρχείο με όνομα full.txt - -Απάντηση: -Για την συνένωση των δύο παραπάνω αρχείων - και γενικότερα δύο ή παραπάνω -αρχειών - χρησιμοποιούμε την εντολή 'cat', οπότε - - cat calfile.txt ask1.txt > full.txt - -Ερώτηση 4: ----------- -Εμφανίστε στην οθόνη τα πέντε πιο πρόσφατα τροποποιημένα αρχεία του καταλόγου σας. - -Απάντηση: -Για να εμφανίσουμε τα αρχεία του καταλόγου χρησιμοποιούμε την εντολή 'ls'. -Προκειμένου να εμφανιστούν κατά ημερομηνία τροποποίησης ενεργοποιούμε την -επιλογή -t. Έπειτα θα κάνουμε pipe το output του 'ls' στην εντολή 'head' για να -εμφανίσουμε μόνο τα 5 πρώτα αρχεία. - - ls -t | head -6 - -Ερώτηση 5: ----------- -Δημιουργήστε έναν κατάλογο με όνομα 'mydir1'. Μεταβείτε σε αυτόν και στη -συνέχεια αντιγράψτε εκεί (χωρίς να αλλάξετε κατάλογο) το αρχείο 'full.txt' -(από το γονικό κατάλογο). Μετονομάστε το εν συνεχεία σε 'new.txt'. -Επιστρέψτε στο γονικό κατάλογο. Διαγράψτε τον κατάλογο 'mydir1' και τα -περιεχόμενά του. - -Απάντηση: -Οι εντολές που θα χρειαστούμε είναι οι εξής: -mkdir: Δημιουργεί κατάλογο -cd: Αλλάζει κατάλογο -cp: Αντιγράφει αρχεία και καταλόγους -rm -rf: Διαγράφει αναδρομικά έναν κατάλογο (εφόσον υπάρχει το -rf) - - mkdir mydir1 && cd mydir1 - cp ../full.txt . - cd .. - rm -rf mydir1 - -Ερώτηση 6: ----------- -Δώστε τις εντολές που θα εμφανίσουν: -(α) όλα τα αρχεία του καταλόγου /usr με πληροφορίες για το inode τους και -το μέγεθος τους σε blocks. -(β) όλα τα περιεχόμενα του δέντρου καταλόγων και υποκαταλόγων (αναδρομικά) -που βρίσκονται κάτω από τον κατάλογο /usr, με πλήρεις πληροφορίες για -κάθε ένα από αυτά και εμφανιζόμενα σταδιακά, σελίδα προς σελίδα. - -Απάντηση: -Και στα δύο υποερωτήματα θα χρησιμοποιηθεί η εντολή 'ls' -(α) Η επιλογή -i εμφανίζει το inode και η επιλογή --s το μέγεθος σε blocks, οπότε - - ls -lsi /usr - -(β) Η επιλογή -R εμφανίζει αναδρομικά όλα τα περιεχόμενα ενός -καταλόγου, οπότε - - ls -lR /usr - -Ερώτηση 7: ----------- -Δημιουργήστε έναν κατάλογο με όνομα 'testdir1'. Μεταβείτε σε αυτόν -και φτιάξτε εκεί ένα hard link (με το όνομα 'ask1link') προς το αρχείο -'ask1.txt' του γονικού καταλόγου. Βεβαιωθείτε (δίνοντας την κατάλληλη -εντολή και εξηγώντας τι βλέπετε) ότι έχει δημιουργηθεί και ότι δεν είναι -symbolic (soft) link. - -Απάντηση: -Για να φτιάξουμε hard link θα χρησιμοποιήσουμε την εντολή 'ln'. - - mkdir testdir1 && cd testdir1 - ln ../ask1.txt ask1link - -Αν εκτελέσουμε την εντολή 'ls -li' στον κατάλογο testdir1 θα δούμε -ότι σε αντίθεση με το soft link, στο hard link δεν εμφανίζεται -το -> το οποίο δηλώνει ότι είναι symbolic link. Επίσης -παρατηρούμε ότι και το ask1link αλλά και το ask1.txt έχουν το ίδιο -inode. - -Ερώτηση 8: ----------- -Μπείτε στο αρχείο 'ask1link' και διαγράψτε την τελευταία του γραμμή. -Βεβαιωθείτε στη συνέχεια ότι η αλλαγή αυτή έχει γίνει και στο αρχείο 'ask1.txt'. - -Απάντηση: -Εφόσον το ask1link ειναι hardlink στο ask1.txt, δηλαδή είναι reference -στο ask1.txt, ό,τι αλλαγή γίνει στο ένα αρχείο, θα γίνει και στο άλλο, -οπότε αν διαγράψουμε την τελευταία γραμμή από το ask1link, η αλλαγή -πράγματι θα έχει γίνει και στο ask1.txt. - -Ερώτηση 9: ----------- -Δημιουργήστε ένα κατάλογο kat1 και μέσα σε αυτόν δύο αρχεία, file1 και file2, -με περιεχόμενο τη λέξη 'one' το ένα και τη λέξη 'two' το άλλο. -Τρέξτε (μέσα στον κατάλογο kat1) την εντολή 'cp *' και εξηγήστε το αποτέλεσμα. -Στη συνέχεια τρέξτε την εντολή 'mv *' και εξηγήστε το αποτέλεσμα. - -Απάντηση: -Αφού τρέξουμε την εντολή 'cp *' στον kat1 θα παρατηρήσουμε ότι και τα -δύο αρχεία τώρα έχουν την λέξη "one". Αυτό γίνεται επειδή γράφοντας -'cp *', επιλέγουμε όλα τα αρχεία του καταλόγου. Επειδή όμως έχουμε δύο -αρχεία η εντολή θα αναπτυχθεί σε - - cp file1 file2 - -και αυτό που θα γίνει τελικά είναι να αντιγραφεί το file1 στο file2. -Όταν τρέξουμε την εντολή 'mv *' θα δούμε ότι διαγράφεται το file1, -επειδή, όπως και με την 'cp *', η εντολή θα αναπτυχθεί σε - - mv file1 file2 - -οπότε το file1 θα μετονομαστεί σε file2, και έτσι θα χαθεί. - -Ερώτηση 10: ------------ -Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες τελειώνουν -με ένα ή περισσότερα συνεχόμενα ψηφία. - -Απάντηση: -Η εντολή 'grep' δέχεται ένα regular expression (regex) και επιστρέφει -τις γραμμές στο αρχείο στις οποίες βρίσκεται το regex. -Το regex που θα ψάξουμε θα αποτελείται από τα εξής μέρη: - -1. [0-9] - οποιδήποτε ψηφίο από το 0 εώς το 9 -2. \+ - μία ή παραπάνω επαναλήψεις του προηγούμενου -3. $ - τέλος γραμμής - -Οπότε η τελική εντολή θα είναι - - grep "[0-9]\+$" ask1.txt - -Ερώτηση 11: ------------ -Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες περιέχουν μεν -το πρότυπο 'Pap' αλλά δεν περιέχουν το πρότυπο 'Aig'. - -Απάντηση: -Στην εντολή 'grep' η επιλογή -v αποκλείει το δοθέν regex. Προκειμένου -πρώτα να πάρουμε τις γραμμές που περιέχουν το πρότυπο 'Pap' αλλα όχι -το πρότυπο 'Aig', θα εκτελέσουμε το 'grep' 2 φορές, ώστε πρώτα να πάρουμε -όλες τις γραμμές που περιέχουν το 'Pap' και μετά να αποκλείσουμε το 'Aig'. - - grep 'Pap' ask1.txt | grep -v 'Aig' - -Ερώτηση 12: ------------ -Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες δεν αρχίζουν -με 'G' ή 'N' και περιέχουν εν συνεχεία (κάπου στα περιεχόμενά τους) -τα πρότυπα 'Geo' και 'Per' με αυτή τη σειρά.' - -Aπάντηση: -Όπως και στην ερώτηση 11, θα μπορούσαμε να χρησιμοποιήσουμε την επιλογή --v για την εντολή 'grep', αλλα θα χρησιμοποιήσουμε μία διαφορετική σύνταξη. -Αυτή τη φορά τα regex που θα ψάξουμε είναι τα εξής - -Για την πρώτη κλήση: -1. ^ - ξεκινάει με -2. ^[GN] - πρεπει να ξεκινάει με G ή N -3. ^[^GN] - ΔΕΝ πρέπει να ξεκινάει με G ή N - -Για την δεύτερη κλήση: -1. Geo - περιέχει την λέξη 'Geo' -2. .* - οποιοσδήποτε αριθμός οποιουδήποτε χαρακτήρα -3. Per - περιέχει την λέξη 'Per' - -Οπότε η τελική εντολή είναι (το | ειναι separator) - - grep "^[^GN]" ask1.txt | grep "Geo.*Per" - -Η παραπάνω κλήση πράγματι θα μάς επιστρέψει την κατάλληλη γραμμή, -η οποία είναι η: - - Helen Georgioy helen3 12136 Peristeri 5748456 - -Ερώτηση 13: ------------ -Πόσοι χρήστες που το username τους δεν αρχίζει από 'ls1' είναι -συνδεδεμένοι στο σύστημα; - -Απάντηση: -Η εντολή 'who' μπορεί να μας επιστρέψει μια λίστα με τους χρήστες -που είναι συνδεδεμένοι. Ο λόγος που χρησιμοποίησα την 'who' αντί -για την 'w' που κάνει περίπου το ίδιο πράγμα είναι επειδή η 'w' -έχει και μια γραμμή header στην αρχή, οπότε 'wc -l' θα την μέτραγε. -Με την χρήση της εντολής 'wc' μπορούμε να μετρήσουμε λέξεις, γραμμές -και χαρακτήρες. Αν στην εντολή 'wc' δώσουμε την επιλογή -l τότε θα -μετρήσει μόνο πόσες γραμμές έχει το input που της δώθηκε. - - who | grep -v "^ls1" | wc -l - -Ερώτηση 14: ------------ -Εμφανίστε όλες τις διεργασίες χρηστών (αλλ/σης) που τρέχουν αυτή -τη στιγμή στο σύστημα. - -Απάντηση: -Η εντολή 'ps' (process status) εμφανίζει τις τρέχουσες διεργασίες που -εκτελεί το σύστημα. Επιπλέον θα χρειαστούμε τις επιλογές a και u, οι οποίες -εμφανίζουν τις διεργασίες που εκτελούνται από όλους τους συνδεδεμένους χρήστες -αυτή τη στιγμη. Στην εντολή 'ps' χρησιμοποιήσα την BSD σύνταξη. - - ps -au - -Αποτέλεσμα εκτέλεσης της εντολής: - - USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND - christos 5200 0.1 0.1 18048 7084 2 Ss 21:44 0:09.04 /usr/local/bin/zsh - christos 1160 0.0 0.1 15072 6016 v0 I 12:19 0:00.07 -zsh (zsh) - christos 1175 0.0 0.0 11828 3044 v0 I+ 12:19 0:00.00 /bin/sh /usr/local/bin/startx - christos 1188 0.0 0.0 13164 3240 v0 I+ 12:19 0:00.00 xinit /home/christos/.xinitrc - christos 1192 0.0 0.1 22152 11360 v0 S 12:19 0:19.69 dwm - christos 1218 0.0 0.1 17136 8000 0- S 12:20 0:16.20 slstatus - christos 5005 0.0 0.1 18004 7000 1 Is 21:15 0:00.31 /usr/local/bin/zsh - christos 5193 0.0 0.2 28028 16288 1 S+ 21:44 0:07.88 nvim ex1.txt - christos 6849 0.0 0.0 11860 3080 2 R+ 00:22 0:00.00 ps -u - root 1158 0.0 0.0 10880 2304 v1 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv1 - root 1159 0.0 0.0 10880 2304 v2 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv2 - root 1160 0.0 0.0 10880 2304 v3 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv3 - -Ερώτηση 15: ------------ -Πόσες διεργασίες χρηστών (αλλ/σης) τρέχουν στο σύστημα και τελειώνει -το όνομά τους με 'sh' ? - -Απάντηση: -Τρέχοντας την εντολή της ερώτησης 14 (ps -ux) και φιλτράροντας -το ouput ώστε να πάρουμε μόνο τις γραμμές που τελειώνουν σε -'sh', έχω 3 διεργασίες που το όνομα τους τελειώνει σε 'sh' - - ps -au | grep "sh$" | wc -l - - Συνολικά έχουμε 3 διεργασίες που τελειώνουν σε sh. - -Ερώτηση 16: ------------ -Εμφανίστε όλες τις διεργασίες χρηστών (αλλ/σης) που τρέχουν αυτή τη στιγμή στο σύστημα. - -Απάντηση: -Αυτή τη φορά στην εντολή 'ps', πέρα από την επιλογή u, θα δώσουμε και την επιλογή -x, η οποία εμφναίζει πληροφορίες ακόμα και για διεργασίες που δεν ελέγχουν κάποιο terminal - - ps -aux - -Το output της εντολής είναι πολύ μεγάλο για να το συμπεριλάβω εδώ. - -Ερώτηση 17: ------------ -Πόσα αρχεία του τρέχοντος καταλόγου σας (μόνο του τρέχοντος -όχι και -των υποκαταλόγων του) έχουν permissions 'rw' από τους πάντες και 'x' -από κανέναν; - -Απάντηση: -Η 'ls -l' στην αρχή κάθε σειράς εμφανίζει το permission string και με την -'grep' μπορούμε να εμφανίσουμε μόνο τις γραμμές που περιέχουν το permission -που ζητάει η εκφώνηση. Τέλος διοχετεύουμε την έξοδο στην 'wc -l'. - - ls -l | grep "^-rw-rw-rw-" | wc -l - -Ερώτηση 18: ------------ -Βρείτε τους καταλόγους του συστήματος που το όνομά τους αρχίζει από 'b'. - -Απάντηση: -Η εντολή 'find' είναι μια πιο ανεπτυγμένη μορφή της 'ls' στην οποία μπορούμε -να δώσουμε πολλές παραπάνω επιλογές. Οι επιλογές που έχουν δωθεί στην παρακάτω εντολή -σημαίνουν τα εξής: -/* - η αναζήτηση ξεκινάει από την ρίζα του συστήματος (root directory) --type d - αναζήτηση μόνο για directories --name "b*" - το όνομα τους πρέπει να ξεκινάει από 'b' - - find /* -type d -name "b*" - -Ερώτηση 19: ------------ -Να βρείτε και να παρουσιάσετε στην οθόνη με πλήρεις πληροφορίες -όλα τα αρχεία με όνομα που αρχίζει από tty και βρίσκονται στον κατάλογο /dev. - -Απάντηση: -Η εντολή stat επιστρέφει πλήρεις πληροφορίες για ένα αρχείο. -Με την εντολή 'grep', όπως έχει ειπωθεί και σε παραπάνω ερωτήσεις, μπορούμε -να πάρουμε τις γραμμές στις οποίες γίνεται match ένα regular -expression - έτσι κατά την εμφάνιση των αρχείων του /dev μπορούμε -να εξάγουμε μόνο όσες γραμμές περιέχουν την λέξη 'tty'. - - stat /dev/* | grep "tty" - -Ερώτηση 20: ------------ -Ταξινομήστε τα περιεχόμενα του αρχείου 'ask1.txt' ως προς το -username σε φθίνουσα σειρά. - -Απάντηση: -Θα ταξινομίσουμε το αρχείο με την χρήση της εντολής 'sort'. -Στην εντολή αυτή μπορούμε να της δώσουμε κατα ποιά στήλη θέλουμε -να ταξινομηθεί το αρχείο με την επιλογή -k. Εφόσον username -βρίσκεται στην 3η στήλη, θα δώσουμε την 3η στήλη ως μέσο -σύγκρισης για ταξινόμηση. Επίσης, προκειμένου να είναι κατα -φθήνουσα σειρά η ταξινόμηση, θα χρησιμοποιήσουμε την επιλογή -r - - sort -rk 3 ask1.txt - -Σε περίπτωση που θέλουμε οι αλλαγές να γραφτούν στο αρχείο, μπορούμε -να γράψουμε την εντολή ως - - sort -rk 3 ask1.txt -o ask1.txt - -Ερώτηση 21: ------------ -Ταξινομήστε τα '.c' αρχεία του καταλόγου στον οποίον δουλεύετε ως -προς το μέγεθός τους. - -Απάντηση: -Στην εντολή 'ls' η επιλογή -S ταξινομεί τα αρχεία ανάλογα με το -μέγεθός του κατα φθήνουσα σειρά (μεγαλύτερο πρώτα), οπότε - - ls -S *.c - -Ερώτηση 22: ------------ -Ταξινομήστε τα αρχεία του λογαριασμού σας με permissions 644 -ως προς το μέγεθός τους. - -Απάντηση: -Μπορούμε να εμφανίσουμε αρχεία που έχουν συγκεκριμένα permissions -με την εντολή 'find' και την επιλογή -perm [PERMISSION] όπου -το PERMISSION πρέπει να δωθεί σε οκταδικό. Επίσης μέσα στην 'find' -μπορούμε να εκτελέσουμε και επιπλέον shell commands στο output της με -την επιλογή -exec [COMMAND] - θα χρησιμοποιήσουμε την 'ls -lS' ώστε -να ταξινομήσει το output κατα μέγεθος. Η τελική εντολή θα εκτελεστεί -στον κατάλογο '/usr/home/christos', ο οποίος είναι ο κατάλογος του λογαριασμού -μου. Το {} \; στο τέλος της εντολής δηλώνει ότι η 'ls -lS' θα εκτελεστεί -σε κάθε αρχείο που βρίσκεται από την 'find'. - - find /usr/home/christos -perm 644 -exec ls -lS {} \; - - -Ερώτηση 23: ------------ -Ταξινομήστε όλα τα περιεχόμενα του καταλόγου /dev κατά πρώτον ως προς -τον owner και κατά δεύτερον ως προς το group και αποθηκεύστε το -output στο αρχείο 'binfiles.txt'. - -Аπάντηση: -Παίρνοντας πληροφορίες για τον owner και το group των αρχείων με την -'ls -l' μπορούμε να ταξινομήσουμε τις κατάλληλες στήλες (3 για owner -και 4 για group). - - ls -l | sort -k 3,4 > binfiles.txt - -Ερώτηση 24: ------------ -Φτιάξτε ένα αρχείο που θα περιέχει πληροφορίες μόνο για τους συνδεδεμένους -χρήστες που το username τους αρχίζει από 'ls1', ταξινομημένο ως προς -την ημερομηνία και ώρα σύνδεσή τους. - -Απάντηση: -ΑΦού φιλτραριστεί το ouput της 'w' ώστε να πάρουμε μόνο τους -χρήστες που το όνομά τους ξεκινάει από ls1, θα ταξινομήσουμε -κατά 2η και 3η στείλει επειδή αυτές δείχνουν την ημερομηνία -και ώρα σύνδεσης. - - w | grep "^ls1" | sort -k 2,3 > userinfo.txt - -Ερώτηση 25: ------------ -Αλλάξτεστο αρχείο 'ask1.txt' το όνομα 'Nick' (όπου συναντάται) σε 'Nickolaos'. - -Απάντηση: -Με την χρήση της εντολής 'sed' (stream editor) μπορούμε να αλλάξουμε ένα -pattern κάθε φορά που συναντάται με την παρακάτω σύνταξη - - sed "s/PATTERN/NEWPATTERN/g" file - -Τo g στο τέλος σημαίνει ότι αυτή η αλλαγή πρέπει να γίνει σε όλο το αρχείο, -και όχι μόνο την πρώτη φορά που θα συναντήσει το PATTERN. -Οπότε, στην προκειμένη περίπτωση η εντολή που θα εκτελεστεί είναι - - sed "s/Nick/Nickolaos/g" ask1.txt - -Εάν θέλουμε οι αλλαγές να αποθηκευτούν στο αρχείο κατευθείαν, μπορούμε -να εκτελέσουμε την εντολή με την επιλογή -i. - - sed -i "s/Nick/Nickolaos/g" ask1.txt - -Ερώτηση 26: ------------ -Έστω τα ακόλουθα items του filesystem με protection strings: -(α) '-rwxr-x--x', -(β) 'drwxr-x---' και -(γ) 'drwx--x--x. -Εξηγείστε τι είδους items είναι και ποια τα δικαιώματα πρόσβασης user, -group και others σε αυτά. - -Απάντηση: -(α) Το είδος item είναι απλό αρχείο εφόσον το πρώτο πεδίο του protection string -είναι κενό. Όσο αφορά τα δικαίωματα του, δικαίωμα εγγραφής έχει μόνο ο ιδιοκτήτης -του αρχείο, διαβάσματος ο ιδιοκτήτης του αρχείου, και όσοι είναι στο ίδιο group με αυτόν. -Επίσης όλοι οι χρήστες μπορούνε να το εκτελέσουν. - -(β) Το είδος είναι directory λόγω του 'd' στο πρώτο πεδίο του string. Δικαίωμα εγγραφής -έχει μόνο ο ιδιοκτήτης, διαβάσματος και εκτέλεσης ο ιδιοκτήτης και τα μέλη του group - -οι υπόλοιποι χρήστες δεν έχουν δικαιώματα για το συγκεκριμένο directory. - -(γ) Το είδος είναι επίσης directory λόγω του 'd' στο πρώτο πεδίο του string. Δικαίωμα -εγγραφής και διαβάσματος έχει μόνο ο ιδιοκτήτης και εκτέλεσης όλοι οι χρήστες. - -Ερώτηση 27: ------------ -Αλλάξτε τα permissions όλων των αρχείων του καταλόγου 'testdir1' -έτσι ώστε να έχουν δικαίωμα εκτέλεσης και εγγραφής μόνο ο ιδιοκτήτης, -ενώ δικαίωμα ανάγνωσης να έχουν όλοι. - -Απάντηση: -Η εντολή 'chmod' μπορεί να αλλάξει permissions. Με την επιλογή 'R' δηλώνουμε -ότι αυτό θέλουμε να γίνει αναδρομικά εφόσον θέλουμε να αλλάξουμε τα permissions -όλων των αρχείων του καταλόγου 'testdir1'. Τα υπόλοιπα πεδία σημαίνουν τα εξής: -u=wx - μόνο ο ιδιοκτήτης του αρχείου έχει δικαίωμα εγγραφής και εκτέλεσης -o=r - οι υπόλοιποι χρήστες έχουν δικαίωμα ανάγνωσης - - chmod -R u=wx,o=r testdir/ - -Ερώτηση 28: ------------ -Αλλάξτε τα permissions του καταλόγου 'testdir1' έτσι ώστε να έχουν δικαίωμα -πρόσβασης μόνοο ιδιοκτήτης και οι χρήστες του ιδίου με αυτόν group, -ενώ οι υπόλοιποι χρήστες να μην έχουν (θεωρείστε ότι τα τρέχοντα -permissions του καταλόγου είναι 755). - -Απάντηση: -Χρησιμοποιώντας πάλι την εντολή 'chmod' μπορούμε να αλλάξουμε και τα permissions -ενός καταλόγου. Τα πεδία τώρα σημαίνουν τα εξής: -ug=r - ο ιδιοκτήτης και τα μέλη του group έχουν δικαίωμα διαβάσματος -o-r - οι υπόλοιποι χρήστες δεν έχουν δικαίωμα διαβάσματος - - chmod ug=r,o-r testdir - -Ερώτηση 29: ------------ -Δημιουργήστε έναν νέο χρήστη στο σύστημά σας με username 'myfriend'. -Αλλάξτε στη συνέχεια τον ιδιοκτήτη του αρχείου 'ask1.txt' σε 'myfriend' και -μετακινήστε το στο working directory του. Περιορίστε τέλος το διαθέσιμο -χώρο αποθήκευσης στο δίσκο για το συγκεκριμένο χρήστη στα 10MB. - -Απάντηση: -Για να φτιάξουμε έναν user χρησιμοποιούμε την εντολή 'useradd'. Σε BSD -συστήματα η εντολή είναι η 'adduser'. Για να αλλάξουμε ιδιοκτήτη αρχείου -χρησιμοποιούμε την εντολή 'chown'. Τέλος, για να περιορίσουμε τον χώρο -αποθηκεύσης στον δίσκο για έναν χρήστη χρησιμοποιούμε την εντολή 'edquota'. - - useradd -m -d /home/myfriend myfriend - chown myfriend ask1.txt - mv ask1.txt /home/myfriend - edquota myfriend - -Η εντολή 'edquota' θα μάς ανοίξει στον default editor μας ένα αρχείο -στο οποίο μπορούμε να τροποποιήσουμε τον αποθηκευτικό χώρο για τον χρήστη -myfriend. Θα πρέπει να δούμε κάτι σαν - - Disk quotas for user ice19390133 (uid 1022): - Filesystem blocks soft hard inodes soft hard - /dev/vda1 36 10240 13312 11 0 0 - -Το 'soft' το θέτουμε σε 10240 (kilobyte), δηλαδή 10MB. - -Ερώτηση 30: ------------ -Έστω τα παρακάτω: -user1@localhost:~$ w -USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT -user1 pts/0 1.2.3.4 03:34 0.00s 0.38s 0.01s w -user2 pts/1 5.6.7.8 03:45 0.00s 0.38s 0.01s ls -user3 pts/2 9.7.5.3 03:57 0.00s 0.38s 0.01s ps - -user1@localhost:~$ ls -al /dev/pts/* -crw--w---- 1 user1 tty136, 0 Oct 25 04:04 /dev/pts/0 -crw--w--w- 1 user2 tty136, 1 Oct 25 04:04 /dev/pts/1 -crw--w--w- 1 user3 tty136, 2 Oct 25 04:04 /dev/pts/2 - -Εξηγήστε τι είδους items του file system είναι τα παραπάνω, -καθώς και τι θα κάνουν οι παρακάτω εντολές: -user1@localhost:~$ cat > /dev/pts/1 -user1@localhost:~$ wall "test" - -Απάντηση: -==================================================================== -==================================================================== -30 -==================================================================== -==================================================================== - -Ερώτηση 31: ------------ -Δημιουργείστε τα αρχεία f1, f2, f3, f4, f5, f6 ,f7 με τα εξής δικαιώματα: -f1, 757 -f2, 313 -f3, 010 -f4, 642 -f5, 551 -f6, 133 -f7, 111 -Με χρήση της εντολής ls –l και διοχετεύοντας τα αποτελέσματά της στην εντολή -egrep να βρείτε τα αρχεία όπου: -a. To group έχει δικαιώματα r-x. -b. Ο user και οι others έχουν ακριβώς τα ίδια δικαιώματα -c. Ο user, το group και οι others έχουν τα ίδια δικαιώματα για write -d. Ο user, το group και οι others έχουν τα ίδια δικαιώματα για write και execute -e. To group και οι others έχουν τα ίδια δικαιώματα για read και execute - -Απάντηση: -a) Το pattern που θα αναζητήσουμε είναι στο permission string να περιέχονται -οποιοιδήποτε χαρακτήρες σε όλα τα πεδία αλλά πρέπει οπωσδήποτε τα permissions -του group να είναι r-x. Το - στην αρχή το βάζουμε για να ψάξουμε μόνο αρχεία και όχι -τυχόν directories. - - ls -l | egrep "^-...r-x..." - -Αποτέλεσμα εκτέλεσης της εντολής: - - -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 - -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 - -b) Θα φτιάξουμε τρία capture groups στα πεδια που βρισκονται τα permissions -του user ώστε να ψάξουμε ό,τι αποθηκεύτηκε στις μεταβλητές 1, 2 και 3 -στο πεδίο που βρίσκονται τα permissions των others. Ένα capture group φτιάχνουμε -βάζοντας () και γράφοντας μέσα τους το pattern που θέλουμε. - - ls -l | egrep "^-(.)(.)(.)...\1\2\3" - -Πιο αναλυτικά συμβαίνει το εξής: -1. Θέλουμε το pattern να ξεκινάει με - ώστε να είναι αρχείο -2. Αποθηκεύουμε τους 3 επόμενους χαρακτήρες στις μεταβλητές 1, 2, 3. -3. Έχουμε φτάσει στο πεδίο του group, οπότε ψάχνουμε για οποιονδήποτε -χαρακτήρα επειδή δεν μας νοιάζει σε αυτό το παράδειγμα τι permissions έχει το group. -4. Тώρα είμαστε στο πεδίο των others. Εμφανίζουμε τις μεταβλητές 1, 2, 3 -(με την σειρά) οι οποίες έχουν κρατήσει κάθε permission του user. - -Αποτέλεσμα εκτέλεσης της εντολής: - - -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 - --wx--x-wx 1 christos christos 0 Nov 14 22:16 f2 - ------x--- 1 christos christos 0 Nov 14 22:16 f3 - ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 - -c) Με την ίδια λογική όπως στο ερώτημα b, απλώς αυτή τη φορά δεν θα κρατήσουμε όλα τα -permissions του user, αλλά μόνο τα permissions για write. - - ls -l | egrep "^-.(.)..\1..\1." - -Αποτέλεσμα εκτέλεσης της εντολής: - - ------x--- 1 christos christos 0 Nov 14 22:16 f3 - -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 - ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 - -d) Ξανά με την ίδια λογική, αλλά κρατήσουμε τα πεδία για write και execute. - - ls -l | egrep "^-.(.)(.).\1\2.\1\2" - -Αποτέλεσμα εκτέλεσης της εντολής: - - -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 - ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 - -e) Αυτή τη φορά θα κρατήσουμε στις μεταβλητές τα permissions από το group, και όχι -από τον user. - - ls -l | egrep "^-...(.).(.)\1.\2" - -Αποτέλεσμα εκτέλεσης της εντολής: - - -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 - --wx--x-wx 1 christos christos 0 Nov 14 22:16 f2 - ---x-wx-wx 1 christos christos 0 Nov 14 22:16 f6 - ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 - -Ερώτηση 32: ------------ -Υποθέστε πως οι γραμμές στο αρχείο /etc/passwd είναι όμοιες με την παρακάτω: - -spouneri:x:2107:1067:Pouneridis Sokratis:/home/student/e2021/spouneri:/bin/bash - -Στο πέμπτο πεδίο θα υπάρχει πάντα πρώτο το επίθετο και μετά το όνομα του χρήστη. -Μόνο ένα επίθετο και μόνο ένα όνομα, γραμμένα με λατινικούς χαρακτήρες κεφαλαίους -ή/και πεζούς. - -Τα υπόλοιπα πεδία θα είναι γραμμένα πάντα με πεζούς λατινικούς -χαρακτήρες. - -Ελέγχοντας το αρχείο /etc/passwd και κάνοντας χρήση της εντολής egrep -βρείτε όλους τους (υποθετικούς) χρήστες του συστήματος όπου: - -a. Χρησιμοποιούν για κέλυφος το bash -b. To HOME DIRECTORY τους βρίσκεται στον κατάλογο /home -c. To UID τους είναι ίδιο μετο GID τους -d. Τουλάχιστον τα 5 πρώτα γράμματα του επιθέτου τους αποτελούν μέρος και του username τους -e. Τουλάχιστον τα 3 πρώτα γράμματα του επιθέτου τους και τα 3 πρώτα γράμματα του -ονόματός τους αποτελούν μέρος και του username τους. - -Απάντηση: - -=================================================================== -=================================================================== -32 -=================================================================== -=================================================================== diff --git a/sh-os1/ex1/ex1.txt b/sh-os1/ex1/ex1.txt @@ -0,0 +1,709 @@ +Eργαστήριο ΛΣ 1 / Άσκηση 1 / 2020-21 +Ονοματεπώνυμο: Χρήστος Μαργιώλης +ΑΜ: [REDACTED] +==================================== + +Ερώτηση 1: +---------- +Δημιουργήστε στον τρέχοντα κατάλογο το αρχείο 'ask1.txt' με τα ακόλουθα +περιεχόμενα(όνομα, επώνυμο, username, ΤΚ, περιοχή, τηλ.), και εμφανίστε +το στησυνέχεια στην οθόνη, με αριθμημένες τις γραμμές του. + +Απάντηση: +Προκειμένου να δημιουργήσουμε ένα αρχείο χρησιμοποιούμε την εντολή 'touch [FILE...]', +όπου FILE είναι το όνομα του αρχείου και ... ότι μπορούμε να δώσουμε όσα ορίσματα +θελουμε. Στην προκειμένη περίπτωση + + touch ask1.txt + +Αν και θα μπορούσαμε να γράψουμε τα δεδομένα του αρχείο σε έναν +κειμενογράφο, χρησιμοποιώντας την 'echo' (και οποιαδηποτε παρόμοια εντολή, +όπως την 'printf'), μπορούμε να ανακατευθύνουμε την έξοδο της στο αρχείο που θέλουμε, +οπότε μπορούμε με τις παρακάτω εντολές να έχουμε το ίδιο αποτέλεσμα. +Για χάρην απλότητας στο διάβασμα επέλεξα να καλέσω αρκετές φορές την 'echo' αντί να +ενώσω τα πάντα με newlines. Από την δεύτερη κλήση της και μετά το >> σημαίνει +ότι θέλουμε να γράψουμε στο τέλος του αρχείο, όχι να γράψουμε το αρχείο από την αρχή. + + echo "George Pappas george2 12136 Peristeri-------" > ask1.txt + echo "Nick Nikolaoy nick23 12232 Aigaleo 5314555" >> ask1.txt + echo "George Georgioy george583 11132 Athens-------" >> ask1.txt + echo "Helen Georgioy helen3 12136 Peristeri 5748456" >> ask1.txt + echo "Nick Pappas nick4 11223 Aigaleo 5324123" >> ask1.txt + echo "Helen Ioannoy helen367 13222 Athens ------- >> ask1.txt + echo "Helen Thanoy helen36 11132 Peristeri9718345 >> ask1.txt + echo "Vasilis Mamalis vas32 12345 Dafni 9738383 >> ask1.txt + +Για να εμφανίσουμε τα περιεχόμενα του αρχείου με αριθμημένες σειρές, +θα χρησιμοποιηθεί η εντολή 'nl', η οποία αριθμεί σειρές, δέχοντας ως +input το αρχείο με τα περιεχόμενα. + + nl ask1.txt + +Αποτέλεσμα εκτέλεσης εντολής: + + 1 George Pappas george2 12136 Peristeri------- + 2 Nick Nikolaoy nick23 12232 Aigaleo 5314555 + 3 George Georgioy george583 11132 Athens------- + 4 Helen Georgioy helen3 12136 Peristeri 5748456 + 5 Nick Pappas nick4 11223 Aigaleo 5324123 + 6 Helen Ioannoy helen367 13222 Athens ------- + 7 Helen Thanoy helen36 11132 Peristeri9718345 + 8 Vasilis Mamalis vas32 12345 Dafni 9738383 + +Ερώτηση 2: +---------- +Τρέξτε την εντολή cal -3 > calfile.txt και εξηγείστε τι ακριβώς κάνει. + +Απάντηση: +Η εντολή 'cal' αρχικά εμφανίζει ημερολόγιο του τρέχοντος μήνα. Με την +εντολή + + cal -3 > calfile.txt + +Θα εμφανιστεί ο προηγούμενος, τρέχων και επόμενος μήνας, και στην συνέχεια +το output της εντολής θα γραφτεί στο αρχείο calfile.txt + +Ερώτηση 3: +---------- +Συνενώστε τα αρχεία calfile.txt και ask1.txt σε ένα αρχείο με όνομα full.txt + +Απάντηση: +Για την συνένωση των δύο παραπάνω αρχείων - και γενικότερα δύο ή παραπάνω +αρχειών - χρησιμοποιούμε την εντολή 'cat', οπότε + + cat calfile.txt ask1.txt > full.txt + +Ερώτηση 4: +---------- +Εμφανίστε στην οθόνη τα πέντε πιο πρόσφατα τροποποιημένα αρχεία του καταλόγου σας. + +Απάντηση: +Για να εμφανίσουμε τα αρχεία του καταλόγου χρησιμοποιούμε την εντολή 'ls'. +Προκειμένου να εμφανιστούν κατά ημερομηνία τροποποίησης ενεργοποιούμε την +επιλογή -t. Έπειτα θα κάνουμε pipe το output του 'ls' στην εντολή 'head' για να +εμφανίσουμε μόνο τα 5 πρώτα αρχεία. + + ls -t | head -6 + +Ερώτηση 5: +---------- +Δημιουργήστε έναν κατάλογο με όνομα 'mydir1'. Μεταβείτε σε αυτόν και στη +συνέχεια αντιγράψτε εκεί (χωρίς να αλλάξετε κατάλογο) το αρχείο 'full.txt' +(από το γονικό κατάλογο). Μετονομάστε το εν συνεχεία σε 'new.txt'. +Επιστρέψτε στο γονικό κατάλογο. Διαγράψτε τον κατάλογο 'mydir1' και τα +περιεχόμενά του. + +Απάντηση: +Οι εντολές που θα χρειαστούμε είναι οι εξής: +mkdir: Δημιουργεί κατάλογο +cd: Αλλάζει κατάλογο +cp: Αντιγράφει αρχεία και καταλόγους +rm -rf: Διαγράφει αναδρομικά έναν κατάλογο (εφόσον υπάρχει το -rf) + +Στην πρώτη σειρά, το && σημαίνει ότι η επόμενη εντολή θα εκτελεστεί +μόνο αν η προηγούμενη εντολή εκτελεστεί επιτυχώς. Στην δεύτερη σειρά +το '.' δηλώνει τον κατάλογο που βρισκόμαστε - το '..' δηλώνει +τον γονικό κατάλογο. + + mkdir mydir1 && cd mydir1 + cp ../full.txt . + cd .. + rm -rf mydir1 + +Ερώτηση 6: +---------- +Δώστε τις εντολές που θα εμφανίσουν: +(α) όλα τα αρχεία του καταλόγου /usr με πληροφορίες για το inode τους και +το μέγεθος τους σε blocks. +(β) όλα τα περιεχόμενα του δέντρου καταλόγων και υποκαταλόγων (αναδρομικά) +που βρίσκονται κάτω από τον κατάλογο /usr, με πλήρεις πληροφορίες για +κάθε ένα από αυτά και εμφανιζόμενα σταδιακά, σελίδα προς σελίδα. + +Απάντηση: +Και στα δύο υποερωτήματα θα χρησιμοποιηθεί η εντολή 'ls' +(α) Η επιλογή -i εμφανίζει το inode και η επιλογή +-s το μέγεθος σε blocks, οπότε + + ls -lsi /usr + +(β) Η επιλογή -R εμφανίζει αναδρομικά όλα τα περιεχόμενα ενός +καταλόγου, οπότε + + ls -lR /usr + +Ερώτηση 7: +---------- +Δημιουργήστε έναν κατάλογο με όνομα 'testdir1'. Μεταβείτε σε αυτόν +και φτιάξτε εκεί ένα hard link (με το όνομα 'ask1link') προς το αρχείο +'ask1.txt' του γονικού καταλόγου. Βεβαιωθείτε (δίνοντας την κατάλληλη +εντολή και εξηγώντας τι βλέπετε) ότι έχει δημιουργηθεί και ότι δεν είναι +symbolic (soft) link. + +Απάντηση: +Για να φτιάξουμε hard link θα χρησιμοποιήσουμε την εντολή 'ln'. + + mkdir testdir1 && cd testdir1 + ln ../ask1.txt ask1link + +Αν εκτελέσουμε την εντολή 'ls -li' στον κατάλογο testdir1 θα δούμε +ότι σε αντίθεση με το soft link, στο hard link δεν εμφανίζεται +το -> το οποίο δηλώνει ότι είναι symbolic link. Επίσης +παρατηρούμε ότι και το ask1link αλλά και το ask1.txt έχουν το ίδιο +inode. + +Ερώτηση 8: +---------- +Μπείτε στο αρχείο 'ask1link' και διαγράψτε την τελευταία του γραμμή. +Βεβαιωθείτε στη συνέχεια ότι η αλλαγή αυτή έχει γίνει και στο αρχείο 'ask1.txt'. + +Απάντηση: +Εφόσον το ask1link ειναι hardlink στο ask1.txt, δηλαδή είναι reference +στο ask1.txt, ό,τι αλλαγή γίνει στο ένα αρχείο, θα γίνει και στο άλλο, +οπότε αν διαγράψουμε την τελευταία γραμμή από το ask1link, η αλλαγή +πράγματι θα έχει γίνει και στο ask1.txt. + +Ερώτηση 9: +---------- +Δημιουργήστε ένα κατάλογο kat1 και μέσα σε αυτόν δύο αρχεία, file1 και file2, +με περιεχόμενο τη λέξη 'one' το ένα και τη λέξη 'two' το άλλο. +Τρέξτε (μέσα στον κατάλογο kat1) την εντολή 'cp *' και εξηγήστε το αποτέλεσμα. +Στη συνέχεια τρέξτε την εντολή 'mv *' και εξηγήστε το αποτέλεσμα. + +Απάντηση: +Αρχικά πρέπει να γράψουμε τα περιέχομενα στα κατάλληλα αρχεία. + + echo "one" > file1 + echo "two" > file2 + +Αφού τρέξουμε την εντολή 'cp *' στον kat1 θα παρατηρήσουμε ότι και τα +δύο αρχεία τώρα έχουν την λέξη "one". + + $ cat file1 file2 + + one + one + +Αυτό γίνεται επειδή γράφοντας 'cp *', επιλέγουμε όλα τα αρχεία του +καταλόγου. Επειδή όμως έχουμε δύο αρχεία η εντολή θα αναπτυχθεί σε + + cp file1 file2 + +και αυτό που θα γίνει τελικά είναι να αντιγραφεί το file1 στο file2. +Όταν τρέξουμε την εντολή 'mv *' θα δούμε ότι διαγράφεται το file1, +επειδή, όπως και με την 'cp *', η εντολή θα αναπτυχθεί σε + + mv file1 file2 + +οπότε το file1 θα μετονομαστεί σε file2, και έτσι θα χαθεί. + +Ερώτηση 10: +----------- +Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες τελειώνουν +με ένα ή περισσότερα συνεχόμενα ψηφία. + +Απάντηση: +Η εντολή 'grep' δέχεται ένα regular expression (regex) και επιστρέφει +τις γραμμές στο αρχείο στις οποίες βρίσκεται το regex. +Το regex που θα ψάξουμε θα αποτελείται από τα εξής μέρη: + +1. [0-9] - οποιδήποτε ψηφίο από το 0 εώς το 9 +2. \+ - μία ή παραπάνω επαναλήψεις του προηγούμενου +3. $ - τέλος γραμμής + +Οπότε η τελική εντολή θα είναι + + grep "[0-9]\+$" ask1.txt + +Ερώτηση 11: +----------- +Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες περιέχουν μεν +το πρότυπο 'Pap' αλλά δεν περιέχουν το πρότυπο 'Aig'. + +Απάντηση: +Στην εντολή 'grep' η επιλογή -v αποκλείει το δοθέν regex. Προκειμένου +πρώτα να πάρουμε τις γραμμές που περιέχουν το πρότυπο 'Pap' αλλα όχι +το πρότυπο 'Aig', θα εκτελέσουμε το 'grep' 2 φορές, ώστε πρώτα να πάρουμε +όλες τις γραμμές που περιέχουν το 'Pap' και μετά να αποκλείσουμε το 'Aig'. + + grep 'Pap' ask1.txt | grep -v 'Aig' + +Ερώτηση 12: +----------- +Εμφανίστε τις γραμμές του αρχείου 'ask1.txt' οι οποίες δεν αρχίζουν +με 'G' ή 'N' και περιέχουν εν συνεχεία (κάπου στα περιεχόμενά τους) +τα πρότυπα 'Geo' και 'Per' με αυτή τη σειρά.' + +Aπάντηση: +Όπως και στην ερώτηση 11, θα μπορούσαμε να χρησιμοποιήσουμε την επιλογή +-v για την εντολή 'grep', αλλα θα χρησιμοποιήσουμε μία διαφορετική σύνταξη. +Αυτή τη φορά τα regex που θα ψάξουμε είναι τα εξής + +Για την πρώτη κλήση: +1. ^ - ξεκινάει με +2. ^[GN] - πρεπει να ξεκινάει με G ή N +3. ^[^GN] - ΔΕΝ πρέπει να ξεκινάει με G ή N + +Για την δεύτερη κλήση: +1. Geo - περιέχει την λέξη 'Geo' +2. .* - οποιοσδήποτε αριθμός οποιουδήποτε χαρακτήρα +3. Per - περιέχει την λέξη 'Per' + +Οπότε η τελική εντολή είναι (το | ειναι separator) + + grep "^[^GN]" ask1.txt | grep "Geo.*Per" + +Αποτέλεσμα εκτέλεσης εντολής: + + Helen Georgioy helen3 12136 Peristeri 5748456 + +Ερώτηση 13: +----------- +Πόσοι χρήστες που το username τους δεν αρχίζει από 'ls1' είναι +συνδεδεμένοι στο σύστημα; + +Απάντηση: +Η εντολή 'who' μπορεί να μας επιστρέψει μια λίστα με τους χρήστες +που είναι συνδεδεμένοι. Ο λόγος που χρησιμοποίησα την 'who' αντί +για την 'w' που κάνει περίπου το ίδιο πράγμα είναι επειδή η 'w' +έχει και μια γραμμή header στην αρχή, οπότε 'wc -l' θα την μέτραγε. +Με την χρήση της εντολής 'wc' μπορούμε να μετρήσουμε λέξεις, γραμμές +και χαρακτήρες. Αν στην εντολή 'wc' δώσουμε την επιλογή -l τότε θα +μετρήσει μόνο πόσες γραμμές έχει το input που της δώθηκε. + + who | grep -v "^ls1" | wc -l + +Ερώτηση 14: +----------- +Εμφανίστε όλες τις διεργασίες χρηστών (αλλ/σης) που τρέχουν αυτή +τη στιγμή στο σύστημα. + +Απάντηση: +Η εντολή 'ps' (process status) εμφανίζει τις τρέχουσες διεργασίες που +εκτελεί το σύστημα. Επιπλέον θα χρειαστούμε τις επιλογές a και u, οι οποίες +εμφανίζουν τις διεργασίες που εκτελούνται από όλους τους συνδεδεμένους χρήστες +αυτή τη στιγμη. Στην εντολή 'ps' χρησιμοποιήσα την BSD σύνταξη. + + ps -au + +Αποτέλεσμα εκτέλεσης της εντολής: + + USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND + christos 5200 0.1 0.1 18048 7084 2 Ss 21:44 0:09.04 /usr/local/bin/zsh + christos 1160 0.0 0.1 15072 6016 v0 I 12:19 0:00.07 -zsh (zsh) + christos 1175 0.0 0.0 11828 3044 v0 I+ 12:19 0:00.00 /bin/sh /usr/local/bin/startx + christos 1188 0.0 0.0 13164 3240 v0 I+ 12:19 0:00.00 xinit /home/christos/.xinitrc + christos 1192 0.0 0.1 22152 11360 v0 S 12:19 0:19.69 dwm + christos 1218 0.0 0.1 17136 8000 0- S 12:20 0:16.20 slstatus + christos 5005 0.0 0.1 18004 7000 1 Is 21:15 0:00.31 /usr/local/bin/zsh + christos 5193 0.0 0.2 28028 16288 1 S+ 21:44 0:07.88 nvim ex1.txt + christos 6849 0.0 0.0 11860 3080 2 R+ 00:22 0:00.00 ps -u + root 1158 0.0 0.0 10880 2304 v1 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv1 + root 1159 0.0 0.0 10880 2304 v2 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv2 + root 1160 0.0 0.0 10880 2304 v3 Is+ 13:14 0:00.00 /usr/libexec/getty Pc ttyv3 + +Ερώτηση 15: +----------- +Πόσες διεργασίες χρηστών (αλλ/σης) τρέχουν στο σύστημα και τελειώνει +το όνομά τους με 'sh' ? + +Απάντηση: +Τρέχοντας την εντολή της ερώτησης 14 (ps -ux) και φιλτράροντας +το ouput ώστε να πάρουμε μόνο τις γραμμές που τελειώνουν σε +'sh', έχω 3 διεργασίες που το όνομα τους τελειώνει σε 'sh' + + ps -au | grep "sh$" | wc -l + +Συνολικά έχουμε 3 διεργασίες που τελειώνουν σε sh. + +Ερώτηση 16: +----------- +Εμφανίστε όλες τις διεργασίες χρηστών (αλλ/σης) που τρέχουν αυτή τη στιγμή στο σύστημα. + +Απάντηση: +Αυτή τη φορά στην εντολή 'ps', πέρα από την επιλογή u, θα δώσουμε και την επιλογή +x, η οποία εμφναίζει πληροφορίες ακόμα και για διεργασίες που δεν ελέγχουν κάποιο terminal + + ps -aux + +Το output της εντολής είναι πολύ μεγάλο για να το συμπεριλάβω εδώ. + +Ερώτηση 17: +----------- +Πόσα αρχεία του τρέχοντος καταλόγου σας (μόνο του τρέχοντος -όχι και +των υποκαταλόγων του) έχουν permissions 'rw' από τους πάντες και 'x' +από κανέναν; + +Απάντηση: +Η 'ls -l' στην αρχή κάθε σειράς εμφανίζει το permission string και με την +'grep' μπορούμε να εμφανίσουμε μόνο τις γραμμές που περιέχουν το permission +που ζητάει η εκφώνηση. Τέλος διοχετεύουμε την έξοδο στην 'wc -l'. + + ls -l | grep "^-rw-rw-rw-" | wc -l + +Ερώτηση 18: +----------- +Βρείτε τους καταλόγους του συστήματος που το όνομά τους αρχίζει από 'b'. + +Απάντηση: +Η εντολή 'find' είναι μια πιο ανεπτυγμένη μορφή της 'ls' στην οποία μπορούμε +να δώσουμε πολλές παραπάνω επιλογές. Οι επιλογές που έχουν δωθεί στην παρακάτω εντολή +σημαίνουν τα εξής: +/* - η αναζήτηση ξεκινάει από την ρίζα του συστήματος (root directory) +-type d - αναζήτηση μόνο για directories +-name "b*" - το όνομα τους πρέπει να ξεκινάει από 'b' + + find /* -type d -name "b*" + +Ερώτηση 19: +----------- +Να βρείτε και να παρουσιάσετε στην οθόνη με πλήρεις πληροφορίες +όλα τα αρχεία με όνομα που αρχίζει από tty και βρίσκονται στον κατάλογο /dev. + +Απάντηση: +Η εντολή stat επιστρέφει πλήρεις πληροφορίες για ένα αρχείο. +Με την εντολή 'grep', όπως έχει ειπωθεί και σε παραπάνω ερωτήσεις, μπορούμε +να πάρουμε τις γραμμές στις οποίες γίνεται match ένα regular +expression - έτσι κατά την εμφάνιση των αρχείων του /dev μπορούμε +να εξάγουμε μόνο όσες γραμμές περιέχουν την λέξη 'tty'. + + stat /dev/* | grep "tty" + +Ερώτηση 20: +----------- +Ταξινομήστε τα περιεχόμενα του αρχείου 'ask1.txt' ως προς το +username σε φθίνουσα σειρά. + +Απάντηση: +Θα ταξινομίσουμε το αρχείο με την χρήση της εντολής 'sort'. +Στην εντολή αυτή μπορούμε να της δώσουμε κατα ποιά στήλη θέλουμε +να ταξινομηθεί το αρχείο με την επιλογή -k. Εφόσον username +βρίσκεται στην 3η στήλη, θα δώσουμε την 3η στήλη ως μέσο +σύγκρισης για ταξινόμηση. Επίσης, προκειμένου να είναι κατα +φθήνουσα σειρά η ταξινόμηση, θα χρησιμοποιήσουμε την επιλογή -r + + sort -rk 3 ask1.txt + +Σε περίπτωση που θέλουμε οι αλλαγές να γραφτούν στο αρχείο, μπορούμε +να γράψουμε την εντολή ως + + sort -rk 3 ask1.txt -o ask1.txt + +Ερώτηση 21: +----------- +Ταξινομήστε τα '.c' αρχεία του καταλόγου στον οποίον δουλεύετε ως +προς το μέγεθός τους. + +Απάντηση: +Στην εντολή 'ls' η επιλογή -S ταξινομεί τα αρχεία ανάλογα με το +μέγεθός του κατα φθήνουσα σειρά (μεγαλύτερο πρώτα), οπότε + + ls -S *.c + +Ερώτηση 22: +----------- +Ταξινομήστε τα αρχεία του λογαριασμού σας με permissions 644 +ως προς το μέγεθός τους. + +Απάντηση: +Μπορούμε να εμφανίσουμε αρχεία που έχουν συγκεκριμένα permissions +με την εντολή 'find' και την επιλογή -perm [PERMISSION] όπου +το PERMISSION πρέπει να δωθεί σε οκταδικό. Επίσης μέσα στην 'find' +μπορούμε να εκτελέσουμε και επιπλέον shell commands στο output της με +την επιλογή -exec [COMMAND] - θα χρησιμοποιήσουμε την 'ls -lS' ώστε +να ταξινομήσει το output κατα μέγεθος. Η τελική εντολή θα εκτελεστεί +στον κατάλογο '/usr/home/christos', ο οποίος είναι ο κατάλογος του λογαριασμού +μου. Το {} \; στο τέλος της εντολής δηλώνει ότι η 'ls -lS' θα εκτελεστεί +σε κάθε αρχείο που βρίσκεται από την 'find'. + + find /usr/home/christos -perm 644 -exec ls -lS {} \; + + +Ερώτηση 23: +----------- +Ταξινομήστε όλα τα περιεχόμενα του καταλόγου /dev κατά πρώτον ως προς +τον owner και κατά δεύτερον ως προς το group και αποθηκεύστε το +output στο αρχείο 'binfiles.txt'. + +Аπάντηση: +Παίρνοντας πληροφορίες για τον owner και το group των αρχείων με την +'ls -l' μπορούμε να ταξινομήσουμε τις κατάλληλες στήλες (3 για owner +και 4 για group). + + ls -l | sort -k 3,4 > binfiles.txt + +Ερώτηση 24: +----------- +Φτιάξτε ένα αρχείο που θα περιέχει πληροφορίες μόνο για τους συνδεδεμένους +χρήστες που το username τους αρχίζει από 'ls1', ταξινομημένο ως προς +την ημερομηνία και ώρα σύνδεσή τους. + +Απάντηση: +ΑΦού φιλτραριστεί το ouput της 'w' ώστε να πάρουμε μόνο τους +χρήστες που το όνομά τους ξεκινάει από ls1, θα ταξινομήσουμε +κατά 2η και 3η στείλει επειδή αυτές δείχνουν την ημερομηνία +και ώρα σύνδεσης. + + w | grep "^ls1" | sort -k 2,3 > userinfo.txt + +Ερώτηση 25: +----------- +Αλλάξτεστο αρχείο 'ask1.txt' το όνομα 'Nick' (όπου συναντάται) σε 'Nickolaos'. + +Απάντηση: +Με την χρήση της εντολής 'sed' (stream editor) μπορούμε να αλλάξουμε ένα +pattern κάθε φορά που συναντάται με την παρακάτω σύνταξη + + sed "s/PATTERN/NEWPATTERN/g" file + +Τo g στο τέλος σημαίνει ότι αυτή η αλλαγή πρέπει να γίνει σε όλο το αρχείο, +και όχι μόνο την πρώτη φορά που θα συναντήσει το PATTERN. +Οπότε, στην προκειμένη περίπτωση η εντολή που θα εκτελεστεί είναι + + sed "s/Nick/Nickolaos/g" ask1.txt + +Εάν θέλουμε οι αλλαγές να αποθηκευτούν στο αρχείο κατευθείαν, μπορούμε +να εκτελέσουμε την εντολή με την επιλογή -i. + + sed -i "s/Nick/Nickolaos/g" ask1.txt + +Ερώτηση 26: +----------- +Έστω τα ακόλουθα items του filesystem με protection strings: +(α) '-rwxr-x--x', +(β) 'drwxr-x---' και +(γ) 'drwx--x--x. +Εξηγείστε τι είδους items είναι και ποια τα δικαιώματα πρόσβασης user, +group και others σε αυτά. + +Απάντηση: +(α) Το είδος item είναι απλό αρχείο εφόσον το πρώτο πεδίο του protection string +είναι κενό. Όσο αφορά τα δικαίωματα του, δικαίωμα εγγραφής έχει μόνο ο ιδιοκτήτης +του αρχείο, διαβάσματος ο ιδιοκτήτης του αρχείου, και όσοι είναι στο ίδιο group με αυτόν. +Επίσης όλοι οι χρήστες μπορούνε να το εκτελέσουν. + +(β) Το είδος είναι directory λόγω του 'd' στο πρώτο πεδίο του string. Δικαίωμα εγγραφής +έχει μόνο ο ιδιοκτήτης, διαβάσματος και εκτέλεσης ο ιδιοκτήτης και τα μέλη του group - +οι υπόλοιποι χρήστες δεν έχουν δικαιώματα για το συγκεκριμένο directory. + +(γ) Το είδος είναι επίσης directory λόγω του 'd' στο πρώτο πεδίο του string. Δικαίωμα +εγγραφής και διαβάσματος έχει μόνο ο ιδιοκτήτης και εκτέλεσης όλοι οι χρήστες. + +Ερώτηση 27: +----------- +Αλλάξτε τα permissions όλων των αρχείων του καταλόγου 'testdir1' +έτσι ώστε να έχουν δικαίωμα εκτέλεσης και εγγραφής μόνο ο ιδιοκτήτης, +ενώ δικαίωμα ανάγνωσης να έχουν όλοι. + +Απάντηση: +Η εντολή 'chmod' μπορεί να αλλάξει permissions. Με την επιλογή 'R' δηλώνουμε +ότι αυτό θέλουμε να γίνει αναδρομικά εφόσον θέλουμε να αλλάξουμε τα permissions +όλων των αρχείων του καταλόγου 'testdir1'. Τα υπόλοιπα πεδία σημαίνουν τα εξής: +u=wx - μόνο ο ιδιοκτήτης του αρχείου έχει δικαίωμα εγγραφής και εκτέλεσης +o=r - οι υπόλοιποι χρήστες έχουν δικαίωμα ανάγνωσης + + chmod -R u=wx,o=r testdir + +Ερώτηση 28: +----------- +Αλλάξτε τα permissions του καταλόγου 'testdir1' έτσι ώστε να έχουν δικαίωμα +πρόσβασης μόνοο ιδιοκτήτης και οι χρήστες του ιδίου με αυτόν group, +ενώ οι υπόλοιποι χρήστες να μην έχουν (θεωρείστε ότι τα τρέχοντα +permissions του καταλόγου είναι 755). + +Απάντηση: +Χρησιμοποιώντας πάλι την εντολή 'chmod' μπορούμε να αλλάξουμε και τα permissions +ενός καταλόγου. Τα πεδία τώρα σημαίνουν τα εξής: +ug=r - ο ιδιοκτήτης και τα μέλη του group έχουν δικαίωμα διαβάσματος +o-r - οι υπόλοιποι χρήστες δεν έχουν δικαίωμα διαβάσματος + + chmod ug=r,o-r testdir + +Ερώτηση 29: +----------- +Δημιουργήστε έναν νέο χρήστη στο σύστημά σας με username 'myfriend'. +Αλλάξτε στη συνέχεια τον ιδιοκτήτη του αρχείου 'ask1.txt' σε 'myfriend' και +μετακινήστε το στο working directory του. Περιορίστε τέλος το διαθέσιμο +χώρο αποθήκευσης στο δίσκο για το συγκεκριμένο χρήστη στα 10MB. + +Απάντηση: +Για να φτιάξουμε έναν user χρησιμοποιούμε την εντολή 'useradd'. Σε BSD +συστήματα η εντολή είναι η 'adduser'. Για να αλλάξουμε ιδιοκτήτη αρχείου +χρησιμοποιούμε την εντολή 'chown'. Τέλος, για να περιορίσουμε τον χώρο +αποθηκεύσης στον δίσκο για έναν χρήστη χρησιμοποιούμε την εντολή 'edquota'. + + useradd -m -d /home/myfriend myfriend + chown myfriend ask1.txt + mv ask1.txt /home/myfriend + edquota myfriend + +Η εντολή 'edquota' θα μάς ανοίξει στον default editor μας ένα αρχείο +στο οποίο μπορούμε να τροποποιήσουμε τον αποθηκευτικό χώρο για τον χρήστη +myfriend. Θα πρέπει να δούμε κάτι σαν + + Disk quotas for user ice19390133 (uid 1022): + Filesystem blocks soft hard inodes soft hard + /dev/vda1 36 10240 13312 11 0 0 + +Το 'soft' το θέτουμε σε 10240 (kilobyte), δηλαδή 10MB. + +Ερώτηση 30: +----------- +Έστω τα παρακάτω: +user1@localhost:~$ w +USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT +user1 pts/0 1.2.3.4 03:34 0.00s 0.38s 0.01s w +user2 pts/1 5.6.7.8 03:45 0.00s 0.38s 0.01s ls +user3 pts/2 9.7.5.3 03:57 0.00s 0.38s 0.01s ps + +user1@localhost:~$ ls -al /dev/pts/* +crw--w---- 1 user1 tty136, 0 Oct 25 04:04 /dev/pts/0 +crw--w--w- 1 user2 tty136, 1 Oct 25 04:04 /dev/pts/1 +crw--w--w- 1 user3 tty136, 2 Oct 25 04:04 /dev/pts/2 + +Εξηγήστε τι είδους items του file system είναι τα παραπάνω, +καθώς και τι θα κάνουν οι παρακάτω εντολές: +user1@localhost:~$ cat > /dev/pts/1 +user1@localhost:~$ wall "test" + +Απάντηση: +Σε ένα permission string, το 'c' δηλώνει ότι αυτό το item +ειναι 'character device', το οποίο πρακτικά σημαίνει συσκευές +οι οποίες μεταφέρουν δεδομένα σε μορφή κειμένου (bytes). Τέτοιες +συσκευές είναι για παράδειγμα τα ηχεία. Στην προκειμένη περίπτωση +το item ειναι 'tty' (από το teletype), δηλαδή είναι terminals. Τα +συγκεκριμένα terminals ειναι συνδεδεμένα με το πληκτρολόγιο. + +Η εντολή 'cat > /dev/pts/1' θα εμφανίζει στο πρώτο terminal που +ανοίχτηκε οτίδηποτε γράψουμε στο stdin. Στον κατάλογο /dev/pts/ +εμφανίζονται τα ανοιχτά terminals που τρέχουν αυτή τη στιγμή. + + $ cat > /dev/pts/1 + + hello world + hello world + +Η εντολή 'wall "test"' θα στείλει το μήνυμα "test" σε όλους τους +συνδεδεμένους χρήστες. + + $ wall "test" + + Broadcast message from christos@freebsd (pts/1) (Wed Nov 14 23:26:58 2020): + + test + + +Ερώτηση 31: +----------- +Δημιουργείστε τα αρχεία f1, f2, f3, f4, f5, f6 ,f7 με τα εξής δικαιώματα: +f1, 757 +f2, 313 +f3, 010 +f4, 642 +f5, 551 +f6, 133 +f7, 111 +Με χρήση της εντολής ls –l και διοχετεύοντας τα αποτελέσματά της στην εντολή +egrep να βρείτε τα αρχεία όπου: +a. To group έχει δικαιώματα r-x. +b. Ο user και οι others έχουν ακριβώς τα ίδια δικαιώματα +c. Ο user, το group και οι others έχουν τα ίδια δικαιώματα για write +d. Ο user, το group και οι others έχουν τα ίδια δικαιώματα για write και execute +e. To group και οι others έχουν τα ίδια δικαιώματα για read και execute + +Απάντηση: +a) Το pattern που θα αναζητήσουμε είναι στο permission string να περιέχονται +οποιοιδήποτε χαρακτήρες σε όλα τα πεδία αλλά πρέπει οπωσδήποτε τα permissions +του group να είναι r-x. Το - στην αρχή το βάζουμε για να ψάξουμε μόνο αρχεία και όχι +τυχόν directories. + + ls -l | egrep "^-...r-x..." + +Αποτέλεσμα εκτέλεσης της εντολής: + + -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 + -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 + +b) Θα φτιάξουμε τρία capture groups στα πεδια που βρισκονται τα permissions +του user ώστε να ψάξουμε ό,τι αποθηκεύτηκε στις μεταβλητές 1, 2 και 3 +στο πεδίο που βρίσκονται τα permissions των others. Ένα capture group φτιάχνουμε +βάζοντας () και γράφοντας μέσα τους το pattern που θέλουμε. + + ls -l | egrep "^-(.)(.)(.)...\1\2\3" + +Πιο αναλυτικά συμβαίνει το εξής: +1. Θέλουμε το pattern να ξεκινάει με - ώστε να είναι αρχείο +2. Αποθηκεύουμε τους 3 επόμενους χαρακτήρες στις μεταβλητές 1, 2, 3. +3. Έχουμε φτάσει στο πεδίο του group, οπότε ψάχνουμε για οποιονδήποτε +χαρακτήρα επειδή δεν μας νοιάζει σε αυτό το παράδειγμα τι permissions έχει το group. +4. Тώρα είμαστε στο πεδίο των others. Εμφανίζουμε τις μεταβλητές 1, 2, 3 +(με την σειρά) οι οποίες έχουν κρατήσει κάθε permission του user. + +Αποτέλεσμα εκτέλεσης της εντολής: + + -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 + --wx--x-wx 1 christos christos 0 Nov 14 22:16 f2 + ------x--- 1 christos christos 0 Nov 14 22:16 f3 + ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 + +c) Με την ίδια λογική όπως στο ερώτημα b, απλώς αυτή τη φορά δεν θα κρατήσουμε όλα τα +permissions του user, αλλά μόνο τα permissions για write. + + ls -l | egrep "^-.(.)..\1..\1." + +Αποτέλεσμα εκτέλεσης της εντολής: + + ------x--- 1 christos christos 0 Nov 14 22:16 f3 + -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 + ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 + +d) Ξανά με την ίδια λογική, αλλά κρατήσουμε τα πεδία για write και execute. + + ls -l | egrep "^-.(.)(.).\1\2.\1\2" + +Αποτέλεσμα εκτέλεσης της εντολής: + + -r-xr-x--x 1 christos christos 0 Nov 14 22:16 f5 + ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 + +e) Αυτή τη φορά θα κρατήσουμε στις μεταβλητές τα permissions από το group, και όχι +από τον user. + + ls -l | egrep "^-...(.).(.)\1.\2" + +Αποτέλεσμα εκτέλεσης της εντολής: + + -rwxr-xrwx 1 christos christos 0 Nov 14 22:16 f1 + --wx--x-wx 1 christos christos 0 Nov 14 22:16 f2 + ---x-wx-wx 1 christos christos 0 Nov 14 22:16 f6 + ---x--x--x 1 christos christos 0 Nov 14 22:16 f7 + +Ερώτηση 32: +----------- +Υποθέστε πως οι γραμμές στο αρχείο /etc/passwd είναι όμοιες με την παρακάτω: + +spouneri:x:2107:1067:Pouneridis Sokratis:/home/student/e2021/spouneri:/bin/bash + +Στο πέμπτο πεδίο θα υπάρχει πάντα πρώτο το επίθετο και μετά το όνομα του χρήστη. +Μόνο ένα επίθετο και μόνο ένα όνομα, γραμμένα με λατινικούς χαρακτήρες κεφαλαίους +ή/και πεζούς. + +Τα υπόλοιπα πεδία θα είναι γραμμένα πάντα με πεζούς λατινικούς +χαρακτήρες. + +Ελέγχοντας το αρχείο /etc/passwd και κάνοντας χρήση της εντολής egrep +βρείτε όλους τους (υποθετικούς) χρήστες του συστήματος όπου: + +a. Χρησιμοποιούν για κέλυφος το bash +b. To HOME DIRECTORY τους βρίσκεται στον κατάλογο /home +c. To UID τους είναι ίδιο μετο GID τους +d. Τουλάχιστον τα 5 πρώτα γράμματα του επιθέτου τους αποτελούν μέρος και του username τους +e. Τουλάχιστον τα 3 πρώτα γράμματα του επιθέτου τους και τα 3 πρώτα γράμματα του +ονόματός τους αποτελούν μέρος και του username τους. + +Απάντηση: + +=================================================================== +=================================================================== +32 +=================================================================== +=================================================================== diff --git a/sh-os1/ex2/searching b/sh-os1/ex2/searching @@ -0,0 +1,57 @@ +#!/bin/sh + +main() { + test $# -eq 0 && usage + isnumber $1 + isnumber $2 + + sum1=0; sum2=0; sum3=0; sum4=0; sum5=0 + while [ ! "$cont" = "n" ] ; do + read -erp "Directory name: " dir + + test -z "$dir" && echo "${0##*/}: please give a directory name" && exit 1 + test ! -d "$dir" && echo "${0##*/}: '$dir' is not a directory" && exit 1 + + echo "Files with permissions $1: " + find "$dir" -perm $1 2> /dev/null + sum1=$(($sum1+$(find "$dir" -perm $1 2> /dev/null | wc -l))) + echo "" + + echo "Files modified within the last $2 days: " + find "$dir" -mtime -$2 2> /dev/null + sum2=$(($sum2+$(find "$dir" -mtime -$2 2> /dev/null | wc -l))) + echo "" + + echo "Subdirectories accessed within the last $2 days: " + find "$dir" -type d -atime -$2 2> /dev/null + sum3=$(($sum3+$(find "$dir" -type d -atime -$2 2> /dev/null | wc -l))) + echo "" + + echo "Files which all users have read access to: " + ls -l "$dir" 2> /dev/null | grep "^-r..r..r.." + sum4=$(($sum4+$(ls -l "$dir" 2> /dev/null | grep "^-r..r..r.." | wc -l))) + echo "" + + echo "Subdirectories which others have write access to: " + ls -l "$dir" 2> /dev/null | grep "^d.w..w..w." + sum5=$(($sum5+$(ls -l "$dir" 2> /dev/null | grep "^d.w..w..w." | wc -l))) + echo "" + + read -erp "Do you want to continue (y/n)? " cont + test "$cont" = "n" && + printf "Total entries found for:\n1. %s\n2. %s\n3. %s\n4. %s\n5. %s\n" \ + "$sum1" "$sum2" "$sum3" "$sum4" "$sum5" + done + +} + +usage() { + echo "usage: ${0##*/} [PERMS] [DAYS]" && exit 0 +} + +isnumber() { + test -z $(echo "$1" | grep "^[0-9]\+$") && + echo "${0##*/}: '$1' is not a digit" && exit 1 +} + +main "$@" diff --git a/sh-os1/ex2/teldb b/sh-os1/ex2/teldb @@ -0,0 +1,86 @@ +#!/bin/sh + +emptylnregex="^\ *$" + +main() { + case $1 in + -a) newentry ;; + -l) list ;; + -s) sortcol $2 ;; + -c) filter $2 ;; + -d) deleteln $2 $3 ;; + -n) emptyln ;; + *) usage ;; + esac +} + +usage() { + echo "usage: ${0##*/} [-a|-l|-s [COL]|-c [KEYWORD]|-d [KEYWORD [-b|-r]]|-n]" + echo "" + echo "options:" + echo "-a add a new entry" + echo "-l list contents of file" + echo "-s sort based on specified column (e.g ${0##*/} -s 3)" + echo "-c filter keyword" + echo "-d delete lines containing a keyword followed by one of the options below" + echo " -b replace line with an empty line" + echo " -r remove line completely" + echo "-n count empty lines and ask if they should be deleted" +} + +errempty() { + test -z "$1" && echo "${0##*/}: expected non-empty string" && exit 1 +} + +skipempty() { + grep -v "$emptylnregex" +} + +newentry() { + read -erp "First name: " fname + errempty "$fname" + + read -erp "Last name: " lname + errempty "$lname" + + read -erp "Town: " town + errempty "$town" + + read -erp "Phone number: " phone + errempty "$phone" + + printf "%s %s %s %s\n" "$fname" "$lname" "$town" "$phone" >> catalog +} + +list() { + nl catalog | skipempty +} + +sortcol() { + errempty "$1" + sort -k "$1" catalog | skipempty +} + +filter() { + errempty "$1" + grep "$1" catalog +} + +deleteln() { + errempty "$1" + errempty "$2" + + case $2 in + -b) sed -i "s/.*$1.*//" catalog ;; + -r) sed -i "/$1/d" catalog ;; + esac +} + +emptyln() { + printf "Empty lines in 'catalog': " + grep "$emptylnregex" catalog | wc -l + read -erp "Delete them (y/n)? " del + test "$del" = "y" && deleteln "$emptylnregex" "-r" +} + +main "$@"