כל הזכויות שמורות © לצבי מלמד, 2014-2022

Lab02: working with a terminal (console)- OR Intro to bash

רקע

SHELL הוא כינוי כללי לתכנה שרצה בטרמינל, ואשר "מתקשרת" איתנו (המשתמשים) - קולטת בכל פעם פקודת משתמש, מבצעת parsing לפקודה, מחליטה אם הפקודה חוקית או לא (תחביר, התייחסות לתוכניות/פקודות שקיימות או לא קיימות במאגר), ואם הפקודה חוקית, ה SHELL דואג לבצע אותה.

ה SHELL מגדיר שפה, וניתן לכתוב תכניות בשפה של ה SHELL - תכניות כאלו נקראות scripts (סקריפטים). קשה להגזים בהערכת החשיבות, הנפוצות והתועלת של שימוש בסקריפטים.

באיזה SHELL להשתמש? אתם מוזמנים לבדוק בגוגל, או לעיין בתשובה לשאלה הזאת ב Stack-Overflow". ובכן, קיימות תוכניות SHELL רבות. במעבדה הזאת ובמשך כל הקורס נעבוד עם bash. גם לינוקס / ubuntu פותח טרמינל ומריץ בו את bash (ברירת מחדל).

"שם המשחק" בעבודה עם טרמינל הוא יעילות. המטרה שלנו (במעבדה הזאת ובמעבדות הבאות) היא ללמוד לעבוד עם bash בצורה יעילה. בדרך כלל, לוקח זמן מה עד שלומדים לעבוד עם SHELL כלשהו, אבל כעבור כמה זמן, ככל שמכירים את האפשרויות שהוא נותן, ניתן להיות מאוד יעילים בעבודה עם ה- SHELL .

המטרה במעבדה הזאת היא להכיר את הפקודות הבסיסיות והנחוצות ביותר בעבודה עם bash, וכן להכיר מושגים ועקרונות בעבודה עם bash. ידע זה יאפשר לכם להיות יעילים בעבודה עם bash בהמשך הקורס וכן במקומות עבודה שתגיעו אליהם בעתיד.

כאמור, bash הוא רק אחד מני רבים - למשל, בסביבת לינוקס קיימים tcsh, ksh, dash, וכו'. ברגע שאתם מכירים היטב shell מסוים, העקרונות שלמדתם וסיגלתם לעצמכם ישימים גם ל SHELLS אחרים. רוב ה SHELLS מספקים קבוצה של אפשרויות (יכולות) דומות. הם נבדלים ביניהם ראשית בתחביר וביכולות נוספות שחלקם מציעים.


 המשימה במעבדה הזאת - מבוא לעבודה בסביבת Bash

הערה: המשימה הזאת מלווה בהדגמה והסברים פרונטליים בזמן השיעור במעבדה, ואתם מתבקשים לבצע את המעבדה במקביל למורה.
אפשרות נוספת (אולי עדיפה... לשיקולכם) - לצפות בהדגמה + כתיבה במחברת, ולבצע את המעבדה בבית.

נושאים עיקריים שנכסה בתירגול הזה

  1. התחלה - כיצד לפתוח טרמינל / חלון של BASH במעבדה
  2. ה- PROMPT -משמעותו, כיצד הוא נקבע ואיך ניתן ל"קנפג" אותו
  3. משתנים Variables
  4. תיקיית הבית home-dir
  5. אילו קבצים קיימים בתיקייה - הפקודה ls
  6. קבצים נסתרים - dot-files
  7. קבצי קונפיגורציה rc-files באופן כללי, וספציפית הקובץ .bashrc
  8. התקנת הקבצים .bashrc and .aliasrc בתיקיית הבית שלכם (על המחשב האישי שלכם)
  9. עריכת שורת הפקודה command line editing
  10. השלמת שם הקובץ file-name completion
  11. שימוש ב semi-colon בשורת הפקודה
  12. מבוא למבנה התיקיות בלינוקס / יוניקס
  13. איזו פקודה מתבצעת תכל'ס ואיך ה SHELL מוצא אותה?המשתנה PATH$
  14. רשימת פקודות שימושיות בלינוקס

Getting started with Bash    לרשימת הנושאים

Open an Ubuntu / bash terminal:
  1. WINDOW+R (i.e. run) and type wsl
