Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
quick-refs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Michael Alan Marsh
quick-refs
Commits
0e1de454
Commit
0e1de454
authored
6 years ago
by
Michael Marsh
Browse files
Options
Downloads
Patches
Plain Diff
bash quick-ref
parent
8220f5e8
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
bash.pdf
+0
-0
0 additions, 0 deletions
bash.pdf
bash.txt
+172
-6
172 additions, 6 deletions
bash.txt
with
172 additions
and
6 deletions
bash.pdf
0 → 100644
+
0
−
0
View file @
0e1de454
File added
This diff is collapsed.
Click to expand it.
bash.txt
+
172
−
6
View file @
0e1de454
...
@@ -53,6 +53,27 @@ Now try:
...
@@ -53,6 +53,27 @@ Now try:
The braces give us considerable more control, and some extra features,
The braces give us considerable more control, and some extra features,
as we'll see.
as we'll see.
It is also possible to set variables for a single command. There
are two ways to do this:
/usr/bin/env a=foo my_command
a=foo my_command
Both of these set the variable `a` to the value `foo`, but *only*
for the environment seen by `my_command`. This is used frequently
to override default variables without changing them:
JAVA_HOME=${HOME}/my_java some_java_program
LD_LIBRARY_PATH=${HOME}/build/lib my_c_program
By convention, script-local variables are lowercase, and more global
variables (like HOME) are uppercase.
Subprocesses typically don't get passed the variables you define. To
change this, you need to export the variable:
export PATH
Parameter Expansion
Parameter Expansion
-------------------
-------------------
...
@@ -71,6 +92,16 @@ details and other expansion options.
...
@@ -71,6 +92,16 @@ details and other expansion options.
| | If *s* not provided, remove the pattern |
| | If *s* not provided, remove the pattern |
| | # and % perform prefix and suffix matches |
| | # and % perform prefix and suffix matches |
We can use this in a script along with variable overriding for handling
script inputs symbolically, rather than positionally:
${target:=foo.txt}
grep foobar ${target}
We would call this (assuming it's called "myscript"):
target=/etc/hosts myscript
Quoting
Quoting
-------
-------
...
@@ -99,16 +130,50 @@ Command Execution
...
@@ -99,16 +130,50 @@ Command Execution
There are multiple ways to do this. Consider an executable `foo`:
There are multiple ways to do this. Consider an executable `foo`:
| *Invocation* | *Effect* |
| *Invocation* | *Effect* |
| ------------ | -------- |
| ------------ | -------- |
| `foo` | foo is run as a subprocess normally |
| `foo` | foo is run as a subprocess normally |
| `foo &` | foo is run in the background, as execution continues |
| `foo &` | foo is run in the background, as execution continues |
| `` `foo` `` | foo is run as a subprocess, and its STDOUT is returned |
| `. foo` | foo is run *in the current shell* |
| `$(foo)` | Same as the above |
| `(foo)` | a subshell is started, and foo is run as a subproc of it |
| `` `foo` `` | foo is run as a subprocess, and its STDOUT is returned |
| `$(foo)` | Same as the above |
The last two are equivalent, but the $() form is preferable, because
The last two are equivalent, but the $() form is preferable, because
it is clearer and can be nested.
it is clearer and can be nested.
The dot-execution is useful for snippets of bash code which set
environment variables or define functions. Think of it like an
"include" statement.
The advantage of running in a subshell is that it doesn't impact
the current shell. Here's an example:
for d in * # "*" expands to the contents of the current directory
do
if [ -d $d ] # Test that $d is a directory
then
(cd $d; git pull origin master)
fi
done
If we ran in the parent shell, we would have to make this longer:
cwd=$(pwd)
for d in * # "*" expands to the contents of the current directory
do
if [ -d $d ] # Test that $d is a directory
then
cd $d
git pull origin master
cd $cwd
fi
done
We could use `..` instead of `$cwd`, but then we'd have to worry
about `cd $d` failing. With a subshell, we don't need to worry about
this at all.
Working with Positional Parameters
Working with Positional Parameters
----------------------------------
----------------------------------
...
@@ -346,3 +411,104 @@ Let's combine this for command-line argument parsing:
...
@@ -346,3 +411,104 @@ Let's combine this for command-line argument parsing:
Functions
Functions
---------
---------
Defining a function:
function my_func {
local a=$1
echo $a
}
Functions begin with the `function` keyword, then a name, and then
the body of the function, in curled braces. The `local` keywords
defines a variable in the function's scope. If not used, the variable
will be defined in the global scope, and hence visible outside of
the function. Positional parameters are redefined for the function's
scope.
Once defined, the function behaves like any other command:
my_func "hello"
You can define particularly useful functions in your ~/.bashrc,
which will be executed (using .) whenever you start a new shell.
Aliases
-------
Common one-liners are often nice to put into simple aliases, which
are defined like:
alias ls='ls -FC'
Here are some aliases I find useful:
alias ls='ls -FC'
alias la='ls -A'
alias ll='ls -l'
alias ltr='ls -ltr'
alias lsd='ls -lsd'
These are defined in my ~/.bashrc. There's also a file called either
~/.bash_profile or ~/.profile, which is only run for a login shell
(that is, only once when you first log in). When you modify one of
these files, make sure you re-dot them
. ~/.bashrc
. ~/.bash_profile
. ~/.profile
Scripting
---------
Some principles I live by:
1. If I'm going to do something more than once, I script it.
2. If I do something once, there's a good chance I'm going to have
to do it again.
Most shells, bash included, treat executable text files specially.
Given no other information, they run them as scripts for the current
shell. *Do not assume that file extensions mean anything.* At the
very least, bash does not care about the name of your file, it only
cares about the content. Naming a file `foo.py` does not mean bash
will treat it as a python file, for instance.
To run the script correctly, there's an easy way and a hard way.
The hard way is to call the appropriate interpreter explicitly:
bash my_shell_script.sh
python my_python_script.py
The easy way is to use a convention called *shebang* (short for
"hash-bang"). The shell will look at the first line of an executable
ASCII file. If that line begins with a shebang, the arguments to
that provide the program with which to run the script:
#! /bin/bash
You can even provide options:
#! /bin/bash -x
For python, there's a better way to call it:
#! /usr/bin/env python
What does this do? We're not actually invoking python directly.
Instead, we invoke env, which passes the parent environment. In
particular, this means it's also using the parent shell's $PATH
variable to determine how to find python. This has a couple of
advantages:
* The location of python may vary from installation to installation,
but env's location is always predictable.
* If you use python virtual environments, this will pick up your
virtualenv python.
As a final note, make sure your scripts are executable! See "chmod"
in the filesystems quick-ref for details, but 99 times out of 100,
you will want to run `chmod a+x` on your script. git keeps track
of file permissions in addition to the contents.
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment