Skip to content
Extraits de code Groupes Projets
Valider 579cf140 rédigé par Pierre-Yves Barriat's avatar Pierre-Yves Barriat
Parcourir les fichiers

Update file Bash.md

parent 01b5e171
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -76,10 +76,6 @@ echo $STRING
---
![h:600](assets/scripting.png)
---
# Bash environment
In a Bash shell many things constitute your environment
......@@ -184,6 +180,12 @@ Your first bash script:
4. make the file executable
5. run it !
<!--
Durée max: 10-15 min
-->
---
# Variables and data types in Bash
......@@ -228,22 +230,23 @@ myvar=$( ls )
## Variable naming conventions
* Variable names **should start** with a letter or an underscore
- Variable names **should start** with a letter or an underscore
* Variable names can contain letters, numbers, and underscores
- Variable names can contain letters, numbers, and underscores
* Variable names are **case-sensitive**
- Variable names are **case-sensitive**
* Variable names **should not** contain spaces or **special characters**
- Variable names **should not** contain spaces or **special characters**
* Use descriptive names that reflect the purpose of the variable
- Use descriptive names that reflect the purpose of the variable
* Avoid using **reserved keywords**, such as `if`, `then`, `else`, `fi`, and so on...
- Avoid using **reserved keywords**, such as `if`, `then`, `else`, `fi`, and so on...
* **Never** name your private variables using only **UPPERCASE** characters to avoid conflicts with builtins
- **Never** name your private variables using only **UPPERCASE** characters to avoid conflicts with builtins
---
<!--
## String manipulation
Consider `string=abcABC123ABCabc`
......@@ -255,20 +258,21 @@ Consider `string=abcABC123ABCabc`
* `${string:(-4)}` or `${string: -4}` is `Cabc`
---
-->
## String manipulation
Consider `filename=/var/log/messages.tar.gz`
* substring removal from left :
* `${filename##/var}` is `/log/messages.tar.gz`
* substring removal from right :
* `${filename%%.gz}` is `/var/log/messages.tar`
- substring removal from left :
- `${filename##/var}` is `/log/messages.tar.gz`
- substring removal from right :
- `${filename%%.gz}` is `/var/log/messages.tar`
You can use `*` to match all characters:
* `${filename%%.*}` is `/var/log/messages`
* `$(filename##*/)` is `messages.tar.gz`
- `${filename%%.*}` is `/var/log/messages`
- `$(filename##*/)` is `messages.tar.gz`
---
......@@ -340,19 +344,19 @@ echo $b # 16
# Conditional statements
Use:
* `if condition; then` to start conditional block
* `else` to start alternative block
* `elif` to start alternative condition block
* `fi` to close conditional block
- `if condition; then` to start conditional block
- `else` to start alternative block
- `elif` to start alternative condition block
- `fi` to close conditional block
The following operaors can be used beween conditions:
* `||` means **OR**
* `&&` mean **AND**
- `||` means **OR**
- `&&` mean **AND**
---
# Conditional exemple
# Conditional example
```bash
#!/bin/bash
......@@ -368,6 +372,12 @@ else
fi
```
<!--
NOTE: réfléchir à la meilleure syntaxe à utiliser ( les ((, les [ ], les [[]] )
-->
---
| Operator | Description |
......@@ -449,12 +459,12 @@ esac
# Hands-on exercise
1. In your `bash_exercises` folder create a new bash file called `exercise_2.sh` and make it executable
2. Ask the user for two numbers smaller than 100 and put them in variables `NUMBER1` and `NUMBER2`
2. Ask the user for two numbers smaller than 100 and put them in variables `number1` and `number2`
> ```bash
> #!/bin/bash
> read NUMBER1
> read NUMBER2
> read number1
> read number2
>```
3. Check if the numbers are smaller than 100
......@@ -536,16 +546,13 @@ Useful for automating repetitive tasks
Basic loop structures in Bash scripting :
* `while` : perform a set of commands while a test is true
* `until` : perform a set of commands until a test is true
* `for` : perform a set of commands for each item in a list
* controlling loops
- `while` : perform a set of commands while a test is true
- `for` : perform a set of commands for each item in a list
* `break` : exit the currently running loop
* `continue` : stop this iteration of the loop and begin the next iteration
- controlling loops
* last loop mechanism : `select` allows you to create a simple menu system
- `break` : exit the currently running loop
- `continue` : stop this iteration of the loop and begin the next iteration
---
......@@ -575,7 +582,7 @@ for word in $words
```
```bash
# range with steps for loop
for value in {10..0..2}
for value in {10..0..-2}
```
```bash
# set of files
......@@ -620,6 +627,13 @@ done
5. Register the end time in `tend`
6. Display the total run time and the total number of letters.
<!--
PY: modifier pour avoir un exemple de 10 mots directement dans le slide
-->
---
# Arguments - Positional Parameters
......@@ -697,6 +711,12 @@ Shells use 3 standard I/O streams
Shell has several **meta-characters** and **control operators**
<!--
Jerome: refaire ces 3 slides
-->
---
# Control operators
......@@ -708,7 +728,8 @@ Shell has several **meta-characters** and **control operators**
| `\|\|` | Execute next command only if command fails |
| `&` | Don't wait for result of command before starting next command |
| `\|` | Use output of command as input for the next command |
| `> file_desc` | Send stdandard output of command to file descriptor |
| `> file_desc` | Send standard output of command to file descriptor |
| `>> file_desc` | Same but in append mode |
| `< file_desc` | Use content of file descriptor as input |
---
......@@ -751,6 +772,11 @@ done < "$input"
> by default `read` removes all leading and trailing whitespace characters such as spaces and tabs
<!--
!!!!!!!!!!!!!!!!!!!!!
REMPLACER cet exemple : a propos de l'entrée standard
`while IFS= read -r line`
The internal field separator (`IFS`) is set to the empty string to preserve whitespace issues
......@@ -764,10 +790,10 @@ The `-r` option is used not to allow backslashes to escape any characters
Linux command returns a status when it terminates normally or abnormally
* every Linux command has an exit status
* the exit status is an integer number
* a command which exits with a **0** status has **succeeded**
* a **non-zero** (1-255) exit status indicates **failure**
- every Linux command has an exit status
- the exit status is an integer number
- a command which exits with a **0** status has **succeeded**
- a **non-zero** (1-255) exit status indicates **failure**
How do I display the exit status of shell command ?
......@@ -797,10 +823,12 @@ command || echo "failed"
command && echo "success" || echo "failed"
```
<!--
```bash
_files="$@"
[[ "$_files" == "" ]] && { echo "Usage: $0 file1.png file2.png"; exit 1; }
```
-->
<!-- Attention utilisatin du [[ ]] pas encore expliqué ? -->
---
......@@ -816,10 +844,10 @@ _files="$@"
# Functions
* "small script within a script" that you may call multiple times
* great way to reuse code
* a function is most reuseable when it performs a single task
* good to put ancillary tasks within functions : logically separate from main code
- "small script within a script" that you may call multiple times
- great way to reuse code
- a function is most reuseable when it performs a single task
- good to put ancillary tasks within functions : logically separate from main code
```bash
#!/bin/bash
......@@ -857,7 +885,7 @@ echo $var
```
---
<!--
## Return Values
Bash functions don’t allow you to return a value when called
......@@ -876,22 +904,11 @@ echo $?
```
---
Return an arbitrary value (different from a return code) from a function :
* Assign the result of the function
```bash
my_function () {
func_result="some result"
}
my_function
echo $func_result
```
<!-- Note JDF: est-ce que la partie ci-dessus est utile ? Autant montrer directement la bonne manière pour moi
-->
* Better way is to send the value to `stdout` using `echo`
# Return an arbitrary value from a function
Assign the result of the function
```bash
my_function () {
......@@ -922,15 +939,24 @@ print_something Mars
# Hands-on exercise
1. Write a script called `exercise_5.sh` expecting **2 arguments**. If not exactly two arguments are provided:
* Echo an error message
* Exit with a non-zero error code
1. Write a script called `exercise_5.sh` expecting **2 arguments**.
2. Write a function taking a **folder path** (e.g `/home/ucl/elic/xxxx`) and an **extension** (e.g `py`) as arguments
3. Use the `ls` command to list the files in the given path having with the given extension. Write this list to a file called `files_found.txt`.
4. Bonus : if there are no files, Exit with a non-zero error code
---
# Subshells
- A subshell is a "child shell" spawned by the main shell ("parent shell")
- A subshell is a **separate** instance of the command process, run as a new process
- **Unlike calling a shell script** (slide before), subshells inherit the **same** variables as the original process
- A subshell allows you to execute commands within a separate shell environment = *Subshell Sandboxing*
> useful to set temporary variables or change directories without affecting the parent shell's environment
- Subshells can be used for **parallel processing**
---
# Shell vs Environment Variables
Consider the script `test.sh` below :
......@@ -950,16 +976,7 @@ bash test.sh
```
> By default, variables from the main interpreter are not available in scripts, unless you `export` them.
---
# Subshells
* A subshell is a "child shell" spawned by the main shell ("parent shell")
* A subshell is a **separate** instance of the command process, run as a new process
* **Unlike calling a shell script** (slide before), subshells inherit the **same** variables as the original process
* A subshell allows you to execute commands within a separate shell environment = *Subshell Sandboxing*
> useful to set temporary variables or change directories without affecting the parent shell's environment
* Subshells can be used for **parallel processing**
<!--
---
......@@ -981,15 +998,14 @@ bash -c "command1; command2; command3"
> Reminder : variables in a subshell are **not** visible outside the block of code in the subshell
-->
---
## Differences between **Sourcing** and **Executing** a script
- source a script = execution **in the current shell**
> variables and functions are valid in the current shell after sourcing even if not `export`ed
- execute a script = execution in a new shell (in a subshell of the current shell)
> all new variables and functions created by the script will only live in the subshell
Source a script using `source` or `.`
......@@ -1006,27 +1022,33 @@ source myScript.sh
```bash
#!/bin/bash
COUNTRY="Belgium"
country="Belgium"
greeting() {
echo "You're in $1"
}
greeting $COUNTRY
greeting $country
```
```bash
COUNTRY="France"
./myScript.sh # or bash or exec
echo $COUNTRY
greeting $COUNTRY # !!
country="France"
./myScript.sh # or bash
echo $country
greeting $country # !!
```
```bash
COUNTRY="France"
country="France"
source myScript.sh
echo $COUNTRY
greeting $COUNTRY
echo $country
greeting $country
```
<!--
!!!!!!!!!!!!!!!! A REDISCUTER
-->
---
# Debug
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter