commit 7a5653aded5380a4b75c94b7140d30d3a9eaaae6
parent 71fe6d09c17d127d2943c4ae67bc31b34999c59f
Author: Christos Margiolis <christos@margiolis.net>
Date: Thu, 26 Nov 2020 15:56:51 +0200
new assignments
Diffstat:
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 "$@"