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 ...@@ -76,10 +76,6 @@ echo $STRING
--- ---
![h:600](assets/scripting.png)
---
# Bash environment # Bash environment
In a Bash shell many things constitute your environment In a Bash shell many things constitute your environment
...@@ -184,6 +180,12 @@ Your first bash script: ...@@ -184,6 +180,12 @@ Your first bash script:
4. make the file executable 4. make the file executable
5. run it ! 5. run it !
<!--
Durée max: 10-15 min
-->
--- ---
# Variables and data types in Bash # Variables and data types in Bash
...@@ -228,22 +230,23 @@ myvar=$( ls ) ...@@ -228,22 +230,23 @@ myvar=$( ls )
## Variable naming conventions ## 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 ## String manipulation
Consider `string=abcABC123ABCabc` Consider `string=abcABC123ABCabc`
...@@ -255,20 +258,21 @@ Consider `string=abcABC123ABCabc` ...@@ -255,20 +258,21 @@ Consider `string=abcABC123ABCabc`
* `${string:(-4)}` or `${string: -4}` is `Cabc` * `${string:(-4)}` or `${string: -4}` is `Cabc`
--- ---
-->
## String manipulation ## String manipulation
Consider `filename=/var/log/messages.tar.gz` Consider `filename=/var/log/messages.tar.gz`
* substring removal from left : - substring removal from left :
* `${filename##/var}` is `/log/messages.tar.gz` - `${filename##/var}` is `/log/messages.tar.gz`
* substring removal from right : - substring removal from right :
* `${filename%%.gz}` is `/var/log/messages.tar` - `${filename%%.gz}` is `/var/log/messages.tar`
You can use `*` to match all characters: You can use `*` to match all characters:
* `${filename%%.*}` is `/var/log/messages` - `${filename%%.*}` is `/var/log/messages`
* `$(filename##*/)` is `messages.tar.gz` - `$(filename##*/)` is `messages.tar.gz`
--- ---
...@@ -340,19 +344,19 @@ echo $b # 16 ...@@ -340,19 +344,19 @@ echo $b # 16
# Conditional statements # Conditional statements
Use: Use:
* `if condition; then` to start conditional block - `if condition; then` to start conditional block
* `else` to start alternative block - `else` to start alternative block
* `elif` to start alternative condition block - `elif` to start alternative condition block
* `fi` to close conditional block - `fi` to close conditional block
The following operaors can be used beween conditions: The following operaors can be used beween conditions:
* `||` means **OR** - `||` means **OR**
* `&&` mean **AND** - `&&` mean **AND**
--- ---
# Conditional exemple # Conditional example
```bash ```bash
#!/bin/bash #!/bin/bash
...@@ -368,6 +372,12 @@ else ...@@ -368,6 +372,12 @@ else
fi fi
``` ```
<!--
NOTE: réfléchir à la meilleure syntaxe à utiliser ( les ((, les [ ], les [[]] )
-->
--- ---
| Operator | Description | | Operator | Description |
...@@ -449,12 +459,12 @@ esac ...@@ -449,12 +459,12 @@ esac
# Hands-on exercise # Hands-on exercise
1. In your `bash_exercises` folder create a new bash file called `exercise_2.sh` and make it executable 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 > ```bash
> #!/bin/bash > #!/bin/bash
> read NUMBER1 > read number1
> read NUMBER2 > read number2
>``` >```
3. Check if the numbers are smaller than 100 3. Check if the numbers are smaller than 100
...@@ -536,16 +546,13 @@ Useful for automating repetitive tasks ...@@ -536,16 +546,13 @@ Useful for automating repetitive tasks
Basic loop structures in Bash scripting : Basic loop structures in Bash scripting :
* `while` : perform a set of commands while a test is true - `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
* `for` : perform a set of commands for each item in a list
* controlling loops
* `break` : exit the currently running loop - controlling loops
* `continue` : stop this iteration of the loop and begin the next iteration
* 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 ...@@ -575,7 +582,7 @@ for word in $words
``` ```
```bash ```bash
# range with steps for loop # range with steps for loop
for value in {10..0..2} for value in {10..0..-2}
``` ```
```bash ```bash
# set of files # set of files
...@@ -620,6 +627,13 @@ done ...@@ -620,6 +627,13 @@ done
5. Register the end time in `tend` 5. Register the end time in `tend`
6. Display the total run time and the total number of letters. 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 # Arguments - Positional Parameters
...@@ -697,6 +711,12 @@ Shells use 3 standard I/O streams ...@@ -697,6 +711,12 @@ Shells use 3 standard I/O streams
Shell has several **meta-characters** and **control operators** Shell has several **meta-characters** and **control operators**
<!--
Jerome: refaire ces 3 slides
-->
--- ---
# Control operators # Control operators
...@@ -708,7 +728,8 @@ Shell has several **meta-characters** and **control operators** ...@@ -708,7 +728,8 @@ Shell has several **meta-characters** and **control operators**
| `\|\|` | Execute next command only if command fails | | `\|\|` | Execute next command only if command fails |
| `&` | Don't wait for result of command before starting next command | | `&` | Don't wait for result of command before starting next command |
| `\|` | Use output of command as input for the 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 | | `< file_desc` | Use content of file descriptor as input |
--- ---
...@@ -751,6 +772,11 @@ done < "$input" ...@@ -751,6 +772,11 @@ done < "$input"
> by default `read` removes all leading and trailing whitespace characters such as spaces and tabs > 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` `while IFS= read -r line`
The internal field separator (`IFS`) is set to the empty string to preserve whitespace issues 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 ...@@ -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 Linux command returns a status when it terminates normally or abnormally
* every Linux command has an exit status - every Linux command has an exit status
* the exit status is an integer number - the exit status is an integer number
* a command which exits with a **0** status has **succeeded** - a command which exits with a **0** status has **succeeded**
* a **non-zero** (1-255) exit status indicates **failure** - a **non-zero** (1-255) exit status indicates **failure**
How do I display the exit status of shell command ? How do I display the exit status of shell command ?
...@@ -797,10 +823,12 @@ command || echo "failed" ...@@ -797,10 +823,12 @@ command || echo "failed"
command && echo "success" || echo "failed" command && echo "success" || echo "failed"
``` ```
<!--
```bash ```bash
_files="$@" _files="$@"
[[ "$_files" == "" ]] && { echo "Usage: $0 file1.png file2.png"; exit 1; } [[ "$_files" == "" ]] && { echo "Usage: $0 file1.png file2.png"; exit 1; }
``` ```
-->
<!-- Attention utilisatin du [[ ]] pas encore expliqué ? --> <!-- Attention utilisatin du [[ ]] pas encore expliqué ? -->
--- ---
...@@ -816,10 +844,10 @@ _files="$@" ...@@ -816,10 +844,10 @@ _files="$@"
# Functions # Functions
* "small script within a script" that you may call multiple times - "small script within a script" that you may call multiple times
* great way to reuse code - great way to reuse code
* a function is most reuseable when it performs a single task - a function is most reuseable when it performs a single task
* good to put ancillary tasks within functions : logically separate from main code - good to put ancillary tasks within functions : logically separate from main code
```bash ```bash
#!/bin/bash #!/bin/bash
...@@ -857,7 +885,7 @@ echo $var ...@@ -857,7 +885,7 @@ echo $var
``` ```
--- ---
<!--
## Return Values ## Return Values
Bash functions don’t allow you to return a value when called Bash functions don’t allow you to return a value when called
...@@ -876,22 +904,11 @@ echo $? ...@@ -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 ```bash
my_function () { my_function () {
...@@ -922,15 +939,24 @@ print_something Mars ...@@ -922,15 +939,24 @@ print_something Mars
# Hands-on exercise # Hands-on exercise
1. Write a script called `exercise_5.sh` expecting **2 arguments**. If not exactly two arguments are provided: 1. Write a script called `exercise_5.sh` expecting **2 arguments**.
* Echo an error message
* Exit with a non-zero error code
2. Write a function taking a **folder path** (e.g `/home/ucl/elic/xxxx`) and an **extension** (e.g `py`) as 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`. 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 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 # Shell vs Environment Variables
Consider the script `test.sh` below : Consider the script `test.sh` below :
...@@ -950,16 +976,7 @@ bash test.sh ...@@ -950,16 +976,7 @@ bash test.sh
``` ```
> By default, variables from the main interpreter are not available in scripts, unless you `export` them. > 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" ...@@ -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 > Reminder : variables in a subshell are **not** visible outside the block of code in the subshell
-->
--- ---
## Differences between **Sourcing** and **Executing** a script ## Differences between **Sourcing** and **Executing** a script
- source a script = execution **in the current shell** - 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) - 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 `.` Source a script using `source` or `.`
...@@ -1006,27 +1022,33 @@ source myScript.sh ...@@ -1006,27 +1022,33 @@ source myScript.sh
```bash ```bash
#!/bin/bash #!/bin/bash
COUNTRY="Belgium" country="Belgium"
greeting() { greeting() {
echo "You're in $1" echo "You're in $1"
} }
greeting $COUNTRY greeting $country
``` ```
```bash ```bash
COUNTRY="France" country="France"
./myScript.sh # or bash or exec ./myScript.sh # or bash
echo $COUNTRY echo $country
greeting $COUNTRY # !! greeting $country # !!
``` ```
```bash ```bash
COUNTRY="France" country="France"
source myScript.sh source myScript.sh
echo $COUNTRY echo $country
greeting $COUNTRY greeting $country
``` ```
<!--
!!!!!!!!!!!!!!!! A REDISCUTER
-->
--- ---
# Debug # 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