-
-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Concept: variables #700
Concept: variables #700
Changes from all commits
e47f06a
ca4b9e8
3053b4a
62458be
a26c1c5
513e878
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# Introduction | ||
# About | ||
|
||
## Shells | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
[ | ||
{ | ||
"description": "Commands and Arguments in the Bash Guide", | ||
"description": "\"Commands and Arguments\" in the Bash Guide", | ||
"url": "https://mywiki.wooledge.org/BashGuide/CommandsAndArguments" | ||
}, | ||
{ | ||
"description": "Shell Operation in the bash manual", | ||
"description": "\"Shell Operation\" in the bash manual", | ||
"url": "https://www.gnu.org/software/bash/manual/bash.html#Shell-Operation" | ||
} | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"authors": [ | ||
"glennj" | ||
], | ||
"contributors": [ | ||
"IsaacG" | ||
], | ||
"blurb": "Learn about variables in bash, and some of the variable expansions." | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# About | ||
|
||
## Variables | ||
|
||
_Variables_ are a place to hold data. | ||
Bash has two kinds of data: strings and arrays. | ||
We'll talk about arrays later. | ||
|
||
You assign a variable like this | ||
```bash | ||
name="value" | ||
``` | ||
|
||
~~~~exercism/note | ||
**Important** -- there must be _no spaces_ around the equal sign! | ||
|
||
When there are spaces, like in this example, | ||
|
||
```bash | ||
x = 10 | ||
``` | ||
|
||
bash is going to call the **command** `x` with the **two arguments** `=` and `10`! | ||
~~~~ | ||
|
||
Variables can also be called _parameters_. | ||
The two terms will be used interchangably in this document. | ||
|
||
Some important parameters used by or set by bash include: | ||
|
||
* `PATH` -- a colon-separated list of directories used to find external commands. | ||
* `IFS` -- the "internal field separator". | ||
We'll see how it's used below. | ||
* `PWD` -- your current working directory. | ||
It will be the same value as the output of the `pwd` command. | ||
* `RANDOM` -- a pseudo-random integer between 0 and 32767. | ||
* `BASH_VERSION` -- the version string of the running instance of bash. | ||
|
||
## Variable Names | ||
|
||
A variable name consists of _uppercase letters, lowercase letters, numbers and underscore_. | ||
It cannot start with a number. | ||
|
||
~~~~exercism/caution | ||
It is best practice to **avoid using ALLCAPS variable names**. | ||
The shell uses this convention for its parameters, and you don't want to accidentally overwrite shell parameters that have special meaning. | ||
For example: [1][1], [2][2], [3][3] | ||
|
||
[1]: https://stackoverflow.com/q/27555060/7552 | ||
[2]: https://stackoverflow.com/q/28310594/7552 | ||
[3]: https://unix.stackexchange.com/q/114596/4667 | ||
~~~~ | ||
|
||
## Parameter Expansion | ||
|
||
You get the value of a parameter with the `$varname` syntax. | ||
|
||
```bash | ||
x=10 | ||
echo "The value of x is $x" | ||
``` | ||
|
||
To prevent the variable name from being confused with surrounding text, you can enclose the variable name in braces. | ||
For example to print the string `10x10` | ||
|
||
```bash | ||
echo "${x}x$x" | ||
# or | ||
echo "${x}x${x}" | ||
``` | ||
|
||
Some [style guides][google-style-guide] recommend using braces in most cases for readability and/or consistency. | ||
|
||
## Positional Parameters | ||
|
||
As we discussed in the [Commands and Arguments][cmds-args] lesson, commands can take arguments. | ||
Bash scripts are no exception. | ||
The arguments to the current instance of bash are called _positional parameters_. | ||
They can be retrieved with these special parameters: | ||
|
||
* `$1` -- the first positional parameter | ||
* `$2` ... `$9` -- subsequent parameters | ||
* `${10}` ... -- double digits require braces. | ||
* `$0` -- the name of the current script. | ||
|
||
Arguments to a shell function are also positional parameters, handled just like this. | ||
We'll see more about functions in a later lesson. | ||
|
||
### Special Positional Parameters | ||
|
||
There are some _special parameters_ that help you work with the positional parameters. | ||
|
||
* `$#` expands to the _number_ of positional parameters. | ||
* `"$@"` expands to the list of all of the positional parameters, each as a separate word. | ||
* `"$*"` expands to a single string of all the positional parameters joined together by a character. | ||
* The join character is _the first character_ of the `$IFS` variable, which is a space by default. | ||
|
||
The `"$@"` is the safest way to pass positional parameters to another command while keeping them safely quoted. | ||
It is also what you will use to loop over the positional parameters: | ||
|
||
```bash | ||
for arg in "$@"; do | ||
do_something_with "$arg" | ||
done | ||
``` | ||
|
||
In practice, `"$@"` is used more often than `"$*"`. | ||
|
||
## Command Substitution | ||
|
||
A very frequent operation you will do in bash scripts is to capture the output of a command and store it in a variable. | ||
To do this, you will use _command substitution_. | ||
|
||
```bash | ||
var=$(command) | ||
``` | ||
|
||
For example, to upper-case a string, you can do this: | ||
|
||
```bash | ||
text="Hello world!" | ||
uppercase=$(echo "$text" | tr '[:lower:]' '[:upper:]') | ||
echo "$uppercase" | ||
# => HELLO WORLD! | ||
``` | ||
|
||
## More on Parameter Expansion | ||
|
||
Bash has many builtin facilities to manipulate variables and strings so that you don't need to call out to external commands. | ||
|
||
* Uppercasing text. | ||
In the previous section I showed how to use `tr` to upper case some text. | ||
To do it in bash: | ||
|
||
```bash | ||
echo "${text^^}" | ||
``` | ||
|
||
Similarly, `${text,,}` lowercases the value. | ||
|
||
* Provide a default value if the variable is empty. | ||
|
||
```bash | ||
default="nothing here" | ||
result="" | ||
echo "${result:-$default}" | ||
# => nothing here | ||
``` | ||
|
||
* Search and replace. | ||
|
||
```bash | ||
text="Hello world!" | ||
echo "${text//[aeiou]/X}" | ||
# => HXllX wXrld!" | ||
``` | ||
|
||
There are many other interesting parameter expansions: extract a substring, get the string length, _assign_ a default value, remove text from the start or end of the value, and more. | ||
Read about them [in the manual][param-exp]. | ||
|
||
|
||
[google-style-guide]: https://google.github.io/styleguide/shellguide.html | ||
[cmds-args]: https://exercism.org/tracks/bash/concepts/commands-and-arguments | ||
[param-exp]: https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
# Introduction | ||
|
||
## Variables | ||
|
||
_Variables_ are a place to hold data. | ||
Bash has two kinds of data: strings and arrays. | ||
We'll talk about arrays later. | ||
|
||
You assign a variable like this | ||
```bash | ||
name="value" | ||
``` | ||
|
||
~~~~exercism/note | ||
**Important** -- there must be _no spaces_ around the equal sign! | ||
|
||
When there are spaces, like in this example, | ||
|
||
```bash | ||
x = 10 | ||
``` | ||
|
||
bash is going to call the **command** `x` with the **two arguments** `=` and `10`! | ||
~~~~ | ||
|
||
Variables can also be called _parameters_. | ||
The two terms will be used interchangably in this document. | ||
|
||
Some important parameters used by or set by bash include: | ||
|
||
* `PATH` -- a colon-separated list of directories used to find external commands. | ||
* `IFS` -- the "internal field separator". | ||
We'll see how it's used below. | ||
* `PWD` -- your current working directory. | ||
glennj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
It will be the same value as the output of the `pwd` command. | ||
* `RANDOM` -- a pseudo-random integer between 0 and 32767. | ||
* `BASH_VERSION` -- the version string of the running instance of bash. | ||
|
||
## Variable Names | ||
|
||
A variable name consists of _uppercase letters, lowercase letters, numbers and underscore_. | ||
It cannot start with a number. | ||
|
||
~~~~exercism/caution | ||
It is best practice to **avoid using ALLCAPS variable names**. | ||
The shell uses this convention for its parameters, and you don't want to accidentally overwrite shell parameters that have special meaning. | ||
For example: [1][1], [2][2], [3][3] | ||
|
||
[1]: https://stackoverflow.com/q/27555060/7552 | ||
[2]: https://stackoverflow.com/q/28310594/7552 | ||
[3]: https://unix.stackexchange.com/q/114596/4667 | ||
~~~~ | ||
|
||
## Parameter Expansion | ||
|
||
You get the value of a parameter with the `$varname` syntax. | ||
glennj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```bash | ||
x=10 | ||
echo "The value of x is $x" | ||
``` | ||
|
||
To prevent the variable name from being confused with surrounding text, you can enclose the variable name in braces. | ||
For example to print the string `10x10` | ||
|
||
```bash | ||
echo "${x}x$x" | ||
# or | ||
echo "${x}x${x}" | ||
``` | ||
|
||
Some [style guides][google-style-guide] recommend using braces in most cases for readability and/or consistency. | ||
|
||
## Positional Parameters | ||
|
||
As we discussed in the [Commands and Arguments][cmds-args] lesson, commands can take arguments. | ||
Bash scripts are no exception. | ||
The arguments to the current instance of bash are called _positional parameters_. | ||
They can be retrieved with these special parameters: | ||
|
||
* `$1` -- the first positional parameter | ||
* `$2` ... `$9` -- subsequent parameters | ||
* `${10}` ... -- double digits require braces. | ||
* `$0` -- the name of the current script. | ||
|
||
Arguments to a shell function are also positional parameters, handled just like this. | ||
We'll see more about functions in a later lesson. | ||
|
||
### Special Positional Parameters | ||
|
||
There are some _special parameters_ that help you work with the positional parameters. | ||
|
||
* `$#` expands to the _number_ of positional parameters. | ||
* `"$@"` expands to the list of all of the positional parameters, each as a separate word. | ||
* `"$*"` expands to a single string of all the positional parameters joined together by a character. | ||
glennj marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* The join character is _the first character_ of the `$IFS` variable, which is a space by default. | ||
|
||
The `"$@"` is the safest way to pass positional parameters to another command while keeping them safely quoted. | ||
It is also what you will use to loop over the positional parameters: | ||
|
||
```bash | ||
for arg in "$@"; do | ||
do_something_with "$arg" | ||
done | ||
``` | ||
|
||
In practice, `"$@"` is used more often than `"$*"`. | ||
|
||
## Command Substitution | ||
|
||
A very frequent operation you will do in bash scripts is to capture the output of a command and store it in a variable. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doc mentions "you" a whole lot and things "you will do". I think the prior doc was a little bit less ...directed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I did lift most of the text from greycat for the last one. Maybe we can "put a pin in it" and revisit it after a few docs are written. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I could modify the factoid messages and/or Wooledge wiki, if that helps :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Upon reflection, I'll circle back to the first concept to give it a rewrite in my voice. |
||
To do this, you will use _command substitution_. | ||
|
||
```bash | ||
var=$(command) | ||
``` | ||
|
||
For example, to upper-case a string, you can do this: | ||
|
||
```bash | ||
text="Hello world!" | ||
uppercase=$(echo "$text" | tr '[:lower:]' '[:upper:]') | ||
echo "$uppercase" | ||
# => HELLO WORLD! | ||
``` | ||
|
||
## More on Parameter Expansion | ||
|
||
Bash has many builtin facilities to manipulate variables and strings so that you don't need to call out to external commands. | ||
|
||
* Uppercasing text. | ||
In the previous section I showed how to use `tr` to upper case some text. | ||
To do it in bash: | ||
|
||
```bash | ||
echo "${text^^}" | ||
``` | ||
|
||
Similarly, `${text,,}` lowercases the value. | ||
|
||
* Provide a default value if the variable is empty. | ||
|
||
```bash | ||
default="nothing here" | ||
result="" | ||
echo "${result:-$default}" | ||
# => nothing here | ||
``` | ||
|
||
* Search and replace. | ||
|
||
```bash | ||
text="Hello world!" | ||
echo "${text//[aeiou]/X}" | ||
# => HXllX wXrld!" | ||
``` | ||
|
||
There are many other interesting parameter expansions: extract a substring, get the string length, _assign_ a default value, remove text from the start or end of the value, and more. | ||
Read about them [in the manual][param-exp]. | ||
|
||
|
||
[google-style-guide]: https://google.github.io/styleguide/shellguide.html | ||
[cmds-args]: https://exercism.org/tracks/bash/concepts/commands-and-arguments | ||
[param-exp]: https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[ | ||
{ | ||
"description": "\"Parameters\" in the Bash Guide", | ||
"url": "https://mywiki.wooledge.org/BashGuide/Parameters" | ||
}, | ||
{ | ||
"description": "\"Shell Parameters\" in the bash manual", | ||
"url": "https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameters" | ||
} | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it often shortened to var? That's news to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I mean, your next line is
varname
and notvariablename
;) Or you can avoid shortening it in the example.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resolved this by using
name="value"
for the example.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For teaching material, regardless, I do prefer using full names, even if it is often shortened in practice. Those that are not "acronyms and abbreviations as a first language" can then easily look up those words in an English dictionary, making interpretation and deciphering easier (especially on top of mult-language audience/readers being highly likely on this platform).