Autosave: 2023-03-17 07:41:38

This commit is contained in:
thomasabishop 2023-03-17 07:41:38 +00:00
parent 3717dbe7b0
commit e44db542c2
5 changed files with 124 additions and 14 deletions

View file

@ -0,0 +1,79 @@
---
categories:
- Programming Languages
tags:
- shell
---
# Capturing user input in Bash
We use [read](/Programming_Languages/Shell/Read.md) to gather user input.
## Capturing raw inputs
```bash
# Wait for the input
echo "What is your name?"
read name
# Silently gather the input and proceed (the input won't show up in the terminal)
echo "What is your password?"
read -s pass
# Combine in single line
read -p "What's your favourite animal? " animal
echo name: $name, pass $pass, animal: $animal
```
## Offering a selection
We can use `select` to get the user to choose from a series of options.
```sh
select animal in "bird" "dog" "cow"
do
echo "You selected $animal"
break
done
```
This will present each option as number that can be inputted:
```
1) bird
2) dog
3) cow
#? 1
You selected bird
```
We could make this more robust by using a case statement:
```sh
select animal in "bird" "dog" "cow"
do
case $animal in
bird) echo "Birds like to tweet";;
dog) echo "Dogs like to woof";;
cow) echo "Cows like to moo";;
quit) break;;
*) "I'm not sure what that means"
esac
done
```
## Validating the user inputs
Here we test that the right number of [arguments](/Programming_Languages/Shell/Passing_arguments_and_options_to_Bash_scripts.md) have been passed to the script:
```sh
if (( $#<3 )); then
echo "This command requires three arguments:"a
echo "username, userId, and favouriteNumber"
else
echo "username: $1"
echo "userid: $2"
echo "favourite number: $3"
fi
```

View file

@ -17,4 +17,4 @@ File descriptors are shorthand for `stdin`, `stdout` and `stderr`:
They are typically used when you want to [redirect](/Programming_Languages/Shell/Redirection.md) the output of the standard/input /output/error somewhere, e.g a file or as input to another program. A classic case is `[some_command] > /dev/null 2>&1`
They are all technically "files" which are open and which append themselves to every process that can run in the shell. For any command or program that you run, you will be able to access `0`, `1` and `2` for them. In this way they are similar to variables like [`$0`](/Programming_Languages/Shell/Passing_arguments_to_scripts.md#passing-arguments) and [`$@`](/Programming_Languages/Shell/Passing_arguments_to_scripts.md#passing-arguments). They have a universal meaning within the context of the shell runtime.
They are all technically "files" which are open and which append themselves to every process that can run in the shell. For any command or program that you run, you will be able to access `0`, `1` and `2` for them. In this way they are similar to variables like [`$0`](/Programming_Languages/Shell/Passing_arguments_and_options_to_Bash_scripts.md#passing-arguments) and [`$@`](/Programming_Languages/Shell/Passing_arguments_and_options_to_Bash_scripts.md#passing-arguments). They have a universal meaning within the context of the shell runtime.

View file

@ -27,7 +27,7 @@ echo $expandedRange
## Get all arguments as an array
We can access all the arguments passed to a function using the `$@` syntax we encountered before when [passing arguments to scripts](/Programming_Languages/Shell/Passing_arguments_to_scripts.md). (Here a function is a kind of script in miniature so the process is the same.)
We can access all the arguments passed to a function using the `$@` syntax we encountered before when [passing arguments to scripts](/Programming_Languages/Shell/Passing_arguments_to_Bash_scripts.md). (Here a function is a kind of script in miniature so the process is the same.)
```sh
function numberThings() {

View file

@ -5,13 +5,13 @@ tags:
- shell
---
# Passing arguments to scripts
# Passing arguments and options to Bash scripts
## Relation between commands and programs
Whenever we issue a command in bash we are really running an executable program that is associated with the command. This is why when we create our own bash scripts we must run `chmod` to make them executable. When we issue a command like `./file.sh` we are running an executable program.
Whenever we issue a command in bash we are running an executable program that the command token references. This is why when we create our own bash scripts we must run `chmod` to make them executable. When we issue a command like `./do_something.sh` we are running an executable program.
When we run a program like `cd` or `npm` we dont have to type `./cd.sh` or `./npm.sh`. This is because a reference to the program file is already in our `$PATH`.
When we run a program like `cd` or `npm` we dont have to type `./cd.sh` or `./npm.sh`. This is because a reference to the program file is already in our [`$PATH`](/Programming_Languages/Shell/The_PATH.md).
In the case of `cd`, this is an in-built program and as such it will be sourced from a binary and we have a reference to the binary in path. In the case of `npm`, this is not an in-built program however in order to run it we must already have it in our `PATH`.
@ -58,9 +58,17 @@ Key points:
## Passing options
Options differ from arguments in that they are prepended with `-` and they can be passed in any order. We use the `getops` program to parse options.
Options differ from arguments in that they are prepended with `-` and they can be passed in any order. We use the `getops` program to parse the options that the user inputs with their command.
We can demonstrate this with a script that takes in a username and password as options:
We can demonstrate this with a script that takes in a username and password as options.
We can handle an option-based input like:
```
some-program -u thomas -p password123
```
With the following construct:
```sh
while getopts u:p: option; do
@ -73,12 +81,29 @@ done
echo "user: $user / pass: $pass"
```
With the input `my-option-script.sh -u thomas -p password123` we would get the following returned:
Which returns:
```
user: thomas / pass: password123
```
Here we set up a `while` loop to parse the stdin and store it in the variable `option`. We run this through a case statement and individuate each option, storing them in dedicated local variables via the global `$OPTARG` variable
Here we set up a `while` loop against the `getopts` command to parse the options in the stdin and store each one in a `option`. We run each `option` through a case statement and individuate each one, storing them in dedicated local variables via the global `$OPTARG` variable
Note: using a colon after each option means that the script will expect the given option to have a value.
### The role of the colons
Using a colon after each option means that the script will expect the given option to have a value. If we put a colon _before_ each of the options we expect this will allow us to view any option the user provides in our option handler. This is useful when you are working with very many options, as with a command-line program.
This version demonstrates a more exhaustive use case:
```sh
while getopts :u:p: option; do
case $option in
u) user=$OPTARG;;
p) pass=$OPTARG;;
a) echo "got the 'a' flag";;
b) echo "got the 'b' flag";;
?) echo "Don't know what $OPTARG is!"
esac
done
```

View file

@ -13,11 +13,17 @@ The primary use of `read` is to capture user input from `stdin`. It can also be
## Example of capturing user input
When we use `read` to gather user input, the script will pause until the input is provided.
```bash
$ read var1 var2
$ thomas bishop # user inputs this
$ echo $var2
$ bishop
echo "What is your name?"
read name
echo "What is your password?"
read -s pass
read
```
> If you don't specify variables, `read` will automatically parse using whitespace