If you work in Linux - just open a terminal. It will  most likely open a bash terminal. (BTW, on Ubuntu you have a short-cut - CNTL+ALT+T (or maybe just ALT+T) to open a terminal).

כעת אתם אמור לקבל חלון - טרמינל של bash שבו אנחנו יכולים להקליד פקודות שונות, והפלט שלהן יוצג (בד"כ) על המסך.

חלון CYGWIN שפתחתי אצלי במחשב נראה בערך כך:

cygwin terminal

החלון שפתחתי בלינוקס (במחשב שלי) נראה כך:

Linux Bash Terminal

Type in the following commands:


date
sleep 5

The Prompt:    לרשימת הנושאים

As you can see, after the command is executed and the date it printed, the shell (bash) is ready to get another command.
But how do we know it is indeed ready to get our next command?  
Answer:   it prints the prompt to the screen.

we can set  the prompt to look nicer and display  important information - for example...

Run the following commands which I use for my prompt:


PS1="\[\e]0;\w\a\]\n\e[7m\[\e[32m\]\u\@\[\e[33m\] \w\[\e[34m\]\n\\[\e[0m\]$==>  "

At this point the prompt has changed, and you should get a prompt similar to the following:

how to set prompt

אני "אוהב" את ה- prompt הזה. האם אני צריך להקליד את הפקודה הנ"ל בכל פעם שאני מריץ מחדש טרמינל של BASH ?

Variables    לרשימת הנושאים

  1. There are variables like in "any programming language".
  2. To set a var + value: <var-name>=<value> -     e.g.    PS1="something"
  3. To examine or reference the value - use '$' before the name of the variables
    echo $PS1
    
  4. There are predefined variables.
    A few important ones are:
    echo $HOME
    echo $USER
    echo $PATH
    
  5. כמובן, ישנם עוד הרבה מאוד משתנים (לעתים מכונים משתני-סביבה.. ויש הבדל מסוים בין "סתם משתנים" לבין "משתני סביבה" לא ניכנס כאן להבדלים האלו). בפרט בסביבה של CYGWIN - הוא מקבל "בירושה" את כל המשתנים שמוגדרים ב- Windows. אין צורך להכיר את כל המשתנים.
    הפקודה הבאה printenv מציגה את כל המשתנים למסך.

    printenv
    

The  Current Working Directory    לרשימת הנושאים

The shell maintains a notion of "current working directory". Why is this VERY  important?
How do I know what is the current working directory?

run the following commands:

שימו לב, הסולמית משמשת כהערה - ה bash מתעלם מכל מה שמופיע אחריה.
אין צורך להקליד את הפקודות הבאות - ניתן לעשות העתק-הדבק לכל הקטע הזה (לכל 6 הפקודות הבאות, כולל ההערה), ולהדביק אותן בחלון cygwin/bash

pwd            # print the working directory
mkdir dir1     # create a directory dir1
cd dir1        # change the working directory
pwd
cd ..          # change dir to the parent directory
pwd

The command pwd - prints the current working directory
the command mkdir - creates a new directory

The home directory    לרשימת הנושאים

What is the purpose and meaning of home directory?
what is the name of your home directory?

Run the following commands:
cd dir1
mkdir dir2
cd dir2
pwd
echo $HOME
cd $HOME
pwd
cd dir1/dir2
pwd
cd ~         # tilde (the symbol ~ is another name to the $HOME
echo ~

Inspecting the files  in the directory - the command ls    לרשימת הנושאים

the command ls tells you which files are there in your directory
run the commands
cd   # same as cd ~ i.e. cd w/o arguement changes to home dir
ls
ls -l
And also Run the commands:
ls -la  # same as ls -l -a : you can combine the flags
הערה לגבי דגלים של פקודות בלינוקס
דגלים הם האותיות הנוספות (לפעמים מלים) שלפניהם הסימן מינוס שאנו מוסיפים לפקודה.

מהי מטרת הדגלים? הדגלים עוברים לתכנית כארגומנטים לפונקציה main. הדגלים משפיעים על פעולת התכנית. לדוגמא, ראינו בפקודה ls שהיא מציגה את שמות הקבצים. אבל אם נוסיף לה את הדגל -l היא מציגה יותר אינפורמציה על הקבצים, כמו למשל, התאריך שבו הקובץ שונה לאחרונה (או נוצר), ההרשאות שיש עליו, גודלו בבתים וכו'.

הדרך המקובלת לתאר דגלים בלינוקס היא הסימן מינוס (לעתים שני מינוסים רצופים) ולאחריו אות או מילה. למשל:

gcc -Wall -std=c99 -c myprog.c
יש כאן דגל של אות אחת c- שאומר לקומפיילר לבצע רק קומפילציה ללא לינק (בלי להפעיל את הלינקר). הדגל Wall- הוא דגל של מילה, שאומר לקומפיילר להדפיס את כל האזהרות, ואילו הדגל std=c99- הוא דגל עם ערך מסוים, שאומר לקומפיילר באיזה סטנדרט של C להשתמש, במקרה הזה הסטנדרט מ- 1999 שנקרא c99. כאשר ישנם דגלים של אות אחת - ניתן לחבר אותם, כמו למשל:
ls -laF
שימו לב שאין תחביר קבוע בלינוקס לגבי הדגלים, אלא כל תכנית (כל פקודה) מגדירה לעצמה את הדגלים. כמו כן, שימו לב שאין צורך להכיר אותם בעל פה, ישנם כמה מנגנונים שעוזרים לנו בזה. אחד הוא הפקודה man והשני הוא שימוש בקיצורים, שהם גם נוחים יותר להקלדה, וגם זוכרים את הדגלים. למשל, (מופיע בהמשך, אבל אקדים את המאוחר): הפקודה grep מחפשת תבנית טסטס מסוימת בקובץ טקסט, ומדפיסה את השורות שמכילות את התבנית. אם אני רוצה שהחיפוש יהיה case insensitive (לא רגיש לאותיות גדולות או קטנות) צריך להוסיף את הדגל i-. אבל, הגדרתי קיצור gi שכולל כבר את הדגל, ואז במקום להקליד את הפקודה grep -i אקליד את הפקודה gi.

Dot files (hidden files), dot-rc files,  .bashrc file    לרשימת הנושאים


Motivation:
applications (programs) often need configuration files. E.g. set the prompt automatically, Set variables. etc...

At the same time, we usually don't want to "see" these configuration files.

Solution: Read configuration file, which we call - "RC" files (or "dot RC files") when they start up.

הערה לגבי קבצי טקסט וסיומות של קבצים בלינוקס
קבצי הקונפיגורציה, וכן הרבה קצבים אחרים הם קבצי טקסט. ניתן לראות אותם (את תכנם) באמצעות כלים כמו less, cat, more וכו'. או, אם רוצים לערוך אותם, ניתן באמצעות כל אדיטור של קבצי טקסט כמו למשל ++gedit, notepad ועוד.

לסיומות הקבצים בלינוקס יש הרבה פחות משמעות מאשר בסביבת חלונות. אמנם, קצבי C נסיים ב h. or .c. וקצבי ++C נסיים בסיומת .cpp or .cc. אבל האסוציאציה שיש בחלונות, בין שם של קובץ לבין האפליקציה שתורץ כאשר עשינו double-click על הקובץ - זה לא קיים בלינוקס. ולכן, קובץ כמו bashrc. - חלונות יחשוב ש bashrc זה הסוג של הקובץ - כי זה הסיומת שלו. בלינוקס, כאמור, המשמעות שונה.

Let's examine the .bashrc file in your home directory

  1. #change work dir  to home. you're probably already there
  2. cd ~
    
  3. view the file using the 'less' command
  4. less is a program, which displays the file page by page.
    less .bashrc
    
  5. Instead you can use the command 'cat' to dump the whole text file to the screen
  6. cat .bashrc
    
  7. OR - view / edit the file, using vi
  8. vi is a common and very old editor of Linux/Unix
    vi .bashrc
    
  9. Lastly, if you are on Linux (rather than Cygwin) you can use gedit
  10. gedit (pronounce: g-edit) is a a very convenient and intuitive editor on Linux.
    gedit .bashrc &
    

Install the files .bashrc and .aliasrc in your home directory    לרשימת הנושאים

One file can source ("include") another file.

Indeed, the setting I'm using, which is also installed in the lab, the .bashrc file is 'sourcing' another file, called '.aliasrc'. This file has many command shortcuts. For example, there's a very useful command called 'grep --color'. Instead of typing that, there's a shortcut definition, and we can type only 'g' instead.

Copy the files .bashrc and .aliasrc and put them in your home directory.

It is a good and common practice to save (keep) the old file, in case something goes wrong with the new file, and we want to undo the change.

  1. Download this file: bashrc tar file
  2. You should run the following command in order to open it:
    tar -xvf bashrc.tar
    cd bashrc_dir
    ls -la                      # you can see the files in this temp directory
    mv ~/.bashrc ~/.bashrc_sav  # saving
    cp .bashrc .aliasrc ~       # copying these two file to home dir (~ is home dir)
    cd                          # change dir to your home
    source .bashrc
    
Note:: after downloading these files, check if the dot at the beginning of the file was omitted. In this case, change the name (use the command mv, e.g. move aliasrc .aliasrc)

#  "move" or rename the .bashrc file - the command to rename a file in Linux is mv
mv .bashrc .bashrc-sav
ls -a
#  move the downloaded files .bashrc and .aliasrc to your home directory. You can do it from the file-explorer on windows.

To check that these files are now in your home directory, run the command:

ls -lda .*
Note: some unix tools allow us to combine flags. we don't need to type: ls -l -d -a ..... instead: ls -lda

What is the flag -d doing?   --> try the same command without this flag.

You should get output similar to this one:

ls -lda .*

Open a new windows, and check that things work properly,

e.g. you get the prompt, and you see the aliases  
Type the command: alias. If the above steps worked properly, you should see many aliases printed on the screen

Show/Hide output of alias command



command line editing    לרשימת הנושאים

בעבודה בטרמינל – מקלידים את הפקודות. חשוב – להיות פרודוקטיביים / יעילים / זריזים.
 כלומר – לחסוך בהקלדות. לתקן בקלות שורת פקודה שגויה. לשנות בקלות שורה/פקודה קודמת
במשימה זאת, עליך להתנסות בפעולות עריכה בסיסיות. טייל עם החצים למטה ולמעלה. כפי שאתה רואה - ה SHELL שומר על ההיסטוריה של הפקודות.
לאחר שהגעת לפקודה מסוימת... אתה יכול להקיש ENTER ואז הפקודה תתבצע כמו שהיא, או שאתה יכול לבצע עריכה של הפקודה במקום. השתמש בחצים ימינה ושמאלה, וכמו כן נסה את צירופי המקשים הבאים:
cntl + a
cntl + e
backspace
cntl + d
cntl + c

שימו לב...
יש המון טריקים וקיצורים בהקשר של עריכה של שורת הפקודה. נכיר "עוד קצת" בהמשך התירגול... צריך לדעת.. שיש דיי הרבה אפשרויות...

מי שעובד בזה הרבה,  (או כשיעבוד) כדאי לו להשקיע בלימוד הזה – ההשקעה מחזירה את עצמה במהירות!


כדוגמה נוספת נסו את הפקודות הבאות:
date
echo aaa
echo bbb
history 5
!-2
!-4
!d


file-name completion – השלמת שם הקובץ    לרשימת הנושאים

כאשר אנו מתחילים להקליד שם של קובץ או תיקייה... לחיצה על מקש TAB משלימה את שם הקובץ כל עוד יש השלמה יחידנית. אם אין השלמה יחידנית – יושמע צלצול פעמון. לחיצה נוספת (רציפה) על TAB מציגה את האפשרויות השונות. בנקודה זאת, נקליד עוד תו (אחד או יותר) ושוב TAB..

הריצו את הפקודות הבאות (אחת אחרי השניה):

mkdir temp_with-long-name  # create temp folder
cd temp<TAB>               # change dir
ls
touch file1 
ls f<TAB>
touch file22222
ls f<TAB><TAB>2<TAB>
cd ..
rmdir tem<TAB> 
# cannot remove, cause it's not empty
rm tem<TAB>/*
rmdir (use up arrow twice)

semicolon in command-line

לעתים נרצה בשורה אחת להקליד שתי פקודות (או יותר) - שתתבצענה ברצף, אחת אחרי השנייה. הדבר אפשרי – צריך להשתמש בנקודה פסיק כמפריד בין הפקודות.
למה זה טוב? לחסוך הקלדות. פקודות שרוצים שתתבצענה בסמיכות רבה.... פקודות שמשתמשים בהן בצמידות – למשל – compile + run-test

הריצו את הפקודות הבאות (אחת אחרי השניה):

mkdir temp ; cd temp ; pwd
touch blah; ls -lt
!-2            # run again the command line 
!!             # run again the last command line

מבוא לתיקיות ביוניקס/לינוקס    לרשימת הנושאים

הריצו את הפקודות הבאות, והבינו מה מתרחש:

pwd # show the present work dir
ls
cd .. # cd to parent
pwd
ls home
ls /home
ls /
cd /
ls home
echo ~
ls ~
mkdir ~/temp
cd ~/temp
touch  blah
cd /
echo $USER
ls home/$USER/temp
rm ~/temp/blah       #rm command to remove a file
rmdir ~/temp         #rmdir - command to remove directory
echo $HOME
cd $HOME

איזה פקודה מתבצעת תכל'ס, ואיך ה- SHELL מוצא אותה?    לרשימת הנושאים

  1. Create a directory with the name ~/labs/hello.
  2. Than, create a file hello.c, with the content below (copy-paste).
  3. compile (run gcc, see the command below)
  4. run the program, and run the command listed below.
// hello.c
int main () {
  puts("hello student!!\n");
  return 0;
}
Run the following commands:
gcc hello.c  
# default name for the compiled object is a.out
ls –l
a
./a
which a
which ./a
which gcc
# we run gcc again, this time give it a specific name for the program it creates
gcc hello.c –o print_hello  
ls –l
./print_hello

להריץ את הפקודה מ"כל מקום" - שימוש ב PATH$    לרשימת הנושאים

הריצו את הפקודות הבאות, שבוחנות את ערכו של PATH$ ומשנות אותו

# Examine the current value of $PATH
echo $PATH
# to see the PATH in a clearer way:
echo $PATH | sed s/:/\\n/g

# (just introduced you to some advanced magic... using pipes and the sed command)

# switch to your home dir... you probably cannot run the print_hello program:
cd       # cd with no param takes you home
print_hello

# modify the $PATH
PATH=$PATH:~/labs/hello
print_hello


רשימת פקודות Bash/Linux    לרשימת הנושאים

alias, unalias create or destroy an alias (shortcut for command)
bash, exit start a bash sell, exit the shell
bg, fg, jobs display the jobs which are currently running, send a job to run in the background or the foreground.
cat, head, tail, less, more print a file to the screen (actually to std out). Head - just the head of it (first few lines), tail - just the tail (last few lines). less or more invoke a PAGER which display one screen of the file each time
mkcd, cd create a directory, change CWD
clear clears the terminal screen
cp, ln copy a file, create link (soft or hard) to a file or directory
chmod change the permissions of a file or directory
date display or set the current time or date
diff, sdiff compare two files
du, df report disk space usage - df: of the disk, du: of a file or directory
pushd, popd, dirs push or pop CWD to the stack, dirs - display the stack of directories
echo display/print text to std out
find find a file
gcc, g++, ld compile a file (gcc - C compiler, g++ - C++ compiler. ld - loader
grep display lines of a file which match a given pattern or text
ls list files, i.e. show the files in the specified directory
history display the recent commands (saved in the 'history' of the shell)
make invoke the make program, which act according to a Makefile. typically used to build/compile applications
man, apropos man displays the man page of a command or function or system call, etc. Apropos searches the DB of man pages, and displays command which might be relevant to the pattern (argument)
mv, rename mv - ranames a file or directory, rename - change the names of many files based on some pattern (פקודה מגניבה)
rm, rmdir rm - removes a file, rmdir - removes a directory
printenv display the values of variables
pwd print current working directory
ps, kill prints information about a process. kill - kills a process or sends a signal to a process
source execute a file (script) in the **current** shell. A little bit like include
awk, sed string substitution and manipulation
time display summary of the time it took to run a command (run: time <some-command>
sleep go to sleep for some time
su, sudo su (set user) - Run shell, Change the effective user (user id and group id).
sudo - execute a command as another user.
These commands are often needed/useful when we need to run something as root.
touch change the timestamp of a file. If the file does not exist, create a zero length file
uname print system information, like type and version of OS (try: uname -a)
tar, gzip, gunzip, zcat compress or expand files.
top display load data and the processes which consume pick resources
wget get/download file(s) and possibly directories from URL
which print the path of a command
who print the session and users on this machine (not working well on windows)
whoami print the name of current user
wc 'word count' - counts the lines, words and characters of a file (or output stream)
hexdump useful do display the content of binary (non-ascii) files