├── .gitignore
├── original_source
├── commands
│ ├── start.txt
│ └── builtin
│ │ ├── start.txt
│ │ ├── return.txt
│ │ ├── exit.txt
│ │ ├── readonly.txt
│ │ ├── export.txt
│ │ ├── wait.txt
│ │ ├── cd.txt
│ │ ├── shopt.txt
│ │ ├── local.txt
│ │ ├── trap.txt
│ │ ├── kill.txt
│ │ ├── exec.txt
│ │ ├── caller.txt
│ │ ├── shift.txt
│ │ └── echo.txt
├── syntax
│ ├── start.txt
│ ├── ccmd
│ │ ├── start.txt
│ │ ├── grouping_subshell.txt
│ │ ├── arithmetic_eval.txt
│ │ ├── until_loop.txt
│ │ ├── intro.txt
│ │ ├── while_loop.txt
│ │ ├── grouping_plain.txt
│ │ ├── user_select.txt
│ │ └── if_clause.txt
│ ├── grammar
│ │ └── start.txt
│ └── expansion
│ │ ├── start.txt
│ │ ├── wordsplit.txt
│ │ ├── arith.txt
│ │ ├── tilde.txt
│ │ └── intro.txt
├── howto
│ ├── start.txt
│ ├── testing-your-scripts.txt
│ └── collapsing_functions.txt
├── scripting
│ ├── tutoriallist.txt
│ └── tutoriallist
│ │ └── bashguide.txt
├── user
│ ├── start.txt
│ └── thebonsai
│ │ └── imprint.txt
├── dict
│ └── terms
│ │ ├── symlink.txt
│ │ ├── special_file.txt
│ │ ├── posix.txt
│ │ ├── directory.txt
│ │ ├── filetimes.txt
│ │ ├── shell.txt
│ │ ├── file.txt
│ │ ├── globbing.txt
│ │ ├── interpreter_directive.txt
│ │ ├── end_of_options.txt
│ │ ├── hardlink.txt
│ │ └── parameter.txt
├── snipplets
│ ├── pause_command.txt
│ ├── filesize.txt
│ ├── start.txt
│ ├── ssh_local_var.txt
│ ├── screen_saverestore.txt
│ ├── ssh_fetchkeys.txt
│ ├── xclip.txt
│ ├── awkcsv.txt
│ ├── prargs.txt
│ ├── largestfile.txt
│ ├── kill_bg_job_without_message.txt
│ ├── wrapperargs.txt
│ └── add_color_to_your_scripts.txt
├── snipplet.txt
├── misc
│ ├── shell_humor.txt
│ └── readthesourceluke.txt
├── meta
│ └── need_love.txt
└── wishes.txt
├── requirements.txt
├── docs
├── tags.md
├── dict
│ ├── symlink.md
│ ├── special_file.md
│ ├── posix.md
│ ├── directory.md
│ ├── filetimes.md
│ ├── shell.md
│ ├── file.md
│ ├── globbing.md
│ ├── interpreter_directive.md
│ ├── end_of_options.md
│ ├── hardlink.md
│ └── parameter.md
├── snipplets
│ ├── index.md
│ ├── filesize.md
│ ├── pause_command.md
│ ├── ssh_local_var.md
│ ├── screen_saverestore.md
│ ├── ssh_fetchkeys.md
│ ├── xclip.md
│ ├── awkcsv.md
│ ├── prargs.md
│ ├── largestfile.md
│ ├── kill_bg_job_without_message.md
│ ├── wrapperargs.md
│ └── add_color_to_your_scripts.md
├── commands
│ └── builtin
│ │ ├── return.md
│ │ ├── exit.md
│ │ ├── readonly.md
│ │ ├── export.md
│ │ ├── wait.md
│ │ ├── shopt.md
│ │ ├── cd.md
│ │ ├── kill.md
│ │ ├── trap.md
│ │ ├── local.md
│ │ ├── exec.md
│ │ ├── caller.md
│ │ ├── shift.md
│ │ └── echo.md
├── syntax
│ ├── ccmd
│ │ ├── grouping_subshell.md
│ │ ├── arithmetic_eval.md
│ │ ├── until_loop.md
│ │ ├── intro.md
│ │ ├── while_loop.md
│ │ ├── user_select.md
│ │ ├── grouping_plain.md
│ │ └── if_clause.md
│ └── expansion
│ │ ├── wordsplit.md
│ │ ├── arith.md
│ │ ├── tilde.md
│ │ └── intro.md
├── misc
│ ├── shell_humor.md
│ ├── readthesourceluke.md
│ └── bashphorisms.md
└── howto
│ ├── testing-your-scripts.md
│ └── collapsing_functions.md
├── .editorconfig
├── .github
└── workflows
│ └── deploy.yml
├── scripts
└── generate-diff-links.sh
├── overrides
└── partials
│ └── comments.html
├── mkdocs.yml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | site
2 | env
--------------------------------------------------------------------------------
/original_source/commands/start.txt:
--------------------------------------------------------------------------------
1 | ====== Commands ======
2 |
3 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/start.txt:
--------------------------------------------------------------------------------
1 | ====== Builtin Commands ======
2 |
--------------------------------------------------------------------------------
/original_source/syntax/start.txt:
--------------------------------------------------------------------------------
1 | ====== Syntax ======
2 |
3 | {{indexmenu>:syntax#10#sort+title}}
--------------------------------------------------------------------------------
/original_source/howto/start.txt:
--------------------------------------------------------------------------------
1 | ====== HOWTO ======
2 |
3 |
4 | {{indexmenu>:howto#10#sort+title}}
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/start.txt:
--------------------------------------------------------------------------------
1 | ====== Compound Commands ======
2 |
3 | {{indexmenu>:syntax:ccmd#10#sort+title}}
4 |
--------------------------------------------------------------------------------
/original_source/syntax/grammar/start.txt:
--------------------------------------------------------------------------------
1 | ====== Syntax: Grammar ======
2 |
3 | {{indexmenu>:syntax:grammar#10#sort+title}}
4 |
5 |
--------------------------------------------------------------------------------
/original_source/syntax/expansion/start.txt:
--------------------------------------------------------------------------------
1 | ====== Syntax: Expansions ======
2 |
3 | {{indexmenu>:syntax:expansion#10#sort+title}}
4 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | mkdocs-material
2 | mkdocs-git-revision-date-localized-plugin
3 | mkdocs-awesome-pages-plugin
4 | mkdocs-minify-plugin
5 |
--------------------------------------------------------------------------------
/docs/tags.md:
--------------------------------------------------------------------------------
1 | ---
2 | hide: [navigation]
3 | ---
4 |
5 | # Tags
6 |
7 | Following is a list of all existing tags:
8 |
9 | [TAGS]
10 |
--------------------------------------------------------------------------------
/original_source/scripting/tutoriallist.txt:
--------------------------------------------------------------------------------
1 | IntelliMindz offers [[Ansys Training in Chennai]https://intellimindz.com/ansys-training-in-chennai/] to help users learn and use this tool effectively. Our course content is from “Getting Started Courses” to deep diving into learning topics. IntelliMindz Ansys Training in Chennai will validate the knowledge and skills needed to work with all Ansys tools. Enroll Now!!! to explore more concepts in it.
--------------------------------------------------------------------------------
/original_source/user/start.txt:
--------------------------------------------------------------------------------
1 | Best PHP Training Institute in Chennai
2 |
3 | https://intellimindz.com/php-training-in-chennai/
4 |
5 | If you are looking for the best PHP training institute, look no further than Intellimindz in Chennai. The best PHP training in Chennai with highly qualified and experienced trainers. Our PHP courses are designed in such a way that trainees can understand each concept instantly. Call us at 09655877677 to schedule a free DEMO now.
6 |
7 |
--------------------------------------------------------------------------------
/docs/dict/symlink.md:
--------------------------------------------------------------------------------
1 | # Symlink
2 |
3 | A symlink (symbolic link) is a \"normal\" file, which contains a pointer
4 | to another filename. Since it really only points to another **filename**
5 | it can
6 |
7 | - reference filenames on other filesystems
8 | - reference filenames that don't actually exist
9 | - save a reference to the name of a directory
10 |
11 | ## See also
12 |
13 | - [hardlink](../dict/hardlink.md)
14 | - [directory](../dict/directory.md)
15 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # https://editorconfig.org/
4 |
5 |
6 | root = true
7 |
8 | [*]
9 | indent_style = space
10 | indent_size = 2
11 |
12 | end_of_line = lf
13 | charset = utf-8
14 | trim_trailing_whitespace = true
15 | insert_final_newline = true
16 | max_line_length = 100
17 |
18 | [*.md]
19 | trim_trailing_whitespace = false
20 |
21 | [*.{conf,html,py}]
22 | indent_size = 4
23 |
--------------------------------------------------------------------------------
/docs/snipplets/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - bash
4 | - shell
5 | - scripting
6 | - code
7 | - download
8 | - snipplet
9 | - example
10 | ---
11 |
12 | # Small code snipplets
13 |
14 | These snipplets are **not** meant as HowTo or Tutorial or FAQ.
15 | Mostly they are only a line of code and a short comment.
16 |
17 | See it more like an initial idea to give you a start.
18 |
19 |
24 |
--------------------------------------------------------------------------------
/original_source/dict/terms/symlink.txt:
--------------------------------------------------------------------------------
1 | ====== Symlink ======
2 |
3 | A symlink (symbolic link) is a "normal" file, which contains a pointer to another filename. Since it really only points to another **filename** it can
4 | * reference filenames on other filesystems
5 | * reference filenames that don't actually exist
6 | * save a reference to the name of a directory
7 |
8 | ===== See also =====
9 | * [[dict:terms:hardlink | hardlink]]
10 | * [[dict:terms:filesystem | filesystem]]
11 | * [[dict:terms:directory | directory]]
12 |
--------------------------------------------------------------------------------
/docs/dict/special_file.md:
--------------------------------------------------------------------------------
1 | # Special file
2 |
3 | Unlike a regular file (a bunch of accessible data organized on a
4 | filesystem), it's a special filename that points to a ressource or
5 | similar:
6 |
7 | - character special files
8 | - block special files
9 | - named pipes
10 | - socket files
11 |
12 | Since a directory also is only a file, you can count it as special file,
13 | too.
14 |
15 | ## See also
16 |
17 | - [file](../dict/file.md)
18 | - [filename](../dict/hardlink.md)
19 | - [directory](../dict/directory.md)
20 |
--------------------------------------------------------------------------------
/original_source/dict/terms/special_file.txt:
--------------------------------------------------------------------------------
1 | ====== Special file ======
2 |
3 | Unlike a regular file (a bunch of accessible data organized on a filesystem), it's a special filename that points to a ressource or similar:
4 | * character special files
5 | * block special files
6 | * named pipes
7 | * socket files
8 | Since a directory also is only a file, you can count it as special file, too.
9 |
10 | ===== See also =====
11 | * [[dict:terms:file | file]]
12 | * [[dict:terms:hardlink | filename]]
13 | * [[dict:terms:directory | directory]]
--------------------------------------------------------------------------------
/original_source/snipplets/pause_command.txt:
--------------------------------------------------------------------------------
1 | ====== Pausing a script (like MSDOS pause command) ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: terminal, pause, input
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Jan Schampera
7 | type: snipplet
8 | ----
9 |
10 | From the [[commands:builtin:read#examples|example section of the read command]], something that acts similar to the MSDOS ''pause'' command:
11 |
12 |
13 | pause() {
14 | local dummy
15 | read -s -r -p "Press any key to continue..." -n 1 dummy
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/original_source/scripting/tutoriallist/bashguide.txt:
--------------------------------------------------------------------------------
1 | ====== Bash guide on Greg's wiki ======
2 |
3 | ---- dataentry tutorial ----
4 | type : tutorial
5 | title : Bash guide on Greg's wiki
6 | website_urls : http://wooledge.org:8000/BashGuide
7 | contact : Lhunath
8 | recindex : 90
9 | ----
10 |
11 | ===== Details =====
12 |
13 | This guide teaches modern stuff and good practises. I recommend to learn from it. It was written by the guys in #bashIRC channel on Freenode (mainly lhunath), because there are so many bad tutorials out there.
--------------------------------------------------------------------------------
/original_source/snipplets/filesize.txt:
--------------------------------------------------------------------------------
1 | ====== Show size of a file ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: files, file size
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Frank Lazzarini
7 | type: snipplet
8 | ----
9 |
10 | This is a simple snippet to echo the size of a file in bytes.
11 |
12 |
13 | #!/bin/bash
14 | FILENAME=/home/heiko/dummy/packages.txt
15 | FILESIZE=$(wc -c < "$FILENAME")
16 | # non standard way (GNU stat): FILESIZE=$(stat -c%s "$FILENAME")
17 |
18 | echo "Size of $FILENAME = $FILESIZE bytes."
19 |
20 |
--------------------------------------------------------------------------------
/docs/dict/posix.md:
--------------------------------------------------------------------------------
1 | # POSIX
2 |
3 | POSIX(r) is a family of standards defined by the IEEE to give a minimum
4 | API and interface standardization across the variants of UNIX(r)
5 | operating systems.
6 |
7 | One part of it is the standardization of minimum functionality and
8 | behaviour of the system shell and some utilities (commands).
9 |
10 | - UNIX is a registered trademark of The Open Group in the US and other
11 | countries.
12 | - POSIX is a registered trademark of the IEEE Inc.
13 |
14 | ## See also
15 |
16 | - Dictionary, internal: [shell](../dict/shell.md)
17 |
--------------------------------------------------------------------------------
/docs/snipplets/filesize.md:
--------------------------------------------------------------------------------
1 | # Show size of a file
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: files, file size
4 | LastUpdate_dt: 2010-07-31 Contributors: Frank Lazzarini type: snipplet
5 |
6 | ------------------------------------------------------------------------
7 |
8 | This is a simple snippet to echo the size of a file in bytes.
9 |
10 | #!/bin/bash
11 | FILENAME=/home/heiko/dummy/packages.txt
12 | FILESIZE=$(wc -c < "$FILENAME")
13 | # non standard way (GNU stat): FILESIZE=$(stat -c%s "$FILENAME")
14 |
15 | echo "Size of $FILENAME = $FILESIZE bytes."
16 |
--------------------------------------------------------------------------------
/docs/snipplets/pause_command.md:
--------------------------------------------------------------------------------
1 | # Pausing a script (like MSDOS pause command)
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: terminal, pause, input
4 | LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera type: snipplet
5 |
6 | ------------------------------------------------------------------------
7 |
8 | From the [example section of the read
9 | command](../commands/builtin/read.md#examples), something that acts similar
10 | to the MSDOS `pause` command:
11 |
12 | pause() {
13 | local dummy
14 | read -s -r -p "Press any key to continue..." -n 1 dummy
15 | }
16 |
--------------------------------------------------------------------------------
/original_source/dict/terms/posix.txt:
--------------------------------------------------------------------------------
1 | ====== POSIX ======
2 |
3 | POSIX(r) is a family of standards defined by the IEEE to give a minimum API and interface standardization across the variants of UNIX(r) operating systems.
4 |
5 | One part of it is the standardization of minimum functionality and behaviour of the system shell and some utilities (commands).
6 |
7 | * UNIX is a registered trademark of The Open Group in the US and other countries.
8 | * POSIX is a registered trademark of the IEEE Inc.
9 |
10 | ===== See also =====
11 | * Dictionary, internal: [[dict:terms:shell]]
12 |
13 |
--------------------------------------------------------------------------------
/docs/dict/directory.md:
--------------------------------------------------------------------------------
1 | # Directory
2 |
3 | In terms of UNIX(r), a directory is a special file which contains a list
4 | of [hardlinks](../dict/hardlink.md) to other files. These other files
5 | also can be directories of course, so it's possible to create a
6 | \"hierarchy of directories\" - the UNIX(r)-typical filesystem structure.
7 |
8 | The structure begins at the special directory `/` (root directory) and
9 | all other directory entries are **subdirectories** of it.
10 |
11 | ## See also
12 |
13 | - [hardlink](../dict/hardlink.md)
14 | - [file](../dict/file.md)
15 | - [special file](../dict/special_file.md)
16 |
--------------------------------------------------------------------------------
/original_source/dict/terms/directory.txt:
--------------------------------------------------------------------------------
1 | ====== Directory ======
2 |
3 | In terms of UNIX(r), a directory is a special file which contains a list of [[dict:terms:hardlink | hardlinks]] to other files. These other files also can be directories of course, so it's possible to create a "hierarchy of directories" - the UNIX(r)-typical filesystem structure.
4 |
5 | The structure begins at the special directory ''/'' (root directory) and all other directory entries are **subdirectories** of it.
6 |
7 |
8 | ===== See also =====
9 | * [[dict:terms:hardlink | hardlink]]
10 | * [[dict:terms:file | file]]
11 | * [[dict:terms:special_file | special file]]
12 |
--------------------------------------------------------------------------------
/docs/dict/filetimes.md:
--------------------------------------------------------------------------------
1 | # File timestamp
2 |
3 | ## atime
4 |
5 | This timestamp indicates when a file was last accessed (read). `cat`ing
6 | a file or executing a shellscript will set it, for example.
7 |
8 | ## ctime
9 |
10 | This timestamp is set, whenever the metadata of a file (stored in the
11 | responsible inode) is set. The metadata includes for example:
12 |
13 | - file name
14 | - fize size
15 | - file mode (permissions)
16 |
17 | and some other things. `ctime` will also be updated when a file is
18 | written to (when `mtime` is updated.
19 |
20 | ## mtime
21 |
22 | The mtime is set, whenever a file's contents are changed, for example
23 | by editing a file.
24 |
--------------------------------------------------------------------------------
/original_source/snipplet.txt:
--------------------------------------------------------------------------------
1 | ~~NOTOC~~
2 | ~~DISCUSSION:off~~
3 |
4 | ====== Small code snipplets ======
5 |
6 | {{keywords>bash shell scripting code download snipplet example}}
7 |
8 | These snipplets are **not** meant as HowTo or Tutorial or FAQ. Mostly they are only a line of code and a short comment.
9 |
10 | See it more like an initial idea to give you a start.
11 |
12 | ===== List of snipplets =====
13 |
14 | * [[snipplets:start|reset filter]]
15 |
16 | ---- datacloud snipplet ----
17 | field: snipplet_tags
18 | ----
19 |
20 |
21 | ---- datatable snipplet ----
22 | cols : %pageid%, LastUpdate_dt
23 | headers : Snipplet, Last updated
24 | sort : %pageid%
25 | ----
26 |
--------------------------------------------------------------------------------
/original_source/dict/terms/filetimes.txt:
--------------------------------------------------------------------------------
1 | ====== File timestamp ======
2 |
3 | ===== atime =====
4 | This timestamp indicates when a file was last accessed (read). ''cat''ing a file or executing a shellscript will set it, for example.
5 |
6 |
7 |
8 | ===== ctime =====
9 | This timestamp is set, whenever the metadata of a file (stored in the responsible inode) is set. The metadata includes for example:
10 | * file name
11 | * fize size
12 | * file mode (permissions)
13 | and some other things. ''ctime'' will also be updated when a file is written to (when ''mtime'' is updated.
14 |
15 | ===== mtime =====
16 | The mtime is set, whenever a file's contents are changed, for example by editing a file.
17 |
18 |
--------------------------------------------------------------------------------
/original_source/dict/terms/shell.txt:
--------------------------------------------------------------------------------
1 | ====== Shell ======
2 |
3 | On UNIX(r), the shell is the main interaction tool between the user-level and the system. That doesn't necessarily mean the user always sits infront of a shell, but it's integral part of the system, not only an "optional commandline interpreter".
4 |
5 | The main job of a shell is to execute commands as a user requests them. This behaviour alone doesn't help much. A shell knits some intelligence and flow control around the possibility to execute commands - it's a complete commandline-oriented user-interface (UI).
6 |
7 | FIXME
8 |
9 | ===== See also =====
10 |
11 | ===== See also (external) =====
12 | * Wikipedia: [[http://en.wikipedia.org/wiki/Unix_shell | UNIX shell]]
--------------------------------------------------------------------------------
/original_source/snipplets/start.txt:
--------------------------------------------------------------------------------
1 | ~~NOTOC~~
2 | ~~DISCUSSION:off~~
3 |
4 | ====== Small code snippets ======
5 |
6 | {{keywords>bash shell scripting code download snippet example}}
7 |
8 | These snippets are **not** meant as HowTo or Tutorial or FAQ. Mostly they are only a line of code and a short comment.
9 |
10 | See them more as an initial idea or starting point rather than a tutorial.
11 |
12 | ===== List of snippets =====
13 |
14 | [[snipplets:start|reset filter]]
15 |
16 | ---- datacloud snippet ----
17 | field: snipplet_tags
18 | ----
19 |
20 |
21 | ---- datatable snippet ----
22 | cols : %pageid%, LastUpdate_dt
23 | headers : Snipplet, Last updated
24 | sort : %pageid%
25 | filter : type=snipplet
26 | ----
27 |
--------------------------------------------------------------------------------
/original_source/snipplets/ssh_local_var.txt:
--------------------------------------------------------------------------------
1 | ====== Run some bash commands with SSH remotely using local variables ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: ssh, variables
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: cweiss
7 | type: snipplet
8 | ----
9 |
10 | In this example, we want to make sure a certain file exists on the remote server:
11 |
12 |
13 | file=/tmp/file.log
14 | ssh ${options} ${login} "if [ ! -e '$file' ] ; then touch '$file' ; fi"
15 |
16 |
17 | Notice the command is surrounded by double quotes, and the $file variable is surrounded by single quotes. That has the effect to be wordsplit-proof in the local shell (due to the double-quotes) and in the remote shell (due to the single-quotes).
18 |
19 |
--------------------------------------------------------------------------------
/docs/dict/shell.md:
--------------------------------------------------------------------------------
1 | # Shell
2 |
3 | On UNIX(r), the shell is the main interaction tool between the
4 | user-level and the system. That doesn't necessarily mean the user
5 | always sits infront of a shell, but it's integral part of the system,
6 | not only an \"optional commandline interpreter\".
7 |
8 | The main job of a shell is to execute commands as a user requests them.
9 | This behaviour alone doesn't help much. A shell knits some intelligence
10 | and flow control around the possibility to execute commands - it's a
11 | complete commandline-oriented user-interface (UI).
12 |
13 | !!! warning "FIXME"
14 | tbd.
15 |
16 | ## See also
17 |
18 | ## See also (external)
19 |
20 | - Wikipedia: [UNIX shell](http://en.wikipedia.org/wiki/Unix_shell)
21 |
--------------------------------------------------------------------------------
/docs/dict/file.md:
--------------------------------------------------------------------------------
1 | # File
2 |
3 | A file is a pool of data in the `filesystem`. On
4 | userlevel, it's referenced using a name, a
5 | [hardlink](hardlink.md) to the file.
6 |
7 | If a file is not referenced anymore (number of hardlinks to it drops to
8 | 1) then the space allocated for that file is re-used, unless it's still
9 | used by some process.
10 |
11 | The file-data splits into actual payload (file contents) and some
12 | metadata like filesize, filemode or timestamps. The metadata is stored
13 | in the `inode`.
14 |
15 | Strictly spoken, a [hardlink](hardlink.md) (also called
16 | \"filename\") points to the `inode` which organizes a
17 | file, not to the file itself.
18 |
19 | ## See also
20 |
21 | - [filetimes](filetimes.md)
22 | - [hardlink](hardlink.md)
23 |
--------------------------------------------------------------------------------
/docs/snipplets/ssh_local_var.md:
--------------------------------------------------------------------------------
1 | # Run some bash commands with SSH remotely using local variables
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: ssh, variables
4 | LastUpdate_dt: 2010-07-31 Contributors: cweiss type: snipplet
5 |
6 | ------------------------------------------------------------------------
7 |
8 | In this example, we want to make sure a certain file exists on the
9 | remote server:
10 |
11 | file=/tmp/file.log
12 | ssh ${options} ${login} "if [ ! -e '$file' ] ; then touch '$file' ; fi"
13 |
14 | Notice the command is surrounded by double quotes, and the \$file
15 | variable is surrounded by single quotes. That has the effect to be
16 | wordsplit-proof in the local shell (due to the double-quotes) and in the
17 | remote shell (due to the single-quotes).
18 |
--------------------------------------------------------------------------------
/original_source/snipplets/screen_saverestore.txt:
--------------------------------------------------------------------------------
1 | ====== Save and restore terminal/screen content ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: terminal, restore screen
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Greg Wooledge
7 | type: snipplet
8 | ----
9 |
10 | This cool hack uses the terminal capabilities (see ''terminfo(5)'' manual) **smcup** and **rmcup** to save and restore the terminal content.
11 |
12 |
13 | For sure, you’ve already seen those programs that restore the terminal contents after they did their work (like ''vim'').
14 |
15 |
16 | # save, clear screen
17 | tput smcup
18 | clear
19 |
20 | # example "application" follows...
21 | read -n1 -p "Press any key to continue..."
22 | # example "application" ends here
23 |
24 | # restore
25 | tput rmcup
26 |
27 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Build and deploy to GitHub Pages
2 | on:
3 | workflow_dispatch:
4 | push:
5 | branches:
6 | - main
7 | permissions:
8 | contents: write
9 | jobs:
10 | deploy:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v3
14 | - uses: actions/setup-python@v4
15 | with:
16 | python-version: 3.x
17 | - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
18 | - uses: actions/cache@v3
19 | with:
20 | key: mkdocs-material-${{ env.cache_id }}
21 | path: .cache
22 | restore-keys: |
23 | mkdocs-material-
24 | - run: pip install mkdocs-material mkdocs-git-revision-date-localized-plugin mkdocs-awesome-pages-plugin mkdocs-minify-plugin
25 | - run: mkdocs gh-deploy --force
26 |
--------------------------------------------------------------------------------
/docs/snipplets/screen_saverestore.md:
--------------------------------------------------------------------------------
1 | # Save and restore terminal/screen content
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: terminal, restore
4 | screen LastUpdate_dt: 2010-07-31 Contributors: Greg Wooledge type:
5 | snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | This cool hack uses the terminal capabilities (see `terminfo(5)` manual)
10 | **smcup** and **rmcup** to save and restore the terminal content.
11 |
12 | For sure, you've already seen those programs that restore the terminal
13 | contents after they did their work (like `vim`).
14 |
15 | # save, clear screen
16 | tput smcup
17 | clear
18 |
19 | # example "application" follows...
20 | read -n1 -p "Press any key to continue..."
21 | # example "application" ends here
22 |
23 | # restore
24 | tput rmcup
25 |
--------------------------------------------------------------------------------
/docs/commands/builtin/return.md:
--------------------------------------------------------------------------------
1 | # The return builtin command
2 |
3 | ## Synopsis
4 |
5 | return [N]
6 |
7 | ## Description
8 |
9 | The `return` command returns from a shell function.
10 |
11 | If `N` is given, the return code to the caller is set to `N`. If not,
12 | the returned status the the status of the most recently executed command
13 | (i.e. `$?`).
14 |
15 | ### Options
16 |
17 | There are no options.
18 |
19 | ### Exit status
20 |
21 | If everything is okay, the `return` command doesn't come back. If it
22 | comes back, there was a problem in doing the return.
23 |
24 | |Status|Reason|
25 | |-|-|
26 | |1|`return` was called while not being in a shell function or sourced file|
27 |
28 | ## Examples
29 |
30 | ## Portability considerations
31 |
32 | ## See also
33 |
34 | - [The exit builtin command](../../commands/builtin/exit.md)
35 | - [The exit status](../../dict/exit_status.md)
36 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/grouping_subshell.md:
--------------------------------------------------------------------------------
1 | # Grouping commands in a subshell
2 |
3 | ## Synopsis
4 |
5 | ( )
6 |
7 | ## Description
8 |
9 | The [list](../../syntax/basicgrammar.md#lists) `` is executed in a
10 | separate shell - a subprocess. No changes to the environment (variables
11 | etc...) are reflected in the "main shell".
12 |
13 | ## Examples
14 |
15 | Execute a command in a different directory.
16 |
17 | ``` bash
18 | echo "$PWD"
19 | ( cd /usr; echo "$PWD" )
20 | echo "$PWD" # Still in the original directory.
21 | ```
22 |
23 | ## Portability considerations
24 |
25 | - The subshell compound command is specified by POSIX.
26 | - Avoid ambiguous syntax.
27 |
28 | ``` bash
29 | (((1+1))) # Equivalent to: (( (1+1) ))
30 | ```
31 |
32 | ## See also
33 |
34 | - [grouping commands](../../syntax/ccmd/grouping_plain.md)
35 | - [Subshells on Greycat's wiki](http://mywiki.wooledge.org/SubShell)
36 |
--------------------------------------------------------------------------------
/original_source/dict/terms/file.txt:
--------------------------------------------------------------------------------
1 | ====== File ======
2 |
3 | A file is a pool of data in the [[dict:terms:filesystem | filesystem]]. On userlevel, it's referenced using a name, a [[dict:terms:hardlink | hardlink]] to the file.
4 |
5 | If a file is not referenced anymore (number of hardlinks to it drops to 0) then the space allocated for that file is re-used, unless it's still used by some process.
6 |
7 | The file-data splits into actual payload (file contents) and some metadata like filesize, filemode or timestamps. The metadata is stored in the [[dict:terms:inode | inode]].
8 |
9 | Strictly spoken, a [[dict:terms:hardlink | hardlink]] (also called "filename") points to the [[dict:terms:inode | inode]] which organizes a file, not to the file itself.
10 |
11 |
12 | ===== See also =====
13 | * [[dict:terms:filesystem | filesystem]]
14 | * [[dict:terms:filetimes | filetimes]]
15 | * [[dict:terms:hardlink | hardlink]]
16 | * [[dict:terms:inode | inode]]
17 |
--------------------------------------------------------------------------------
/scripts/generate-diff-links.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -o errexit
4 | set -o nounset
5 |
6 | GIT_HASH="${1:-50aeb31ff80e7bdde9b8edd50ab924e3791fe606}"
7 |
8 | BASE_LOCAL_URL="http://127.0.0.1:8000/bash-hackers-wiki/"
9 | BASE_DEPLOY_URL="https://flokoe.github.io/bash-hackers-wiki/"
10 | BASE_ARCHIVE_URL="https://web.archive.org/web/20230127020427/https://wiki.bash-hackers.org/"
11 |
12 | # Table Headers
13 | cat << EOF
14 | |Filename|Local Version|Deployed Version|Archive Version|
15 | |--|--|--|--|
16 | EOF
17 |
18 | for file in $(git show --name-only "${GIT_HASH}" | grep md$); do
19 | filename_no_docs_prefix="${file#*docs/}"
20 | filename_no_ext="${filename_no_docs_prefix%.*}"
21 | echo "|"${filename_no_docs_prefix} \
22 | "|[${filename_no_ext}](${BASE_LOCAL_URL}${filename_no_ext})" \
23 | "|[${filename_no_ext}](${BASE_DEPLOY_URL}${filename_no_ext})" \
24 | "|[${filename_no_ext}](${BASE_ARCHIVE_URL}${filename_no_ext})|"
25 | done
26 |
27 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/return.txt:
--------------------------------------------------------------------------------
1 | ====== The return builtin command ======
2 |
3 | ===== Synopsis =====
4 | return [N]
5 |
6 | ===== Description =====
7 | The ''return'' command returns from a shell function.
8 |
9 | If ''N'' is given, the return code to the caller is set to ''N''. If not, the returned status the the status of the most recently executed command (i.e. ''$?'').
10 |
11 | ==== Options ====
12 | There are no options.
13 |
14 |
15 | ==== Exit status ====
16 |
17 | If everything is okay, the ''return'' command doesn't come back. If it comes back, there was a problem in doing the return.
18 |
19 | ^Status ^Reason ^
20 | |1 |''return'' was called while not being in a shell function or sourced file |
21 |
22 |
23 | ===== Examples =====
24 |
25 |
26 | ===== Portability considerations =====
27 |
28 | ===== See also =====
29 | * [[commands:builtin:exit|The exit builtin command]]
30 | * [[dict:terms:exit_status|The exit status]]
31 |
--------------------------------------------------------------------------------
/original_source/snipplets/ssh_fetchkeys.txt:
--------------------------------------------------------------------------------
1 | ====== Fetching SSH hostkeys without interaction ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: ssh, ssh-keys
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Jan Schampera
7 | ----
8 |
9 | Applies at least to ''openssh''.
10 |
11 | To get the hostkeys for a server, and write them to ''known_hosts''-file (to avoid that yes/no query when the key isn't known), you can do:
12 |
13 |
14 | ssh-keyscan -t rsa foo foo.example.com 1.2.3.4 >> ~/.ssh/known_host
15 |
16 |
17 | This example queries the hostkeys for the very same machine, but under 3 different "names" (hostname, FQDN, IP) and redirects the output to the ''known_hosts''-file.
18 |
19 | __**Notes:**__
20 | * if done blindly, the ''known_host''-file may grow very large. It might be wise to check for key existance first
21 | * if multiple keys for the same host exist in ''known_hosts'', the first one is taken (which might be an old or wrong one)
22 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/grouping_subshell.txt:
--------------------------------------------------------------------------------
1 | ====== Grouping commands in a subshell ======
2 |
3 | ===== Synopsis =====
4 |
5 | ( )
6 |
7 |
8 |
9 | ===== Description =====
10 | The [[syntax:basicgrammar#lists|list]] '''' is executed in a separate shell - a subprocess. No changes to the environment (variables etc...) are reflected in the "main shell".
11 |
12 | ===== Examples =====
13 |
14 | Execute a command in a different directory.
15 |
16 | echo "$PWD"
17 | ( cd /usr; echo "$PWD" )
18 | echo "$PWD" # Still in the original directory.
19 |
20 |
21 | ===== Portability considerations =====
22 |
23 | * The subshell compound command is specified by POSIX.
24 | * Avoid ambiguous syntax.
25 |
26 | (((1+1))) # Equivalent to: (( (1+1) ))
27 |
28 |
29 | ===== See also =====
30 | * [[syntax:ccmd:grouping_plain | grouping commands]]
31 | * [[http://mywiki.wooledge.org/SubShell | Subshells on Greycat's wiki]]
32 |
--------------------------------------------------------------------------------
/docs/dict/globbing.md:
--------------------------------------------------------------------------------
1 | # Globbing
2 |
3 | Globbing is the procedure of
4 |
5 | - matching all filenames against a given pattern
6 | - expanding to all matching filenames
7 |
8 | Unlike MSDOS, where the called program had to interpret the patterns,
9 | the globbing on UNIX(r) is done by the shell, the matched filenames are
10 | given as parameters to a called command:
11 |
12 | $ cat *.txt
13 |
14 | really executes
15 |
16 | $ cat 1.txt 3.txt foobar.txt XXX.txt
17 |
18 | The term \"glob\" originates back in the UNIX(r) days where an
19 | executable `glob` (from \"global\") existed which was used to expand
20 | pattern-matching characters. Later, this functionality was built into
21 | the shell. There's still a library function called `glob()` (POSIX(r)),
22 | which serves the same purpose.
23 |
24 | ## See also
25 |
26 | - [shell](../dict/shell.md)
27 | - [hardlink](../dict/hardlink.md)
28 |
29 | ## See also (article)
30 |
31 | - [pathname expansion](../syntax/expansion/globs.md)
32 |
--------------------------------------------------------------------------------
/original_source/user/thebonsai/imprint.txt:
--------------------------------------------------------------------------------
1 | ====== Imprint ======
2 |
3 | My provider forces me to publish my full and true name and address here. Otherwise they can close and lock the account. **I strictly contradict every unpermitted use of my name and address. Especially sending commercials of your own accord and/or selling the address are strictly forbidden! For exceptions my written permission is absolutely necessary.**
4 |
5 | Responsible for site content and design:
6 |
7 | ''Jan Schampera\\ Erich-Schott-Str. 2\\ 95666 Mitterteich\\ Federal Republic of Germany''
8 |
9 |
10 | //"I am not responsible for contents of linked pages. I dissociate myself from illegal contents, especially child porn, any radical statements, picture material as well as illegal links. The webmasters of linked pages are responsible by themselves! I assure my users of trying to link only serious pages, and of checking my links first. But at least I can not guarantee for unknown people and their thoughts."//
11 |
--------------------------------------------------------------------------------
/docs/snipplets/ssh_fetchkeys.md:
--------------------------------------------------------------------------------
1 | # Fetching SSH hostkeys without interaction
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: ssh, ssh-keys
4 | LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
5 |
6 | ------------------------------------------------------------------------
7 |
8 | Applies at least to `openssh`.
9 |
10 | To get the hostkeys for a server, and write them to `known_hosts`-file
11 | (to avoid that yes/no query when the key isn't known), you can do:
12 |
13 | ssh-keyscan -t rsa foo foo.example.com 1.2.3.4 >> ~/.ssh/known_host
14 |
15 | This example queries the hostkeys for the very same machine, but under 3
16 | different \"names\" (hostname, FQDN, IP) and redirects the output to the
17 | `known_hosts`-file.
18 |
19 | **Notes:**
20 |
21 | - if done blindly, the `known_host`-file may grow very large. It might
22 | be wise to check for key existance first
23 | - if multiple keys for the same host exist in `known_hosts`, the first
24 | one is taken (which might be an old or wrong one)
25 |
--------------------------------------------------------------------------------
/original_source/dict/terms/globbing.txt:
--------------------------------------------------------------------------------
1 | ====== Globbing ======
2 |
3 | Globbing is the procedure of
4 | * matching all filenames against a given pattern
5 | * expanding to all matching filenames
6 |
7 | Unlike MSDOS, where the called program had to interpret the patterns, the globbing on UNIX(r) is done by the shell, the matched filenames are given as parameters to a called command:
8 |
9 | $ cat *.txt
10 |
11 | really executes
12 |
13 | $ cat 1.txt 3.txt foobar.txt XXX.txt
14 |
15 |
16 | The term "glob" originates back in the UNIX(r) days where an executable ''glob'' (from "global") existed which was used to expand pattern-matching characters. Later, this functionality was built into the shell. There's still a library function called ''glob()'' (POSIX(r)), which serves the same purpose.
17 |
18 | ===== See also =====
19 | * [[dict:terms:shell | shell]]
20 | * [[dict:terms:hardlink | hardlink]]
21 |
22 | ===== See also (article) =====
23 | * [[ syntax:expansion:globs | pathname expansion]]
24 |
--------------------------------------------------------------------------------
/docs/misc/shell_humor.md:
--------------------------------------------------------------------------------
1 | # Shell Humor
2 |
3 | Nothing special, just my private collection of some more or less funny
4 | shell stuff I saw during the years.
5 |
6 | Usually Bash and/or Linux (GNU Toolset) specific.
7 |
8 | $ %blow
9 | -bash: fg: %blow: no such job
10 |
11 | $ ar m god
12 | ar: creating god
13 |
14 | $ touch /pussy
15 | touch: cannot touch `/pussy': Permission denied
16 |
17 | $ mount; fsck; fsck; fsck; umount; sleep
18 |
19 | # the lover variant
20 | $ unzip; strip; touch; finger; grep; mount; fsck; more; yes; fsck; fsck; umount; sleep
21 |
22 | # it's not directly funny, only because it's not obvious that this is an sed command
23 | # for the <<<, it works only in Bash
24 | $ sed streetlight <<< reeter
25 | lighter
26 |
27 | # see above for comments
28 | $ sed statement <<< cat
29 | cement
30 |
31 | $ (-
32 | bash: (-: command not found
33 |
34 | $ echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
35 | GET A LIFE!
36 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/arithmetic_eval.md:
--------------------------------------------------------------------------------
1 | # Arithmetic evaluation (command)
2 |
3 | ## Synopsis
4 |
5 | (( ))
6 |
7 | ## Description
8 |
9 | This command evaluates the [arithmetic expression](../../syntax/arith_expr.md)
10 | ``.
11 |
12 | If the expression evaluates to 0 then the exit code of the expression is
13 | set to 1 (`FALSE`). If the expression evaluates to something else than
14 | 0, then the exit code of the expression is set to 0 (`TRUE`). For this
15 | return code mapping, please see [this
16 | section](../../syntax/arith_expr.md#arithmetic_expressions_and_return_codes).
17 |
18 | The functionality basically is equivalent to what the [`let` builtin
19 | command](../../commands/builtin/let.md) does. The arithmetic evaluation compound
20 | command should be preferred.
21 |
22 | ## Examples
23 |
24 | ## Portability considerations
25 |
26 | ## See also
27 |
28 | - Internal: [arithmetic expressions](../../syntax/arith_expr.md)
29 | - Internal: [arithmetic expansion](../../syntax/expansion/arith.md)
30 | - Internal: [The `let` builtin command](../../commands/builtin/let.md)
31 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/arithmetic_eval.txt:
--------------------------------------------------------------------------------
1 | ====== Arithmetic evaluation (command) ======
2 |
3 | ===== Synopsis =====
4 |
5 | (( ))
6 |
7 |
8 | ===== Description =====
9 | This command evaluates the [[syntax:arith_expr | arithmetic expression]] ''''.
10 |
11 | If the expression evaluates to 0 then the exit code of the expression is set to 1 (''FALSE''). If the expression evaluates to something else than 0, then the exit code of the expression is set to 0 (''TRUE''). For this return code mapping, please see [[syntax:arith_expr#arithmetic_expressions_and_return_codes | this section]].
12 |
13 |
14 | The functionality basically is equivalent to what the [[commands:builtin:let | ''let'' builtin command]] does. The arithmetic evaluation compound command should be preferred.
15 |
16 | ===== Examples =====
17 |
18 |
19 | ===== Portability considerations =====
20 |
21 | ===== See also =====
22 | * Internal: [[syntax:arith_expr | arithmetic expressions]]
23 | * Internal: [[syntax:expansion:arith | arithmetic expansion]]
24 | * Internal: [[commands:builtin:let | The ''let'' builtin command]]
25 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/until_loop.md:
--------------------------------------------------------------------------------
1 | # The until loop
2 |
3 | ## Synopsis
4 |
5 | until ; do
6 |
7 | done
8 |
9 | ## Description
10 |
11 | The until-loop is relatively simple in what it does: it executes the
12 | [command list](../../syntax/basicgrammar.md#lists) `` and if the exit
13 | code of it was **not** 0 (FALSE) it executes ``. This happens
14 | again and again until `` returns TRUE.
15 |
16 | This is exactly the opposite of the [while
17 | loop](../../syntax/ccmd/while_loop.md).
18 |
19 | :!: Like all loops (both `for`-loops, `while` and `until`), this loop
20 | can be
21 |
22 | - terminated (broken) by the `break` command, optionally as `break N`
23 | to break `N` levels of nested loops
24 | - forced to immediately do the next iteration using the `continue`
25 | command, optionally as `continue N` analog to `break N`
26 |
27 | ### Return status
28 |
29 | The return status is the one of the last command executed in ``,
30 | or `0` (`TRUE`) if none was executed.
31 |
32 | ## Examples
33 |
34 | ## Portability considerations
35 |
36 | ## See also
37 |
38 | - Internal: [The while loop](../../syntax/ccmd/while_loop.md)
39 |
--------------------------------------------------------------------------------
/original_source/misc/shell_humor.txt:
--------------------------------------------------------------------------------
1 | ====== Shell Humor ======
2 |
3 | Nothing special, just my private collection of some more or less funny shell stuff I saw during the years.
4 |
5 | Usually Bash and/or Linux (GNU Toolset) specific.
6 |
7 |
8 | $ %blow
9 | -bash: fg: %blow: no such job
10 |
11 |
12 |
13 | $ ar m god
14 | ar: creating god
15 |
16 |
17 |
18 | $ touch /pussy
19 | touch: cannot touch `/pussy': Permission denied
20 |
21 |
22 |
23 | $ mount; fsck; fsck; fsck; umount; sleep
24 |
25 |
26 |
27 | # the lover variant
28 | $ unzip; strip; touch; finger; grep; mount; fsck; more; yes; fsck; fsck; umount; sleep
29 |
30 |
31 |
32 | # it's not directly funny, only because it's not obvious that this is an sed command
33 | # for the <<<, it works only in Bash
34 | $ sed streetlight <<< reeter
35 | lighter
36 |
37 |
38 |
39 | # see above for comments
40 | $ sed statement <<< cat
41 | cement
42 |
43 |
44 |
45 | $ \(-
46 | bash: (-: command not found
47 |
48 |
49 |
50 | $ echo '[q]sa[ln0=aln256%Pln256/snlbx]sb3135071790101768542287578439snlbxq'|dc
51 | GET A LIFE!
52 |
53 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/until_loop.txt:
--------------------------------------------------------------------------------
1 | ====== The until loop ======
2 |
3 | ===== Synopsis =====
4 |
5 | until ; do
6 |
7 | done
8 |
9 |
10 | ===== Description =====
11 | The until-loop is relatively simple in what it does: it executes the [[syntax:basicgrammar#lists | command list]] '''' and if the exit code of it was **not** 0 (FALSE) it executes ''''. This happens again and again until '''' returns TRUE.
12 |
13 | This is exactly the opposite of the [[syntax:ccmd:while_loop | while loop]].
14 |
15 | :!: Like all loops (both ''for''-loops, ''while'' and ''until''), this loop can be
16 | * terminated (broken) by the ''break'' command, optionally as ''break N'' to break ''N'' levels of nested loops
17 | * forced to immediately do the next iteration using the ''continue'' command, optionally as ''continue N'' analog to ''break N''
18 |
19 | ==== Return status ====
20 |
21 | The return status is the one of the last command executed in '''', or ''0'' (''TRUE'') if none was executed.
22 |
23 | ===== Examples =====
24 |
25 | ===== Portability considerations =====
26 |
27 | ===== See also =====
28 |
29 | * Internal: [[syntax:ccmd:while_loop | The while loop]]
30 |
--------------------------------------------------------------------------------
/original_source/dict/terms/interpreter_directive.txt:
--------------------------------------------------------------------------------
1 | ====== Interpreter Directive ======
2 |
3 | * shebang
4 |
5 | The interpreter directive, usually called shebang, is the character sequence starting with ''#!'' (hash, exclamation-point) at the beginning of the very first line of an executable text file on unixoid operating systems.
6 |
7 | The program loader of the operating system may use this line to load an interpreter for this file when executed. This makes it a self-executable script.
8 |
9 | A shebang will typically look like
10 |
11 | #!/bin/bash
12 |
13 |
14 | Since the line starting with ''#'' is a comment for the shell (and some other scripting languages), it's ignored.
15 |
16 | Regarding the shebang, there are various, differences between operating systems, including:
17 | * may require a space after ''#!'' and before the pathname of the interpreter
18 | * may be able to take arguments for the interpreter
19 | * ...
20 |
21 | POSIX(r) doesn't specify the shebang, though in general it's commonly supported by operating systems.
22 |
23 | ===== See also =====
24 | * [[http://www.in-ulm.de/~mascheck/various/shebang/ | #!-magic]] - a nice overview of the differences between various operating systems
25 |
--------------------------------------------------------------------------------
/docs/dict/interpreter_directive.md:
--------------------------------------------------------------------------------
1 | # Interpreter Directive
2 |
3 | - shebang
4 |
5 | The interpreter directive, usually called shebang, is the character
6 | sequence starting with `#!` (hash, exclamation-point) at the beginning
7 | of the very first line of an executable text file on unixoid operating
8 | systems.
9 |
10 | The program loader of the operating system may use this line to load an
11 | interpreter for this file when executed. This makes it a self-executable
12 | script.
13 |
14 | A shebang will typically look like
15 |
16 | #!/bin/bash
17 |
18 | Since the line starting with `#` is a comment for the shell (and some
19 | other scripting languages), it's ignored.
20 |
21 | Regarding the shebang, there are various, differences between operating
22 | systems, including:
23 |
24 | - may require a space after `#!` and before the pathname of the
25 | interpreter
26 | - may be able to take arguments for the interpreter
27 | - \...
28 |
29 | POSIX(r) doesn't specify the shebang, though in general it's commonly
30 | supported by operating systems.
31 |
32 | ## See also
33 |
34 | - [#!-magic](http://www.in-ulm.de/~mascheck/various/shebang/) - a nice
35 | overview of the differences between various operating systems
36 |
--------------------------------------------------------------------------------
/docs/dict/end_of_options.md:
--------------------------------------------------------------------------------
1 | # End of Options
2 |
3 | The options of UNIX(r) utilities usually are introduced with a dash
4 | (`-`) character.
5 |
6 | This is problematic when a non-option argument has to be specified that
7 | begins with a dash. A common example for this are filenames.
8 |
9 | Many utilities use the convention to specify two consecutive dashes
10 | (`--`) to signal \"end of options at this point\". Beyond this tag, no
11 | options are processed anymore, even if an argument begins with a dash.
12 |
13 | Example: You want to list (`ls`) the file with the name `-hello`. With
14 | common option processing, this could end up in the ls-options `-h`,
15 | `-e`, `-l` and `-o` and probably in an error message about invalid
16 | options. You use this to avoid the wrong option processing:
17 |
18 | ls -- -hello
19 |
20 | POSIX(r) specifies that every utility should follow this rule (see ch.
21 | [12.2 Utility Syntax
22 | Guidelines](https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/basedefs/V1_chap12.html)),
23 | except
24 |
25 | - `echo` (historical reasons)
26 | - `test` (obvious parsing reasons)
27 |
28 | ## See also
29 |
30 | - Scripting article, internal:
31 | [getopts_tutorial](../howto/getopts_tutorial.md)
32 |
--------------------------------------------------------------------------------
/original_source/dict/terms/end_of_options.txt:
--------------------------------------------------------------------------------
1 | ====== End of Options ======
2 |
3 | The options of UNIX(r) utilities usually are introduced with a dash (''-'') character.
4 |
5 | This is problematic when a non-option argument has to be specified that begins with a dash. A common example for this are filenames.
6 |
7 | Many utilities use the convention to specify two consecutive dashes (''--'') to signal "end of options at this point". Beyond this tag, no options are processed anymore, even if an argument begins with a dash.
8 |
9 | Example: You want to list (''ls'') the file with the name ''-hello''. With common option processing, this could end up in the ls-options ''-h'', ''-e'', ''-l'' and ''-o'' and probably in an error message about invalid options. You use this to avoid the wrong option processing:
10 |
11 | ls -- -hello
12 |
13 |
14 | POSIX(r) specifies that every utility should follow this rule (see ch. [[https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/basedefs/V1_chap12.html|12.2 Utility Syntax Guidelines]]), except
15 | * ''echo'' (historical reasons)
16 | * ''test'' (obvious parsing reasons)
17 |
18 | ===== See also =====
19 |
20 | * Scripting article, internal: [[howto:getopts_tutorial]]
21 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/intro.txt:
--------------------------------------------------------------------------------
1 | ====== Bash compound commands ======
2 |
3 | The main part of Bash's syntax are the so-called **compound commands**. They're called like that because they use "real" commands ([[syntax:basicgrammar#simple_commands | simple commands]] or [[syntax:basicgrammar#lists | lists]]) and knit some intelligence around them. That is what the essential "Bash language" is made of.
4 |
5 | ===== Command grouping =====
6 | * grouping: [[grouping_plain | command grouping]]
7 | * grouping again: [[grouping_subshell | command grouping in a subshell]]
8 |
9 |
10 | ===== Conditional reactions =====
11 |
12 | Note that conditionals can also be scripted using [[syntax:basicgrammar#lists | list]], which are syntax elements, not commands.
13 |
14 | * the "new" test command: [[conditional_expression | conditional expression]]
15 | * if-clause: [[if_clause | conditional branching]]
16 | * case statement: [[case | pattern-based branching]]
17 |
18 | ===== Loops =====
19 | * [[classic_for | classic for-loop]]
20 | * [[c_for | C-style for-loop]]
21 | * [[while_loop | while loop]]
22 | * [[until_loop | until loop]]
23 |
24 | ===== Misc =====
25 | * math: [[arithmetic_eval | arithmetic evaluation]]
26 | * menus: [[user_select | user selections]]
--------------------------------------------------------------------------------
/docs/syntax/ccmd/intro.md:
--------------------------------------------------------------------------------
1 | # Bash compound commands
2 |
3 | The main part of Bash's syntax are the so-called **compound commands**.
4 | They're called like that because they use "real" commands ([simple
5 | commands](../../syntax/basicgrammar.md#simple_commands) or
6 | [lists](../../syntax/basicgrammar.md#lists)) and knit some intelligence around
7 | them. That is what the essential "Bash language" is made of.
8 |
9 | ## Command grouping
10 |
11 | - grouping: [command grouping](grouping_plain.md)
12 | - grouping again: [command grouping in a subshell](grouping_subshell.md)
13 |
14 | ## Conditional reactions
15 |
16 | Note that conditionals can also be scripted using
17 | [list](../../syntax/basicgrammar.md#lists), which are syntax elements, not
18 | commands.
19 |
20 | - the "new" test command: [conditional
21 | expression](conditional_expression.md)
22 | - if-clause: [conditional branching](if_clause.md)
23 | - case statement: [pattern-based branching](case.md)
24 |
25 | ## Loops
26 |
27 | - [classic for-loop](classic_for.md)
28 | - [C-style for-loop](c_for.md)
29 | - [while loop](while_loop.md)
30 | - [until loop](until_loop.md)
31 |
32 | ## Misc
33 |
34 | - math: [arithmetic evaluation](arithmetic_eval.md)
35 | - menus: [user selections](user_select.md)
36 |
--------------------------------------------------------------------------------
/docs/commands/builtin/exit.md:
--------------------------------------------------------------------------------
1 | # The exit builtin command
2 |
3 | ## Synopsis
4 |
5 | exit [N]
6 |
7 | ## Description
8 |
9 | The `exit` command terminates the current shell (or script).
10 |
11 | If `N` is given, the return code to the parent process is set to `N`. If
12 | not, the returned status the the status of the most recently executed
13 | command (i.e. `$?`).
14 |
15 | A [trap](../../commands/builtin/trap.md) on `EXIT` is executed before the shell
16 | exits, except the executed `exit` command is part of an already running
17 | trap.
18 |
19 | ### Options
20 |
21 | There are no options.
22 |
23 | ### Exit status
24 |
25 | Naturally, you can't ask for the exit status from within the shell that
26 | executed the `exit` command, because the shell exits.
27 |
28 | |Status|Reason|
29 | |------|------|
30 | |255|invalid (e.g. non-numeric) argument - this staus is returned to the parent|
31 |
32 | ## Examples
33 |
34 | ### Exit the shell and explicitely set its exit status
35 |
36 | exit 3
37 |
38 | ## Portability considerations
39 |
40 | - if `N` is specified, but its value is not between 0 and 255
41 | inclusively, the exit status is undefined.
42 |
43 | ## See also
44 |
45 | - [The trap builtin command](../../commands/builtin/trap.md)
46 | - [The exit status](../../dict/exit_status.md)
47 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/while_loop.md:
--------------------------------------------------------------------------------
1 | # The while-loop
2 |
3 | ## Synopsis
4 |
5 | while ; do
6 |
7 | done
8 |
9 | ## Description
10 |
11 | The while-loop is relatively simple in what it does: it executes the
12 | [command list](../../syntax/basicgrammar.md#lists) `` and if the exit
13 | code of it was 0 (TRUE) it executes ``. This happens again and
14 | again until `` returns FALSE.
15 |
16 | This is exactly the opposite of the [until
17 | loop](../../syntax/ccmd/until_loop.md).
18 |
19 | :!: Like all loops (both `for`-loops, `while` and `until`), this loop
20 | can be
21 |
22 | - terminated (broken) by the `break` command, optionally as `break N`
23 | to break `N` levels of nested loops
24 | - forced to immediately do the next iteration using the `continue`
25 | command, optionally as `continue N` analog to `break N`
26 |
27 | ### Return status
28 |
29 | The return status is the one of the last command executed in ``,
30 | or `0` (`TRUE`) if none was executed.
31 |
32 | ## Examples
33 |
34 | ## Portability considerations
35 |
36 | ## See also
37 |
38 | - Internal: [The until loop](../../syntax/ccmd/until_loop.md)
39 | - Internal: [code examples of the read builtin
40 | command](../../commands/builtin/read.md#code_examples) to see how you can
41 | loop over lines
42 |
--------------------------------------------------------------------------------
/docs/commands/builtin/readonly.md:
--------------------------------------------------------------------------------
1 | # The readonly builtin command
2 |
3 | ## Synopsis
4 |
5 | readonly [-p] [-a] [-A] [-f] [NAME[=VALUE] ...]
6 |
7 | ## Description
8 |
9 | The `readonly` builtin command is used to mark variables or functions as
10 | read-only, which means unchangeable. This implies that it can't be
11 | unset anymore. A `readonly` variable may not be redefined in child
12 | scopes. A readonly global may not be redefined as a function local
13 | variable. Simple command environment assignments may not reference
14 | readonly variables.
15 |
16 | ### Options
17 |
18 | |Option|Description|
19 | |-|-|
20 | |`-a`|refer to normal arrays|
21 | |`-A`|refer to associative arrays|
22 | |`-f`|refer to functions|
23 | |`-p`|print all read-only variables or functions, `-a`, `-A` and `-f` can be used to filter. The output is reusable as input|
24 |
25 | An argument of `--` disables further option processing.
26 |
27 | ### Return status
28 |
29 | |Status|Reason|
30 | |-|-|
31 | |0|no error|
32 | |!=0|invalid option|
33 | |!=0|invalid combination of options|
34 | |!=0|a given `NAME` is invalid|
35 |
36 | ## Examples
37 |
38 | ## Portability considerations
39 |
40 | - in POSIX(r), only the `-p` option is specified
41 |
42 | ## See also
43 |
44 | - [declare](../../commands/builtin/declare.md)
45 | - [unset](../../commands/builtin/unset.md)
46 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/while_loop.txt:
--------------------------------------------------------------------------------
1 | ====== The while-loop ======
2 |
3 | ===== Synopsis =====
4 |
5 | while ; do
6 |
7 | done
8 |
9 |
10 | ===== Description =====
11 | The while-loop is relatively simple in what it does: it executes the [[syntax:basicgrammar#lists | command list]] '''' and if the exit code of it was 0 (TRUE) it executes ''''. This happens again and again until '''' returns FALSE.
12 |
13 | This is exactly the opposite of the [[syntax:ccmd:until_loop | until loop]].
14 |
15 | :!: Like all loops (both ''for''-loops, ''while'' and ''until''), this loop can be
16 | * terminated (broken) by the ''break'' command, optionally as ''break N'' to break ''N'' levels of nested loops
17 | * forced to immediately do the next iteration using the ''continue'' command, optionally as ''continue N'' analog to ''break N''
18 |
19 | ==== Return status ====
20 |
21 | The return status is the one of the last command executed in '''', or ''0'' (''TRUE'') if none was executed.
22 |
23 | ===== Examples =====
24 |
25 |
26 | ===== Portability considerations =====
27 |
28 |
29 | ===== See also =====
30 |
31 | * Internal: [[syntax:ccmd:until_loop | The until loop]]
32 | * Internal: [[commands:builtin:read#code_examples|code examples of the read builtin command]] to see how you can loop over lines
33 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/exit.txt:
--------------------------------------------------------------------------------
1 | ====== The exit builtin command ======
2 |
3 | ===== Synopsis =====
4 | exit [N]
5 |
6 | ===== Description =====
7 | The ''exit'' command terminates the current shell (or script).
8 |
9 | If ''N'' is given, the return code to the parent process is set to ''N''. If not, the returned status the the status of the most recently executed command (i.e. ''$?'').
10 |
11 | A [[commands:builtin:trap|trap]] on ''EXIT'' is executed before the shell exits, except the executed ''exit'' command is part of an already running trap.
12 |
13 | ==== Options ====
14 | There are no options.
15 |
16 |
17 | ==== Exit status ====
18 |
19 | Naturally, you can't ask for the exit status from within the shell that executed the ''exit'' command, because the shell exits.
20 |
21 | ^Status ^Reason ^
22 | |255 |invalid (e.g. non-numeric) argument - this staus is returned to the parent |
23 |
24 |
25 | ===== Examples =====
26 |
27 | ==== Exit the shell and explicitely set its exit status ====
28 |
29 | exit 3
30 |
31 |
32 | ===== Portability considerations =====
33 | * if ''N'' is specified, but its value is not between 0 and 255 inclusively, the exit status is undefined.
34 |
35 |
36 | ===== See also =====
37 | * [[commands:builtin:trap|The trap builtin command]]
38 | * [[dict:terms:exit_status|The exit status]]
39 |
40 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/readonly.txt:
--------------------------------------------------------------------------------
1 | ====== The readonly builtin command ======
2 |
3 | ===== Synopsis =====
4 |
5 |
6 | readonly [-p] [-a] [-A] [-f] [NAME[=VALUE] ...]
7 |
8 |
9 | ===== Description =====
10 |
11 | The ''readonly'' builtin command is used to mark variables or functions as read-only, which means unchangeable. This implies that it can't be unset anymore. A ''readonly'' variable may not be redefined in child scopes. A readonly global may not be redefined as a function local variable. Simple command environment assignments may not reference readonly variables.
12 |
13 | ==== Options ====
14 |
15 | ^Option ^Description ^
16 | |''-a'' |refer to normal arrays |
17 | |''-A'' |refer to associative arrays |
18 | |''-f'' |refer to functions |
19 | |''-p'' |print all read-only variables or functions, ''-a'', ''-A'' and ''-f'' can be used to filter. The output is reusable as input |
20 |
21 | An argument of ''%%--%%'' disables further option processing.
22 | ==== Return status ====
23 |
24 | ^Status ^Reason ^
25 | |0 |no error |
26 | |!=0 |invalid option |
27 | |!=0 |invalid combination of options |
28 | |!=0 |a given ''NAME'' is invalid |
29 |
30 | ===== Examples =====
31 |
32 | ===== Portability considerations =====
33 |
34 | * in POSIX(r), only the ''-p'' option is specified
35 |
36 | ===== See also =====
37 |
38 | * [[commands:builtin:declare]]
39 | * [[commands:builtin:unset]]
--------------------------------------------------------------------------------
/docs/commands/builtin/export.md:
--------------------------------------------------------------------------------
1 | # The export builtin command
2 |
3 | ## Synopsis
4 |
5 | export [-fn] [NAME[=VALUE] ...]
6 | export -p
7 |
8 | ## Description
9 |
10 | The `export` builtin command is used to mark variables or functions
11 | referenced by `NAME` for automatic export to the environment. If `NAME`
12 | is a shell variable, a value `VALUE` can be assigned before exporting
13 | it.
14 |
15 | ### Options
16 |
17 | |Option|Description|
18 | |------|-----------|
19 | |`-f`|refer to shell functions|
20 | |`-n`|remove the export property from any referenced `NAME`|
21 | |`-p`|print all exported variables, with `-f`, print all exported functions - all in a format re-usable as input|
22 |
23 | An argument of `--` disables further option processing.
24 |
25 | ### Return status
26 |
27 | |Status|Reason|
28 | |------|------|
29 | |0|no error|
30 | |!=0|invalid option|
31 | |!=0|a given `NAME` is invalid|
32 |
33 | ## Examples
34 |
35 | Set the display to use when launching a GUI application (useful during
36 | SSH sessions):
37 |
38 | export DISPLAY=":0"
39 |
40 | Set your default text editor (e.g. SublimeText):
41 |
42 | export EDITOR=subl
43 |
44 | ## Portability considerations
45 |
46 | - in POSIX(r), only the `-p` option is specified
47 | - in POSIX(r), only variables (with value assignment) are to be
48 | exported, not shell functions
49 |
50 | ## See also
51 |
52 | - [declare](../../commands/builtin/declare.md)
53 |
--------------------------------------------------------------------------------
/original_source/snipplets/xclip.txt:
--------------------------------------------------------------------------------
1 | ====== X-Clipboard on Commandline ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: clipboard, x11, xclip, readline
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Josh Triplett
7 | type: snipplet
8 | ----
9 |
10 |
11 | # Make Control-v paste, if in X and if xclip available - Josh Triplett
12 | if [ -n "$DISPLAY" ] && [ -x /usr/bin/xclip ] ; then
13 | # Work around a bash bug: \C-@ does not work in a key binding
14 | bind '"\C-x\C-m": set-mark'
15 | # The '#' characters ensure that kill commands have text to work on; if
16 | # not, this binding would malfunction at the start or end of a line.
17 | bind 'Control-v: "#\C-b\C-k#\C-x\C-?\"$(xclip -o -selection c)\"\e\C-e\C-x\C-m\C-a\C-y\C-?\C-e\C-y\ey\C-x\C-x\C-d"'
18 | fi
19 |
20 |
21 | The behaviour is a bit tricky to explain:
22 | * kill text after the cursor
23 | * since the kill command **wants** text, it blindly adds a fake text "#" here
24 | * kill text before the cursor
25 | * since the kill command **wants** text, it blindly adds a fake text "#" here, too
26 | * write out ''"$(xclip -o -selection c)"''
27 | * run Control-Meta-e (shell-expand-line) to expand the ''"$(xclip -o -selection c)"''
28 | * yank the previously killed text back where it belongs
29 |
30 | Of course you can use any other command, you're not limited to ''xclip'' here.
31 |
32 | Note: C-@ as well as M-SPC both works and set the mark for me -- pgas
33 |
--------------------------------------------------------------------------------
/docs/commands/builtin/wait.md:
--------------------------------------------------------------------------------
1 | # The wait builtin command
2 |
3 | ## Synopsis
4 |
5 | wait [-f] [-n] [-p VARNAME] [ID...]
6 |
7 | ## Description
8 |
9 | The `wait` builtin command is used to wait for job completion and return
10 | exit status.
11 |
12 | - if `ID` is a job specification, it waits for all processes in the
13 | pipeline of this job
14 | - waits for a specific job (asynchronous command) and report its exit
15 | status if one or more `ID` is given
16 | - waits for all running jobs (asynchronous commands)
17 | - waits for "the next" job (`-n` option)
18 | - waits for termination instead of status change (`-f` option)
19 |
20 | `ID` may be an operating system process identifier or a shell job
21 | specification.
22 |
23 | ### Options
24 |
25 | |Option|Description|
26 | |------|-----------|
27 | |`-n`|Waits for "the next" child to exit (as opposed to "all children" without this option). Accepts a list of IDs (jobs)|
28 | |`-f`|Waits for the termination of the given `ID` (instead of waiting for a status change only)|
29 | |`-p VARNAME`|When waiting for a list (-n) or all jobs, writes the job ID to the job that was actually terminated into the variable `VARNAME`|
30 |
31 | ### Return status
32 |
33 | The return status is the return status of the job waited for, or
34 |
35 | |Status|Reason|
36 | |------|------|
37 | |0|waited for all jobs in shell's job list|
38 | |1|the given `ID` is not a valid job or process ID|
39 |
40 | ## Examples
41 |
42 | ## Portability considerations
43 |
44 | ## See also
45 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/export.txt:
--------------------------------------------------------------------------------
1 | ====== The export builtin command ======
2 |
3 | ===== Synopsis =====
4 |
5 |
6 | export [-fn] [NAME[=VALUE] ...]
7 | export -p
8 |
9 |
10 | ===== Description =====
11 |
12 | The ''export'' builtin command is used to mark variables or functions referenced by ''NAME'' for automatic export to the environment. If ''NAME'' is a shell variable, a value ''VALUE'' can be assigned before exporting it.
13 |
14 | ==== Options ====
15 |
16 | ^Option ^Description ^
17 | |''-f'' |refer to shell functions |
18 | |''-n'' |remove the export property from any referenced ''NAME'' |
19 | |''-p'' |print all exported variables, with ''-f'', print all exported functions - all in a format re-usable as input |
20 |
21 | An argument of ''%%--%%'' disables further option processing.
22 | ==== Return status ====
23 |
24 | ^Status ^Reason ^
25 | |0 |no error |
26 | |!=0 |invalid option |
27 | |!=0 |a given ''NAME'' is invalid |
28 |
29 | ===== Examples =====
30 |
31 | Set the display to use when launching a GUI application (useful during SSH sessions):
32 |
33 | export DISPLAY=":0"
34 |
35 |
36 | Set your default text editor (e.g. SublimeText):
37 |
38 | export EDITOR=subl
39 |
40 | ===== Portability considerations =====
41 |
42 | * in POSIX(r), only the ''-p'' option is specified
43 | * in POSIX(r), only variables (with value assignment) are to be exported, not shell functions
44 |
45 | ===== See also =====
46 |
47 | * [[commands:builtin:declare]]
48 |
--------------------------------------------------------------------------------
/docs/snipplets/xclip.md:
--------------------------------------------------------------------------------
1 | # X-Clipboard on Commandline
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: clipboard, x11, xclip,
4 | readline LastUpdate_dt: 2010-07-31 Contributors: Josh Triplett type:
5 | snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | # Make Control-v paste, if in X and if xclip available - Josh Triplett
10 | if [ -n "$DISPLAY" ] && [ -x /usr/bin/xclip ] ; then
11 | # Work around a bash bug: \C-@ does not work in a key binding
12 | bind '"\C-x\C-m": set-mark'
13 | # The '#' characters ensure that kill commands have text to work on; if
14 | # not, this binding would malfunction at the start or end of a line.
15 | bind 'Control-v: "#\C-b\C-k#\C-x\C-?\"$(xclip -o -selection c)\"\e\C-e\C-x\C-m\C-a\C-y\C-?\C-e\C-y\ey\C-x\C-x\C-d"'
16 | fi
17 |
18 | The behaviour is a bit tricky to explain:
19 |
20 | - kill text after the cursor
21 | - since the kill command **wants** text, it blindly adds a fake
22 | text \"#\" here
23 | - kill text before the cursor
24 | - since the kill command **wants** text, it blindly adds a fake
25 | text \"#\" here, too
26 | - write out `"$(xclip -o -selection c)"`
27 | - run Control-Meta-e (shell-expand-line) to expand the
28 | `"$(xclip -o -selection c)"`
29 | - yank the previously killed text back where it belongs
30 |
31 | Of course you can use any other command, you\'re not limited to `xclip`
32 | here.
33 |
34 | Note: C-@ as well as M-SPC both works and set the mark for me -- pgas
35 |
--------------------------------------------------------------------------------
/docs/snipplets/awkcsv.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - awk
4 | - csv
5 | ---
6 |
7 | # Using `awk` to deal with CSV that uses quoted/unquoted delimiters
8 |
9 | CSV files are a mess, yes.
10 |
11 | Assume you have CSV files that use the comma as delimiter and quoted
12 | data fields that can contain the delimiter.
13 |
14 | "first", "second", "last"
15 | "fir,st", "second", "last"
16 | "firtst one", "sec,ond field", "final,ly"
17 |
18 | Simply using the comma as separator for `awk` won't work here, of
19 | course.
20 |
21 | Solution: Use the field separator `", "|^"|"$` for `awk`.
22 |
23 | This is an OR-ed list of 3 possible separators:
24 |
25 | | | |
26 | |--------|----------------------------------------------|
27 | |`", "` | matches the area between the datafields|
28 | |`^"` | matches the area left of the first datafield|
29 | |`"$` | matches the area right of the last data field|
30 |
31 | You can tune these delimiters if you have other needs (for example if
32 | you don't have a space after the commas).
33 |
34 | Test:
35 |
36 | The `awk` command used for the CSV above just prints the fileds
37 | separated by `###` to see what's going on:
38 |
39 | $ awk -v FS='", "|^"|"$' '{print $2"###"$3"###"$4}' data.csv
40 | first###second###last
41 | fir,st###second###last
42 | firtst one###sec,ond field###final,ly
43 |
44 | **ATTENTION** If the CSV data changes its format every now and then (for
45 | example it only quotes the data fields if needed, not always), then this
46 | way will not work.
47 |
--------------------------------------------------------------------------------
/original_source/snipplets/awkcsv.txt:
--------------------------------------------------------------------------------
1 | ====== Using ''awk'' to deal with CSV that uses quoted/unquoted delimiters ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags : awk, csv
5 | LastUpdate_dt : 2010-07-31
6 | Contributors : SiegX (IRC)
7 | type : snipplet
8 | ----
9 |
10 | CSV files are a mess, yes.
11 |
12 | Assume you have CSV files that use the comma as delimiter and quoted data fields that can contain the delimiter.
13 |
14 |
15 | "first", "second", "last"
16 | "fir,st", "second", "last"
17 | "firtst one", "sec,ond field", "final,ly"
18 |
19 |
20 | Simply using the comma as separator for ''awk'' won't work here, of course.
21 |
22 | Solution:
23 | Use the field separator ''", "|^"|"$'' for ''awk''.
24 |
25 | This is an OR-ed list of 3 possible separators:
26 | |''", "''|matches the area between the datafields|
27 | |''^"''|matches the area left of the first datafield|
28 | |''"$''|matches the area right of the last data field|
29 |
30 | You can tune these delimiters if you have other needs (for example if you don't have a space after the commas).
31 |
32 | Test:
33 |
34 | The ''awk'' command used for the CSV above just prints the fileds separated by ''###'' to see what's going on:
35 |
36 | $ awk -v FS='", "|^"|"$' '{print $2"###"$3"###"$4}' data.csv
37 | first###second###last
38 | fir,st###second###last
39 | firtst one###sec,ond field###final,ly
40 |
41 |
42 | **ATTENTION** If the CSV data changes its format every now and then (for example it only quotes the data fields if needed, not always), then this way will not work.
43 |
--------------------------------------------------------------------------------
/docs/dict/hardlink.md:
--------------------------------------------------------------------------------
1 | # Hardlink
2 |
3 | Also the article for:
4 |
5 | - filename
6 |
7 | A hardlink associates a *filename* with a [file](../dict/file.md). That
8 | name is an entry in a directory listing. Of course a file can have more
9 | hardlinks to it (usually the number of hardlinks to a file is limited),
10 | but all hardlinks to a file must reside on the same
11 | `filesystem` as the file itself!
12 |
13 | What you usually call a file is just a name for that file, and thus, a
14 | hardlink.
15 |
16 | The difference between a [symbolic link](../dict/symlink.md) and a hard
17 | link is that there is no easy way to differentiate between a \'real\'
18 | file and a hard link, let's take a look at the example:
19 |
20 | \* create an empty file
21 |
22 | $ touch a
23 |
24 | \* create a hard link \'b\' and sym link \'c\' to empty file
25 |
26 | $ ln a b
27 | $ ln -s a c
28 |
29 | as you can see file(1) can't differentiate between a real file \'a\'
30 | and a hard link \'b\', but it can tell \'c\' is a sym link
31 |
32 | $ file *
33 | a: empty
34 | b: empty
35 | c: symbolic link to `a'
36 |
37 | `ls -i` prints out the inode numbers of files, if two files have the
38 | same inode number AND are on the same file system it means they are
39 | **hardlinked**.
40 |
41 | $ ls -i *
42 | 5262 a 5262 b 5263 c
43 |
44 | hard links don't consume additional space on the filesystem, the space
45 | is freed when the last hard link pointing to it is deleted.
46 |
47 | ## See also
48 |
49 | - [file](../dict/file.md)
50 | - [symlink](../dict/symlink.md)
51 |
--------------------------------------------------------------------------------
/original_source/dict/terms/hardlink.txt:
--------------------------------------------------------------------------------
1 | ====== Hardlink ======
2 |
3 | Also the article for:
4 | * filename
5 |
6 | A hardlink associates a //filename// with a [[dict:terms:file | file]]. That name is an entry in a directory listing. Of course a file can have more hardlinks to it (usually the number of hardlinks to a file is limited), but all hardlinks to a file must reside on the same [[dict:terms:filesystem | filesystem]] as the file itself!
7 |
8 | What you usually call a file is just a name for that file, and thus, a hardlink.
9 |
10 | The difference between a [[dict:terms:symlink | symbolic link]] and a hard link is that there is no easy way to differentiate between a 'real' file and a hard link, let's take a look at the example:
11 |
12 | * create an empty file
13 |
14 | $ touch a
15 |
16 | * create a hard link 'b' and sym link 'c' to empty file
17 |
18 | $ ln a b
19 | $ ln -s a c
20 |
21 | as you can see file(1) can't differentiate between a real file 'a' and a hard link 'b', but it can tell 'c' is a sym link
22 |
23 | $ file *
24 | a: empty
25 | b: empty
26 | c: symbolic link to `a'
27 |
28 | ''ls -i'' prints out the inode numbers of files, if two files have the same inode number AND are on the same file system it means they are **hardlinked**.
29 |
30 | $ ls -i *
31 | 5262 a 5262 b 5263 c
32 |
33 |
34 | hard links don't consume additional space on the filesystem, the space is freed when the last hard link pointing to it is deleted.
35 |
36 | ===== See also =====
37 | * [[dict:terms:file | file]]
38 | * [[dict:terms:filesystem | filesystem]]
39 | * [[dict:terms:symlink | symlink]]
40 |
41 |
--------------------------------------------------------------------------------
/original_source/snipplets/prargs.txt:
--------------------------------------------------------------------------------
1 | ====== Print argument list for testing ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: debug, arguments
5 | LastUpdate_dt: 2013-03-23
6 | Contributors: Snappy (IRC), Dan Douglas
7 | type: snipplet
8 | ----
9 |
10 | Sometimes you might find it useful to see how arguments passed to a program arrive there.
11 |
12 | Check this script (save it as script file or make a function):
13 |
14 | printf '"%b"\n' "$0" "$@" | nl -v0 -s": "
15 |
16 |
17 | It uses the [[commands:builtin:printf | printf command]] to generate a list of arguments, even with escape sequences interpreted. This list is shown formatted by the nl(1) utility.
18 |
19 | Another alternative with colorized output. If run in Bash, it temporarily disables all debug output for itself, including the test that determines whether to hide debug output. In ksh, tracing would have to be enabled on the function to show debug output, so it works out to being equivalent.
20 |
21 |
22 | # Bash or ksh93 debugging function for colored display of argv.
23 | # Optionally set OFD to the desired output file descriptor.
24 | function args {
25 | { BASH_XTRACEFD=3 command eval ${BASH_VERSION+"$(/dev/null
26 | case $- in *x*)
27 | set +x
28 | trap 'trap RETURN; set -x' RETURN
29 | esac
30 | EOF
31 |
32 | [[ ${OFD-1} == +([0-9]) ]] || return
33 |
34 | if [[ -t ${OFD:-2} ]]; then
35 | typeset -A clr=([green]=$(tput setaf 2) [sgr0]=$(tput sgr0))
36 | else
37 | typeset clr
38 | fi
39 |
40 | if ! ${1+false}; then
41 | printf -- "${clr[green]}<${clr[sgr0]}%s${clr[green]}>${clr[sgr0]} " "$@"
42 | echo
43 | else
44 | echo 'no args.'
45 | fi >&"${OFD:-2}"
46 | }
47 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/wait.txt:
--------------------------------------------------------------------------------
1 | ====== The wait builtin command ======
2 |
3 | ===== Synopsis =====
4 | wait [-f] [-n] [-p VARNAME] [ID...]
5 |
6 | ===== Description =====
7 | The ''wait'' builtin command is used to wait for job completion and return exit status.
8 |
9 | * if ''ID'' is a job specification, it waits for all processes in the pipeline of this job
10 | * waits for a specific job (asynchronous command) and report its exit status if one or more ''ID'' is given
11 | * waits for all running jobs (asynchronous commands)
12 | * waits for "the next" job (''-n'' option)
13 | * waits for termination instead of status change (''-f'' option)
14 |
15 | ''ID'' may be an operating system process identifier or a shell job specification.
16 |
17 | ==== Options ====
18 |
19 | ^ Option ^ Description ^
20 | | ''-n'' | Waits for "the next" child to exit (as opposed to "all children" without this option). Accepts a list of IDs (jobs) |
21 | | ''-f'' | Waits for the termination of the given ''ID'' (instead of waiting for a status change only) |
22 | | ''-p VARNAME'' | When waiting for a list (-n) or all jobs, writes the job ID to the job that was actually terminated into the variable ''VARNAME'' |
23 |
24 | ==== Return status ====
25 |
26 | The return status is the return status of the job waited for, or
27 |
28 | ^Status ^Reason ^
29 | |0 |waited for all jobs in shell's job list |
30 | |1 |the given ''ID'' is not a valid job or process ID |
31 |
32 | ===== Examples =====
33 |
34 |
35 | ===== Portability considerations =====
36 |
37 |
38 | ===== See also =====
39 |
40 |
--------------------------------------------------------------------------------
/original_source/snipplets/largestfile.txt:
--------------------------------------------------------------------------------
1 | ====== Get largest file ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: directory, recursive, find, crawl
5 | LastUpdate_dt: 2013-03-23
6 | Contributors: Dan Douglas
7 | type: snipplet
8 | ----
9 |
10 | One basic pattern for recursive directory traversal with operations on files at each node. This gets the largest file in each subdirectory. Toggling some small details will make it return the smallest, or traverse breadth-first instead of depth-first.
11 |
12 |
13 | #!/usr/bin/env bash
14 | # GNU find + bash4 / ksh93v / zsh
15 | # Get the largest file matching pattern in the given directories recursively
16 | ${ZSH_VERSION+false} || emulate ksh
17 | ${BASH_VERSION+shopt -s lastpipe extglob}
18 |
19 | function getLargest {
20 | typeset -A cur top || return
21 | typeset dir x
22 | for dir in "$2"/*/; do
23 | [[ -d $dir ]] || return 0
24 | getLargest "$1" "${dir%/}" || return
25 | top[size]=-1
26 | find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | {
27 | while :; do
28 | for x in cur\[{size,name}\]; do
29 | IFS= read -rd '' "$x" || break 2
30 | done
31 | if (( cur[size] > top[size] )); then
32 | top[size]=${cur[size]} top[name]=${cur[name]}
33 | fi
34 | done
35 | printf '%q\n' "${dir}${top[name]}"
36 | }
37 | done
38 | }
39 |
40 | # main pattern dir [ dir ... ]
41 | function main {
42 | if [[ -n $1 ]]; then
43 | typeset dir pattern=$1
44 | shift
45 | for dir; do
46 | [[ -d $dir ]] || return
47 | getLargest "$pattern" "$dir"
48 | done
49 | else
50 | return 1
51 | fi
52 | }
53 |
54 | main "$@"
55 |
56 | # vim: set fenc=utf-8 ff=unix ft=sh :
57 |
58 |
59 | ===== More examples =====
60 | * http://mywiki.wooledge.org/BashFAQ/003
61 | * http://mywiki.wooledge.org/UsingFind
--------------------------------------------------------------------------------
/docs/snipplets/prargs.md:
--------------------------------------------------------------------------------
1 | # Print argument list for testing
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: debug, arguments
4 | LastUpdate_dt: 2013-03-23 Contributors: Snappy (IRC), Dan Douglas type:
5 | snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | Sometimes you might find it useful to see how arguments passed to a
10 | program arrive there.
11 |
12 | Check this script (save it as script file or make a function):
13 |
14 | printf '"%b"\n' "$0" "$@" | nl -v0 -s": "
15 |
16 | It uses the [printf command](../commands/builtin/printf.md) to generate a
17 | list of arguments, even with escape sequences interpreted. This list is
18 | shown formatted by the nl(1) utility.
19 |
20 | Another alternative with colorized output. If run in Bash, it
21 | temporarily disables all debug output for itself, including the test
22 | that determines whether to hide debug output. In ksh, tracing would have
23 | to be enabled on the function to show debug output, so it works out to
24 | being equivalent.
25 |
26 | ``` bash
27 | # Bash or ksh93 debugging function for colored display of argv.
28 | # Optionally set OFD to the desired output file descriptor.
29 | function args {
30 | { BASH_XTRACEFD=3 command eval ${BASH_VERSION+"$(/dev/null
31 | case $- in *x*)
32 | set +x
33 | trap 'trap RETURN; set -x' RETURN
34 | esac
35 | EOF
36 |
37 | [[ ${OFD-1} == +([0-9]) ]] || return
38 |
39 | if [[ -t ${OFD:-2} ]]; then
40 | typeset -A clr=([green]=$(tput setaf 2) [sgr0]=$(tput sgr0))
41 | else
42 | typeset clr
43 | fi
44 |
45 | if ! ${1+false}; then
46 | printf -- "${clr[green]}<${clr[sgr0]}%s${clr[green]}>${clr[sgr0]} " "$@"
47 | echo
48 | else
49 | echo 'no args.'
50 | fi >&"${OFD:-2}"
51 | }
52 | ```
53 |
--------------------------------------------------------------------------------
/overrides/partials/comments.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
21 |
49 |
--------------------------------------------------------------------------------
/mkdocs.yml:
--------------------------------------------------------------------------------
1 | site_name: The Bash Hackers Wiki
2 | site_url: https://flokoe.github.io/bash-hackers-wiki/
3 |
4 | repo_url: https://github.com/flokoe/bash-hackers-wiki
5 | repo_name: flokoe/bash-hackers-wiki
6 | edit_uri: edit/main/docs/
7 |
8 | theme:
9 | name: material
10 | custom_dir: overrides
11 | features:
12 | - navigation.instant
13 | - navigation.tracking
14 | - navigation.tabs
15 | - navigation.sections
16 | - navigation.top
17 | - content.action.view
18 | - content.action.edit
19 | - search.suggest
20 | - search.highlight
21 | - content.code.copy
22 | icon:
23 | repo: fontawesome/brands/github
24 | palette:
25 | - scheme: default
26 | toggle:
27 | icon: material/brightness-7
28 | name: Switch to dark mode
29 | - scheme: slate
30 | toggle:
31 | icon: material/brightness-4
32 | name: Switch to light mode
33 |
34 | plugins:
35 | - git-revision-date-localized:
36 | enable_creation_date: true
37 | - search
38 | - awesome-pages
39 | - tags:
40 | tags_file: tags.md
41 | - minify:
42 | minify_html: true
43 | minify_css: true
44 | minify_js: true
45 | htmlmin_opts:
46 | remove_comments: true
47 | cache_safe: true
48 |
49 | markdown_extensions:
50 | - admonition
51 | - pymdownx.emoji:
52 | emoji_index: !!python/name:material.extensions.emoji.twemoji
53 | emoji_generator: !!python/name:material.extensions.emoji.to_svg
54 | - pymdownx.highlight:
55 | anchor_linenums: true
56 | - pymdownx.superfences
57 | - pymdownx.highlight
58 | - pymdownx.inlinehilite
59 | - pymdownx.keys
60 | - pymdownx.smartsymbols
61 | - footnotes
62 | - toc:
63 | permalink: true
64 |
65 | nav:
66 | - Start: index.md
67 | - ... | regex=^(?!need_love\.md|bash4\.md|wishes\.md|tags\.md)
68 | - tags.md
69 |
70 | watch:
71 | - overrides
72 |
--------------------------------------------------------------------------------
/docs/commands/builtin/shopt.md:
--------------------------------------------------------------------------------
1 | # The shopt builtin command
2 |
3 | The `shopt` builtin manages [shell options](../../internals/shell_options.md), a
4 | set of boolean (`on`/`off`) configuration variables that control the
5 | behaviour of the shell.
6 |
7 | ## Synopsis
8 |
9 | shopt [-pqsu] [-o]
10 |
11 | ## Description
12 |
13 | Note: Some of these options and other shell options can also be set with
14 | [the set builtin](../../commands/builtin/set.md).
15 |
16 | ### Options
17 |
18 | |Option|Description|
19 | |------|-----------|
20 | |`-o`|Restrict the values of `` to only those also known by [the set builtin](../../commands/builtin/set.md)|
21 | |`-p`|Print all shell options and their current value. **Default**.|
22 | |`-q`|Quiet mode. Set exit code if named option is set. For multiple options: `TRUE` if all options are set, `FALSE` otherwise|
23 | |`-s`|Enable (set) the shell options named by `` or list all *enabled* options if no names are given|
24 | |`-u`|Disabe (unset) the shell options named by `` or list all *disabled* options if no names are given|
25 |
26 | As noted above, if only `-s` or `-u` are given without any option names,
27 | only the currently enabled (`-s`) or disabled (`-u`) options are
28 | printed.
29 |
30 | ### Exit code
31 |
32 | When listing options, the exit code is `TRUE` (0), if all options are
33 | enabled, `FALSE` otherwise.
34 |
35 | When setting/unsetting an option, the exit code is `TRUE` unless the
36 | named option doesn't exitst.
37 |
38 | ## Examples
39 |
40 | Enable the `nullglob` option:
41 |
42 | shopt -s nullglob
43 |
44 | ## Portability considerations
45 |
46 | The `shopt` command is not portable accross different shells.
47 |
48 | ## See also
49 |
50 | - Internal: [The set builtin command](../../commands/builtin/set.md)
51 | - Internal: [List of shell options](../../internals/shell_options.md)
52 |
--------------------------------------------------------------------------------
/original_source/syntax/expansion/wordsplit.txt:
--------------------------------------------------------------------------------
1 | ====== Word splitting ======
2 |
3 | FIXME to be continued!
4 |
5 | Word splitting occurs once any of the following expansions are done (and only then!)
6 | * [[syntax:pe | Parameter expansion]]
7 | * [[syntax:expansion:cmdsubst | Command substitution]]
8 | * [[syntax:expansion:arith | Arithmetic expansion]]
9 | Bash will scan the results of these expansions for special ''IFS'' characters that mark word boundaries. This is only done on results that are **not double-quoted**!
10 |
11 | ===== Internal Field Separator IFS =====
12 |
13 | The ''IFS'' variable holds the characters that Bash sees as word boundaries in this step. The default contains the characters
14 | *
15 | *
16 | *
17 | These characters are also assumed when IFS is **unset**. When ''IFS'' is **empty** (nullstring), no word splitting is performed at all.
18 |
19 |
20 |
21 |
22 | ===== Behaviour =====
23 |
24 | The results of the expansions mentioned above are scanned for ''IFS''-characters. If **one or more** (in a sequence) of them is found, the expansion result is split at these positions into multiple words.
25 |
26 | This doesn't happen when the expansion results were **double-quoted**.
27 |
28 | When a null-string (e.g., something that before expanded to >>nothing<<) is found, it is removed, unless it is quoted ('''''' or ''""'').
29 |
30 | __**Again note:**__ Without any expansion beforehand, Bash won't perform word splitting! In this case, the initial token parsing is solely responsible.
31 |
32 |
33 | ===== See also =====
34 | * [[syntax:expansion:intro | Introduction to expansion and substitution]]
35 | * [[syntax:quoting | Quoting and escaping]]
36 | * [[http://mywiki.wooledge.org/WordSplitting | WordSplitting]], [[http://mywiki.wooledge.org/IFS | IFS]], and [[http://mywiki.wooledge.org/DontReadLinesWithFor | DontReadLinesWithFor]] - Greg's wiki
--------------------------------------------------------------------------------
/original_source/commands/builtin/cd.txt:
--------------------------------------------------------------------------------
1 | ====== The cd builtin command ======
2 |
3 | ===== Synopsis =====
4 | cd [-L|-P] [DIRECTORY]
5 | cd -
6 |
7 | ===== Description =====
8 | The ''cd'' builtin command is used to change the current working directory
9 | * to the given directory (''cd DIRECTORY'')
10 | * to the previous working directory (''cd -'') as saved in the [[syntax:shellvars#OLDPWD|OLDPWD]] shell variable
11 | * to the user's home directory as specified in the [[syntax:shellvars#HOME|HOME]] environment variable (when used without a ''DIRECTORY'' argument)
12 |
13 | The ''cd'' builtin command searches the directories listed in [[syntax:shellvars#CDPATH|CDPATH]] for a matching directory.
14 |
15 | The default behaviour is to follow symbolic links unless the ''-P'' option is given or the shell is configured to do so (see the ''-P'' option of [[commands:builtin:set|the set builtin command]]).
16 |
17 | ==== Options ====
18 |
19 | ^Option^Description^
20 | |''-L'' |Follow symbolic links (default) |
21 | |''-P'' |Do not follow symbolic links |
22 | |''-@'' |Browse a file's extended attributed, if supported |
23 |
24 | ==== Exit status ====
25 |
26 | * true if the directory was changed successfully
27 | * false if a change to the home directory was requested, but [[syntax:shellvars#HOME|HOME]] is unset
28 | * false if anything else goes wrong
29 |
30 | ===== Examples =====
31 |
32 | ==== Change the working directory to the user's home directory ====
33 |
34 | cd
35 |
36 | ==== Change the working directory to the previous directory ====
37 |
38 | cd -
39 |
40 | ===== Portability considerations =====
41 |
42 | ===== See also =====
43 | * variable [[syntax:shellvars#CDPATH|CDPATH]]
44 | * variable [[syntax:shellvars#HOME|HOME]]
45 | * variable [[syntax:shellvars#OLDPWD|OLDPWD]]
46 | * the ''-P'' option of [[commands:builtin:set|the set builtin command]]
47 |
--------------------------------------------------------------------------------
/docs/commands/builtin/cd.md:
--------------------------------------------------------------------------------
1 | # The cd builtin command
2 |
3 | ## Synopsis
4 |
5 | cd [-L|-P] [DIRECTORY]
6 |
7 | cd -
8 |
9 | ## Description
10 |
11 | The `cd` builtin command is used to change the current working directory
12 |
13 | - to the given directory (`cd DIRECTORY`)
14 | - to the previous working directory (`cd -`) as saved in the
15 | [OLDPWD](../../syntax/shellvars.md#OLDPWD) shell variable
16 | - to the user's home directory as specified in the
17 | [HOME](../../syntax/shellvars.md#HOME) environment variable (when used
18 | without a `DIRECTORY` argument)
19 |
20 | The `cd` builtin command searches the directories listed in
21 | [CDPATH](../../syntax/shellvars.md#CDPATH) for a matching directory.
22 |
23 | The default behaviour is to follow symbolic links unless the `-P` option
24 | is given or the shell is configured to do so (see the `-P` option of
25 | [the set builtin command](../../commands/builtin/set.md)).
26 |
27 | ### Options
28 |
29 | |Option|Description|
30 | |------|-----------|
31 | |`-L`|Follow symbolic links (default)|
32 | |`-P`|Do not follow symbolic links|
33 | |`-@`|Browse a file's extended attributed, if supported|
34 |
35 | ### Exit status
36 |
37 | - true if the directory was changed successfully
38 | - false if a change to the home directory was requested, but
39 | [HOME](../../syntax/shellvars.md#HOME) is unset
40 | - false if anything else goes wrong
41 |
42 | ## Examples
43 |
44 | ### Change the working directory to the user's home directory
45 |
46 | cd
47 |
48 | ### Change the working directory to the previous directory
49 |
50 | cd -
51 |
52 | ## Portability considerations
53 |
54 | ## See also
55 |
56 | - variable [CDPATH](../../syntax/shellvars.md#CDPATH)
57 | - variable [HOME](../../syntax/shellvars.md#HOME)
58 | - variable [OLDPWD](../../syntax/shellvars.md#OLDPWD)
59 | - the `-P` option of [the set builtin command](../../commands/builtin/set.md)
60 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/shopt.txt:
--------------------------------------------------------------------------------
1 | ====== The shopt builtin command ======
2 |
3 | The ''shopt'' builtin manages [[internals:shell_options | shell options]], a set of boolean (''on''/''off'') configuration variables that control the behaviour of the shell.
4 |
5 | ===== Synopsis =====
6 |
7 |
8 | shopt [-pqsu] [-o]
9 |
10 |
11 | ===== Description =====
12 |
13 | Note: Some of these options and other shell options can also be set with [[commands:builtin:set | the set builtin]].
14 |
15 | ==== Options ====
16 |
17 | ^Option^Description^
18 | |''-o''|Restrict the values of '''' to only those also known by [[commands:builtin:set | the set builtin]]|
19 | |''-p''|Print all shell options and their current value. **Default**.|
20 | |''-q''|Quiet mode. Set exit code if named option is set. For multiple options: ''TRUE'' if all options are set, ''FALSE'' otherwise|
21 | |''-s''|Enable (__s__et) the shell options named by '''' or list all //enabled// options if no names are given|
22 | |''-u''|Disabe (__u__nset) the shell options named by '''' or list all //disabled// options if no names are given|
23 |
24 | As noted above, if only ''-s'' or ''-u'' are given without any option names, only the currently enabled (''-s'') or disabled (''-u'') options are printed.
25 |
26 | ==== Exit code ====
27 |
28 | When listing options, the exit code is ''TRUE'' (0), if all options are enabled, ''FALSE'' otherwise.
29 |
30 | When setting/unsetting an option, the exit code is ''TRUE'' unless the named option doesn't exitst.
31 |
32 | ===== Examples ======
33 |
34 | Enable the ''nullglob'' option:
35 |
36 | shopt -s nullglob
37 |
38 |
39 | ===== Portability considerations ======
40 |
41 | The ''shopt'' command is not portable accross different shells.
42 |
43 | ===== See also ======
44 |
45 | * Internal: [[commands:builtin:set | The set builtin command]]
46 | * Internal: [[internals:shell_options | List of shell options]]
47 |
--------------------------------------------------------------------------------
/docs/syntax/expansion/wordsplit.md:
--------------------------------------------------------------------------------
1 | # Word splitting
2 |
3 | !!! warning "FIXME"
4 | to be continued!
5 |
6 | Word splitting occurs once any of the following expansions are done (and
7 | only then!)
8 |
9 | - [Parameter expansion](../../syntax/pe.md)
10 | - [Command substitution](../../syntax/expansion/cmdsubst.md)
11 | - [Arithmetic expansion](../../syntax/expansion/arith.md)
12 |
13 | Bash will scan the results of these expansions for special `IFS`
14 | characters that mark word boundaries. This is only done on results that
15 | are **not double-quoted**!
16 |
17 | ## Internal Field Separator IFS
18 |
19 | The `IFS` variable holds the characters that Bash sees as word
20 | boundaries in this step. The default contains the characters
21 |
22 | - <space>
23 | - <tab>
24 | - <newline>
25 |
26 | These characters are also assumed when IFS is **unset**. When `IFS` is
27 | **empty** (nullstring), no word splitting is performed at all.
28 |
29 | ## Behaviour
30 |
31 | The results of the expansions mentioned above are scanned for
32 | `IFS`-characters. If **one or more** (in a sequence) of them is found,
33 | the expansion result is split at these positions into multiple words.
34 |
35 | This doesn't happen when the expansion results were **double-quoted**.
36 |
37 | When a null-string (e.g., something that before expanded to
38 | >>nothing<<) is found, it is removed, unless it is quoted (`''` or
39 | `""`).
40 |
41 | **Again note:** Without any expansion beforehand, Bash
42 | won't perform word splitting! In this case, the initial token parsing
43 | is solely responsible.
44 |
45 | ## See also
46 |
47 | - [Introduction to expansion and
48 | substitution](../../syntax/expansion/intro.md)
49 | - [Quoting and escaping](../../syntax/quoting.md)
50 | - [WordSplitting](http://mywiki.wooledge.org/WordSplitting),
51 | [IFS](http://mywiki.wooledge.org/IFS), and
52 | [DontReadLinesWithFor](http://mywiki.wooledge.org/DontReadLinesWithFor) -
53 | Greg's wiki
54 |
--------------------------------------------------------------------------------
/original_source/meta/need_love.txt:
--------------------------------------------------------------------------------
1 | ====== Bash Hackers Wiki needs love ======
2 |
3 | There are things to do. Always.
4 |
5 | ===== Article optics and structure =====
6 |
7 | Target: A more or less unique structure (done)
8 |
9 | * [[syntax:ccmd:intro]] - bring all mentioned compound command description pages into a format
10 | * SYNOPSIS
11 | * DESCRIPTION
12 | * (with as many sub-topics as needed)
13 | * EXAMPLES
14 | * PORTABILITY CONSIDERATIONS
15 | * SEE ALSO
16 | * do the same with command descriptions (printf, read, ...)
17 |
18 |
19 | ===== Article content and correctness =====
20 |
21 | In general all pages need review, all the time. If you find anything incorrect, stupid, unclear, just edit the page or write a mail. It's also possible to use the integrated discussion option (below every article).
22 |
23 | Specific needs:
24 | * [[scripting:tutoriallist]] - new tutorials? opinions? etc.
25 |
26 | ===== Article code examples =====
27 | * [[howto:getopts_tutorial]] - lacks some complex or more sophisticated examples
28 |
29 | ===== Article completeness =====
30 | * [[scripting:newbie_traps]] - add your personal top newbie traps
31 | * [[internals:shell_options]] - are these all options?
32 | * [[commands:builtin:printf]] - can printf do more?
33 | * [[syntax:shellvars]] - needs complete shell variables
34 |
35 | ===== Greg's BashFAQ mirror =====
36 |
37 | The code rewrite to mirror Greg's BashFAQ was a bad idea, it doesn't work good. A fix to not lose the links would be to invent some nifty mod_rewrite rules to forward any requests to the namespace to the real BashFAQ wiki.
38 |
39 | **Update:** Just hacked the rewrite rules - the mirror is gone and the mirror URLs redirect to Greg's BashFAQ.
40 |
41 | **Future:** Mirror it as real MoinMoinWiki instance. This won't happen here on the webspace, more on a dedicated server.
42 |
43 | ===== Getopts tutorial =====
44 |
45 | * more examples
46 | * workaround to use long options: translate long option to short option and replace positional parameters before using getopts
--------------------------------------------------------------------------------
/docs/snipplets/largestfile.md:
--------------------------------------------------------------------------------
1 | # Get largest file
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: directory, recursive,
4 | find, crawl LastUpdate_dt: 2013-03-23 Contributors: Dan Douglas type:
5 | snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | One basic pattern for recursive directory traversal with operations on
10 | files at each node. This gets the largest file in each subdirectory.
11 | Toggling some small details will make it return the smallest, or
12 | traverse breadth-first instead of depth-first.
13 |
14 | ``` bash
15 | #!/usr/bin/env bash
16 | # GNU find + bash4 / ksh93v / zsh
17 | # Get the largest file matching pattern in the given directories recursively
18 | ${ZSH_VERSION+false} || emulate ksh
19 | ${BASH_VERSION+shopt -s lastpipe extglob}
20 |
21 | function getLargest {
22 | typeset -A cur top || return
23 | typeset dir x
24 | for dir in "$2"/*/; do
25 | [[ -d $dir ]] || return 0
26 | getLargest "$1" "${dir%/}" || return
27 | top[size]=-1
28 | find "$dir" -maxdepth 1 -type f -name "$1" -printf '%s\0%f\0' | {
29 | while :; do
30 | for x in cur\[{size,name}\]; do
31 | IFS= read -rd '' "$x" || break 2
32 | done
33 | if (( cur[size] > top[size] )); then
34 | top[size]=${cur[size]} top[name]=${cur[name]}
35 | fi
36 | done
37 | printf '%q\n' "${dir}${top[name]}"
38 | }
39 | done
40 | }
41 |
42 | # main pattern dir [ dir ... ]
43 | function main {
44 | if [[ -n $1 ]]; then
45 | typeset dir pattern=$1
46 | shift
47 | for dir; do
48 | [[ -d $dir ]] || return
49 | getLargest "$pattern" "$dir"
50 | done
51 | else
52 | return 1
53 | fi
54 | }
55 |
56 | main "$@"
57 |
58 | # vim: set fenc=utf-8 ff=unix ft=sh :
59 | ```
60 |
61 | ## More examples
62 |
63 | -
64 | -
65 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/user_select.md:
--------------------------------------------------------------------------------
1 | # User selections
2 |
3 | ## Synopsis
4 |
5 | select ; do
6 |
7 | done
8 |
9 | select in ; do
10 |
11 | done
12 |
13 | # alternative, historical and undocumented syntax
14 |
15 | select
16 | {
17 |
18 | }
19 |
20 | select in
21 | {
22 |
23 | }
24 |
25 | ## Description
26 |
27 | This compound command provides a kind of menu. The user is prompted with
28 | a *numbered list* of the given words, and is asked to input the index
29 | number of the word. If a word was selected, the variable `` is set
30 | to this word, and the [list](../../syntax/basicgrammar.md#lists) `` is
31 | executed.
32 |
33 | If no `in ` is given, then the positional parameters are taken as
34 | words (as if `in "$@"` was written).
35 |
36 | Regardless of the functionality, the *number* the user entered is saved
37 | in the variable `REPLY`.
38 |
39 | Bash knows an alternative syntax for the `select` command, enclosing the
40 | loop body in `{...}` instead of `do ... done`:
41 |
42 | select x in 1 2 3
43 | {
44 | echo $x
45 | }
46 |
47 | This syntax is **not documented** and should not be used. I found the
48 | parser definitions for it in 1.x code, and in modern 4.x code. My guess
49 | is that it's there for compatiblity reasons. This syntax is not
50 | specified by POSIX(R).
51 |
52 | ## Examples
53 |
54 | ``` bash
55 | # select in ; do
56 | #
57 | # done
58 |
59 |
60 | # meaning e.g.:
61 |
62 | clear
63 | echo
64 | echo hit number key 1 2 or 3 then ENTER-key
65 | echo ENTER alone is an empty choice and will loop endlessly until Ctrl-C or Ctrl-D
66 | echo
67 |
68 | select OPTIONX in beer whiskey wine liquor ; do
69 |
70 | echo you ordered a $OPTIONX
71 | break # break avoids endless loop -- second line to be executed always
72 |
73 | done
74 |
75 | # place some if else fi business here
76 | # and explain how it makes sense that $OPTIONX is red but OPTIONX is black
77 | # even though both are variables
78 | ```
79 |
80 | ## Portability considerations
81 |
82 | ## See also
83 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/grouping_plain.txt:
--------------------------------------------------------------------------------
1 | ====== Grouping commands ======
2 |
3 | ===== Synopsis =====
4 | { ; }
5 |
6 |
7 | {
8 |
9 | }
10 |
11 |
12 | ===== Description =====
13 |
14 | The [[syntax:basicgrammar#lists|list]] '''' is simply executed in the **current** shell environment. The list must be terminated with a **newline** or **semicolon**. For parsing reasons, the curly braces must be separated from '''' by a **semicolon** and **blanks** if they're in the same line! ((Actually any properly terminated compound command will work without extra separator (also in some other shells), **example**: ''{ while sleep 1; do echo ZzZzzZ; done }'' is valid. But this is not documented, infact the documentation explicitly says that a semicolon or a newline must separate the enclosed list. -- thanks ''geirha'' at Freenode))((The main reason is the fact that in shell grammar, the curly braces are not control operators but reserved words -- TheBonsai))
15 |
16 | This is known as a **group command**. The return status is the [[scripting:basics#exit_codes|exit status (exit code)]] of the list.
17 |
18 | The input and output **filedescriptors** are cumulative:
19 |
20 | {
21 | echo "PASSWD follows"
22 | cat /etc/passwd
23 | echo
24 | echo "GROUPS follows"
25 | cat /etc/group
26 | } >output.txt
27 |
28 |
29 | This compound command also usually is the body of a [[syntax:basicgrammar#shell_function_definitions | function definition]], though not the only compound command that's valid there:
30 |
31 | print_help() {
32 | echo "Options:"
33 | echo "-h This help text"
34 | echo "-f FILE Use config file FILE"
35 | echo "-u USER Run as user USER"
36 | }
37 |
38 |
39 | ===== Examples =====
40 | ==== A Try-Catch block ====
41 |
42 | try_catch() {
43 | { # Try-block:
44 | eval "$@"
45 | } ||
46 | { # Catch-block:
47 | echo "An error occurred"
48 | return -1
49 | }
50 | }
51 | ===== Portability considerations =====
52 |
53 |
54 | ===== See also =====
55 | * [[syntax:ccmd:grouping_subshell | grouping commands in a subshell]]
56 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/local.txt:
--------------------------------------------------------------------------------
1 | ====== The local builtin command ======
2 |
3 | ===== Synopsis =====
4 |
5 | local [option] name[=value] ...
6 |
7 |
8 | ===== Description =====
9 |
10 | ''local'' is identical to [[commands:builtin:declare|declare]] in every way, and takes all the same options, with 3 exceptions:
11 | * Usage outside of a function is an error. Both ''declare'' and ''local'' within a function have the same effect on variable scope, including the -g option.
12 | * ''local'' with no options prints variable names and values in the same format as ''declare'' with no options, except the variables are filtered to print only locals that were set in the same scope from which ''local'' was called. Variables in parent scopes are not printed.
13 | * If name is ‘-’, the set of shell options is made local to the function in which local is invoked: shell options changed using the set builtin inside the function are restored to their original values when the function returns. The restore is effected as if a series of set commands were executed to restore the values that were in place before the function.
14 |
15 | ===== Portability considerations =====
16 |
17 | * ''local'' is not specified by POSIX. Most bourne-like shells don't have a builtin called ''local'', but some such as ''dash'' and the busybox shell do.
18 |
19 | * The behavior of function scope is not defined by POSIX, however local variables are implemented widely by bourne-like shells, and behavior differs substantially. Even the''dash'' shell has local variables.
20 |
21 | * In ksh93, using POSIX-style function definitions, ''typeset'' doesn't set ''local'' variables, but rather acts upon variables of the next-outermost scope (e.g. setting attributes). Using ''typeset'' within functions defined using ksh ''function name {'' syntax, variables follow roughly [[http://community.schemewiki.org/?lexical-scope|lexical-scoping]], except that functions themselves don't have scope, just like Bash. This means that even functions defined within a "function's scope" don't have access to non-local variables except through ''namerefs''.
22 |
23 | ===== See also =====
24 |
25 | * http://wiki.bash-hackers.org/scripting/basics#variable_scope
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bash Hackers Wiki
2 |
3 | The popular [wiki.bash-hackers.org](https://wiki.bash-hackers.org) (original IP address: `83.243.40.67`) site had its DNS expire in April 2023. The owner seems unresponsive, see the [Reddit thread here](https://www.reddit.com/r/bash/comments/12klulf/bashhackersorg_is_now_a_parking_domain/). Fortunately, the web server behind wiki.bash-hackers.org is still running, so I crawled the entire wiki to archive the current versions of all pages.
4 |
5 | This repo tries to preserve and present all this valuable information in a modern way and format, just in case the original wiki won't come back.
6 |
7 | ## Development
8 |
9 | To edit and develop locally install the following packages and run the built in dev webserver:
10 |
11 | ```bash
12 | python3 -m venv env
13 | source env/bin/activate
14 | pip install -r requirements.txt
15 | mkdocs serve
16 | ```
17 |
18 | ## LICENSE
19 |
20 | As per the original wiki.bash-hackers.org:
21 |
22 | > This wiki and any programs found in this wiki are free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
23 | >
24 | > This wiki and its programs are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
25 |
26 | See [LICENSE](LICENSE) for more details.
27 |
28 | ### Modifications
29 |
30 | The original source files that I scraped from the wiki can be found unmodified in [original_source](original_source/).
31 |
32 | Under [docs](docs/) you will find files that are converted from the original DokuWiki Text to Markdown. Furthermore, I slightly modified the organization of the files to be a better fit for MkDocs Material.
33 |
34 | ## COPYRIGHT
35 |
36 | The original copyright belongs to Jan Schampera (TheBonsai) and subsequent contributors, 2007 - 2023.
37 |
38 | It is important to me that copyright and attribution are given where required. If you're one of the original contributors, and you believe I've violated your copyright in any way, please let me know and write me an email at [mail@flokoe.de](mailto:mail@flokoe.de).
39 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/user_select.txt:
--------------------------------------------------------------------------------
1 | ====== User selections ======
2 |
3 | ===== Synopsis =====
4 |
5 | select ; do
6 |
7 | done
8 |
9 |
10 |
11 | select in ; do
12 |
13 | done
14 |
15 |
16 |
17 | # alternative, historical and undocumented syntax
18 |
19 | select
20 | {
21 |
22 | }
23 |
24 | select in
25 | {
26 |
27 | }
28 |
29 |
30 | ===== Description =====
31 | This compound command provides a kind of menu. The user is prompted with a //numbered list// of the given words, and is asked to input the index number of the word. If a word was selected, the variable '''' is set to this word, and the [[syntax:basicgrammar#lists | list]] '''' is executed.
32 |
33 | If no ''in '' is given, then the positional parameters are taken as words (as if ''in "$@"'' was written).
34 |
35 | Regardless of the functionality, the //number// the user entered is saved in the variable ''REPLY''.
36 |
37 | Bash knows an alternative syntax for the ''select'' command, enclosing the loop body in ''{...}'' instead of ''do ... done'':
38 |
39 | select x in 1 2 3
40 | {
41 | echo $x
42 | }
43 |
44 | This syntax is **not documented** and should not be used. I found the parser definitions for it in 1.x code, and in modern 4.x code. My guess is that it's there for compatiblity reasons. This syntax is not specified by POSIX(R).
45 |
46 | ===== Examples =====
47 |
48 | # select in ; do
49 | #
50 | # done
51 |
52 |
53 | # meaning e.g.:
54 |
55 | clear
56 | echo
57 | echo hit number key 1 2 or 3 then ENTER-key
58 | echo ENTER alone is an empty choice and will loop endlessly until Ctrl-C or Ctrl-D
59 | echo
60 |
61 | select OPTIONX in beer whiskey wine liquor ; do
62 |
63 | echo you ordered a $OPTIONX
64 | break # break avoids endless loop -- second line to be executed always
65 |
66 | done
67 |
68 | # place some if else fi business here
69 | # and explain how it makes sense that $OPTIONX is red but OPTIONX is black
70 | # even though both are variables
71 |
72 | ===== Portability considerations =====
73 |
74 | ===== See also =====
75 |
76 |
--------------------------------------------------------------------------------
/original_source/snipplets/kill_bg_job_without_message.txt:
--------------------------------------------------------------------------------
1 | ====== Kill a background job without a message ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: kill, process management, jobs
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Jan Schampera
7 | type: snipplet
8 | ----
9 |
10 | When you start background jobs from within a script (non-interactive shell) and kill it afterwards, you will get a message from the shell that the process was terminated.
11 |
12 | Example:
13 |
14 | #!/bin/bash
15 |
16 | # example background process
17 | sleep 300 &
18 |
19 | # get the PID
20 | BG_PID=$!
21 |
22 | # kill it, hard and mercyless
23 | kill -9 $BG_PID
24 |
25 | echo "Yes, we killed it"
26 |
27 |
28 | You will get something like this:
29 |
30 | $ ./bg_kill1.sh
31 | ./bg_kill1.sh: line 11: 3413 Killed sleep 300
32 | Yes, we killed it
33 |
34 |
35 | This is more or less a normal message. And it can't be easily redirected since it's the shell itself that yells this message, not the command ''kill'' or something else. You would have to redirect the whole script's output.
36 |
37 | It's also useless to temporarily redirect ''stderr'' when you call the ''kill'' command, since the successful termination of the job, the termination of the ''kill'' command and the message from the shell may not happen at the same time. And a blind ''sleep'' after the ''kill'' would be just a workaround.
38 |
39 | The solution is relatively easy: The shell spits that message because it controls the background job, and when it terminates, the shell will tell you whenever possible. Now you just need to tell your shell that it is no longer responsible for that background process. This is done by the ''disown'' command, which can take an internal shell job number (like ''%1'') or a process ID as argument.
40 |
41 |
42 | #!/bin/bash
43 |
44 | # example background process
45 | sleep 300 &
46 |
47 | # get the PID
48 | BG_PID=$!
49 |
50 | ### HERE, YOU TELL THE SHELL TO NOT CARE ANY MORE ###
51 | disown $BG_PID
52 | ###
53 |
54 |
55 | # kill it, hard and mercyless, now without a trace
56 | kill -9 $BG_PID
57 |
58 | echo "Yes, we killed it"
59 |
60 |
61 | That way, you can run and kill background processes without disturbing messages.
62 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/grouping_plain.md:
--------------------------------------------------------------------------------
1 | # Grouping commands
2 |
3 | ## Synopsis
4 |
5 | { ; }
6 |
7 | {
8 |
9 | }
10 |
11 | ## Description
12 |
13 | The [list](../../syntax/basicgrammar.md#lists) `` is simply executed in
14 | the **current** shell environment. The list must be terminated with a
15 | **newline** or **semicolon**. For parsing reasons, the curly braces must
16 | be separated from `` by a **semicolon** and **blanks** if they're
17 | in the same line! [^1][^2]
18 |
19 | This is known as a **group command**. The return status is the [exit
20 | status (exit code)](../../scripting/basics.md#exit_codes) of the list.
21 |
22 | The input and output **filedescriptors** are cumulative:
23 |
24 | {
25 | echo "PASSWD follows"
26 | cat /etc/passwd
27 | echo
28 | echo "GROUPS follows"
29 | cat /etc/group
30 | } >output.txt
31 |
32 | This compound command also usually is the body of a [function
33 | definition](../../syntax/basicgrammar.md#shell_function_definitions), though not
34 | the only compound command that's valid there:
35 |
36 | print_help() {
37 | echo "Options:"
38 | echo "-h This help text"
39 | echo "-f FILE Use config file FILE"
40 | echo "-u USER Run as user USER"
41 | }
42 |
43 | ## Examples
44 |
45 | ### A Try-Catch block
46 |
47 | try_catch() {
48 | { # Try-block:
49 | eval "$@"
50 | } ||
51 | { # Catch-block:
52 | echo "An error occurred"
53 | return -1
54 | }
55 | }
56 |
57 | ## Portability considerations
58 |
59 | ## See also
60 |
61 | * [[syntax:ccmd:grouping_subshell | grouping commands in a subshell]]
62 |
63 | [^1]: Actually any properly terminated compound command will work
64 | without extra separator (also in some other shells), **example**:
65 | `{ while sleep 1; do echo ZzZzzZ; done }` is valid. But this is not
66 | documented, infact the documentation explicitly says that a
67 | semicolon or a newline must separate the enclosed list. -- thanks
68 | `geirha` at Freenode
69 |
70 | [^2]: The main reason is the fact that in shell grammar, the curly
71 | braces are not control operators but reserved words -- TheBonsai
72 |
--------------------------------------------------------------------------------
/original_source/dict/terms/parameter.txt:
--------------------------------------------------------------------------------
1 | ====== Parameter ======
2 |
3 | Also the article for: __variable__, __positional parameter__, __special parameter__
4 |
5 | In Bash, a parameter is simply an entity that stores values and can be referenced. Depending on the type, the parameters can be set directly, only indirectly, or only automatically by the shell.
6 |
7 | Bash knows 3 types of parameters:
8 | * variables
9 | * positional parameters
10 | * special parameters
11 |
12 | ===== variables =====
13 |
14 | A shell variable is a parameter denoted by a //variable name//:
15 | * containing only alphanumeric characters and underscores
16 | * beginning with an alphabetic character or an underscore
17 |
18 | A value can be assigned to a variable, using the variable's name and an equal-sign:
19 | NAME=VALUE
20 |
21 | Once a variable is set, it exists and can only be unset by the ''unset'' builtin command.
22 |
23 | The nullstring is a valid value:
24 |
25 | NAME=
26 | NAME=""
27 |
28 |
29 |
30 | ===== positional parameters =====
31 |
32 | A positional parameter is denoted by a number other than ''0'' (zero).
33 |
34 | Positional parameters reflect the shell's arguments that are not given to the shell itself (in practise, the script arguments, also the function arguments). You can't directly assign to the positional parameters, however, [[commands:builtin:set | the set builtin command]] can be used to indirectly set them.
35 |
36 | The first to ninth positional parameter is referenced by ''$1'' to ''$9''. All following positional parameters (tenth and above) must be referenced by the number given in curly braces, i.e., ''${10}'' or ''${432}''.
37 |
38 | Unlike popular belief, ''$0'' is //not a positional parameter//.
39 |
40 | See also the [[scripting:posparams | scripting article about handling positional parameters]].
41 |
42 | ===== special parameters =====
43 |
44 | There are a bunch of special parameters, which are set by the shell. Direct assignment to them is not possible. These parameter names are formed of one character.
45 |
46 | Please see [[syntax:shellvars]].
47 |
48 |
49 |
50 | ===== See also =====
51 | * Syntax article, internal: [[syntax:pe]]
52 | * Syntax article, internal: [[syntax:shellvars]]
53 | * Scripting article, internal: [[scripting:posparams]]
54 |
55 |
--------------------------------------------------------------------------------
/docs/dict/parameter.md:
--------------------------------------------------------------------------------
1 | # Parameter
2 |
3 | Also the article for: variable, positional
4 | parameter, special parameter
5 |
6 | In Bash, a parameter is simply an entity that stores values and can be
7 | referenced. Depending on the type, the parameters can be set directly,
8 | only indirectly, or only automatically by the shell.
9 |
10 | Bash knows 3 types of parameters:
11 |
12 | - variables
13 | - positional parameters
14 | - special parameters
15 |
16 | ## variables
17 |
18 | A shell variable is a parameter denoted by a *variable name*:
19 |
20 | - containing only alphanumeric characters and underscores
21 | - beginning with an alphabetic character or an underscore
22 |
23 | A value can be assigned to a variable, using the variable's name and an
24 | equal-sign:
25 |
26 | NAME=VALUE
27 |
28 | Once a variable is set, it exists and can only be unset by the `unset`
29 | builtin command.
30 |
31 | The nullstring is a valid value:
32 |
33 | NAME=
34 | NAME=""
35 |
36 | ## positional parameters
37 |
38 | A positional parameter is denoted by a number other than `0` (zero).
39 |
40 | Positional parameters reflect the shell's arguments that are not given
41 | to the shell itself (in practise, the script arguments, also the
42 | function arguments). You can't directly assign to the positional
43 | parameters, however, [the set builtin command](../commands/builtin/set.md)
44 | can be used to indirectly set them.
45 |
46 | The first to ninth positional parameter is referenced by `$1` to `$9`.
47 | All following positional parameters (tenth and above) must be referenced
48 | by the number given in curly braces, i.e., `${10}` or `${432}`.
49 |
50 | Unlike popular belief, `$0` is *not a positional parameter*.
51 |
52 | See also the [scripting article about handling positional
53 | parameters](../scripting/posparams.md).
54 |
55 | ## special parameters
56 |
57 | There are a bunch of special parameters, which are set by the shell.
58 | Direct assignment to them is not possible. These parameter names are
59 | formed of one character.
60 |
61 | Please see [shellvars](../syntax/shellvars.md).
62 |
63 | ## See also
64 |
65 | - Syntax article, internal: [pe](../syntax/pe.md)
66 | - Syntax article, internal: [shellvars](../syntax/shellvars.md)
67 | - Scripting article, internal: [posparams](../scripting/posparams.md)
68 |
--------------------------------------------------------------------------------
/original_source/wishes.txt:
--------------------------------------------------------------------------------
1 | ====== Wishlist ======
2 |
3 | **NOTE:** Due to neverending SPAM from various IPs (the usual pharmacy-links and whatnot nonsens) this page was made readonly.
4 |
5 | Another way of submitting wishes is the following form:
6 | {{contact>subj=Wiki: wishlist}}
7 |
8 |
9 | ===== Token Recognition and Shell Grammar =====
10 |
11 | a more human-readable version of the following topics:
12 |
13 | * [[http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_03]]
14 | * [[http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_10]]
15 |
16 | ===== General =====
17 | A simplified version of `man bash' and interesting bash tricks.:-)
18 | > The whole site is meant to be like that: a simplified or better human-readable collection of manpage snipplets. Maybe a page with the main topics of bash manpage that link to the proper articles would be good (I just don't have enough articles heh) - a kind of summary page --- Jan
19 |
20 |
21 | ===== Some ideas =====
22 |
23 | **hmm maybe some of this stuff could make it somewhere to the wiki...:)**
24 |
25 | * an article about how to do ksh coprocess in bash (:V4: may be obsolete regarding [[bash4 | Bash 4 features]])
26 | - single way -> process substitution
27 | - 2 way name pipes
28 | * let's write a interactive tutorial script that teaches readline/bash (like C-h t in emacs, or vimtutor or vilearn)
29 | * programmable history: http://pastebin.bash-hackers.org/index.php?show=22
30 |
31 | ===== Implemented =====
32 |
33 | ==== Bash For Loop Multi-word lines ====
34 |
35 | From this solution on modifying the internal Field Separator (IFS) in bash I found here:
36 | * http://linux.derkeiler.com/Mailing-Lists/Debian/2006-08/msg00462.html
37 |
38 | > added to [[syntax:ccmd:classic_for|the for-loop-article]] as example, but also made some critical comments; thanks --- Jan
39 |
40 | ==== Getopts tutorial ====
41 | * My school offers a UNIX programming course (C, shell, etc.). I use this site extensively to help my friends taking this course learn concepts such as I/O redirection etc. As it gets more advanced they need to do option parsing. Therefore I would like to see a "getopts illustrated" article or some such, showing the breakdown of how it parses parameters.
42 | * "[[howto:getopts_tutorial]]" is a first step for the getopts stuff - provide ideas
--------------------------------------------------------------------------------
/docs/commands/builtin/kill.md:
--------------------------------------------------------------------------------
1 | # The kill builtin command
2 |
3 | ## Synopsis
4 |
5 | kill [-s SIGNAL | -n SIGNALNUMBER | -SIGNAL] PID|JOB
6 |
7 | kill -l|-L [SIGNAL...]
8 |
9 | ## Description
10 |
11 | The `kill` command is used to send signals to processes specified by
12 | their `PID` or their `JOB`-specification.
13 |
14 | The signal(s) to be specified can have the following formats:
15 |
16 | - Numerical: The signal is specified using its constant numeric value.
17 | Be aware that not all systems have identical numbers for the
18 | signals.
19 | - Symbolic (long): The signal is specified using the same name that is
20 | used for the constant/macro in the C API (`SIG`)
21 | - Symbolic (short): The signal is specified using the name from the C
22 | API without the `SIG`-prefix (``)
23 |
24 | Without any specified signal, the command sends the `SIGTERM`-signal.
25 |
26 | The `kill` command is a Bash builtin command instead of relying on the
27 | external `kill` command of the operating system to
28 |
29 | - be able to use shell job specifications instead of Unix process IDs
30 | - be able to send signals ("kill something") also, when your process
31 | limit is reached
32 |
33 | ### Options
34 |
35 | |Option|Description|
36 | |------|-----------|
37 | |`-s SIGNAL`|specifies the signal to send|
38 | |`-n SIGNALNUMBER`|specifies the signal to send|
39 | |`-SIGNAL`|specifies the signal to send|
40 | |`-l [SIGNAL...]`|Lists supported/known signal numbers and their symbolic name. If `SIGNAL` is given, only list this signal, translated (if a number is given the symbolic name is printed, and vice versa)|
41 | |`-L [SIGNAL...]`|Same as `-l [SIGNAL]` (compatiblity option)|
42 |
43 | ### Return status
44 |
45 | |Status|Reason|
46 | |------|------|
47 | |0|no error/success|
48 | |!=0|invalid option|
49 | |!=0|invalid signal specification|
50 | |!=0|error returned by the system function (e.g. insufficient permissions to send to a specific process)|
51 |
52 | ## Examples
53 |
54 | ### List supported signals
55 |
56 | kill -l
57 |
58 | ### Send KILL to a process ID
59 |
60 | kill -9 12345
61 |
62 | kill -KILL 12345
63 |
64 | kill -SIGKILL 12345
65 |
66 | ## Portability considerations
67 |
68 | - POSIX(R) and ISO C only standardize symbolic signal names (no
69 | numbers) and a default action
70 |
71 | ## See also
72 |
--------------------------------------------------------------------------------
/docs/commands/builtin/trap.md:
--------------------------------------------------------------------------------
1 | # The trap builtin command
2 |
3 | ## Synopsis
4 |
5 | trap [-lp] [[ARGUMENT] SIGNAL]
6 |
7 | ## Description
8 |
9 | The `trap` command is used to "trap" signals and other events. In this
10 | context, "trapping" means to install handler code.
11 |
12 | The shell code `ARGUMENT` is to be read and executed whenever the shell
13 | receives a signal or another event `SIGNAL`. The given `SIGNAL`
14 | specification can be
15 |
16 | - the name of a signal with the SIG prefix, e.g. `SIGTERM`
17 | - the name of a signal without the SIG prefix, e.g. `TERM`
18 | - the number of a signal (see `trap -l`), e.g. `15`
19 | - the name or number of a special event (see table below), e.g. `EXIT`
20 |
21 | Without any options or operands, `trap` prints a list of installed traps
22 | in a reusable format (equivalent to the `-p` option).
23 |
24 | Special `ARGUMENT`s
25 |
26 | - if `ARGUMENT` is absent or `-` (dash), the signal/event handler is
27 | reset to its original value
28 | - if `ARGUMENT` is the null string, the signal/event is ignored
29 |
30 | Special events
31 |
32 | |Name|Code|Description|
33 | |----|----|-----------|
34 | |`EXIT`|0|executed on shell exit|
35 | |`DEBUG`||executed before every simple command|
36 | |`RETURN`||executed when a shell function or a sourced code finishes executing|
37 | |`ERR`||executed each time a command's failure would cause the shell to exit when the [`-e` option (`errexit`)](../../commands/builtin/set.md) is enabled|
38 |
39 | ### Options
40 |
41 | |Option|Description|
42 | |------|-----------|
43 | |`-l`|print a list of signal names and their corresponding numbers|
44 | |`-p`|display the trap commands associated with each signal specification in a reusable format|
45 |
46 | ### Return status
47 |
48 | |Status|Reason|
49 | |------|------|
50 | |0|no error/success|
51 | |!=0|invalid option|
52 | |!=0|invalid signal specification|
53 |
54 | ## Examples
55 |
56 | ### List installed traps
57 |
58 | trap
59 |
60 | ### Ignore terminal interrupt (Ctrl-C, SIGINT)
61 |
62 | trap '' INT
63 |
64 | ## Portability considerations
65 |
66 | - `trap` is specified by POSIX(R) without the `-l` and `-p` options
67 | - in POSIX(R), beside signals, only `EXIT` (0) is valid as an event
68 |
69 | ## See also
70 |
71 | - [the set command](../../commands/builtin/set.md) for the `-e` (`errexit`)
72 | option
73 |
--------------------------------------------------------------------------------
/docs/commands/builtin/local.md:
--------------------------------------------------------------------------------
1 | # The local builtin command
2 |
3 | ## Synopsis
4 |
5 | local [option] name[=value] ...
6 |
7 | ## Description
8 |
9 | `local` is identical to [declare](../../commands/builtin/declare.md) in every
10 | way, and takes all the same options, with 3 exceptions:
11 |
12 | - Usage outside of a function is an error. Both `declare` and `local`
13 | within a function have the same effect on variable scope, including
14 | the -g option.
15 | - `local` with no options prints variable names and values in the same
16 | format as `declare` with no options, except the variables are
17 | filtered to print only locals that were set in the same scope from
18 | which `local` was called. Variables in parent scopes are not
19 | printed.
20 | - If name is '-', the set of shell options is made local to the
21 | function in which local is invoked: shell options changed using the
22 | set builtin inside the function are restored to their original
23 | values when the function returns. The restore is effected as if a
24 | series of set commands were executed to restore the values that were
25 | in place before the function.
26 |
27 | ## Portability considerations
28 |
29 | - `local` is not specified by POSIX. Most bourne-like shells don't
30 | have a builtin called `local`, but some such as `dash` and the
31 | busybox shell do.
32 |
33 | - The behavior of function scope is not defined by POSIX, however
34 | local variables are implemented widely by bourne-like shells, and
35 | behavior differs substantially. Even the`dash` shell has local
36 | variables.
37 |
38 | - In ksh93, using POSIX-style function definitions, `typeset` doesn't
39 | set `local` variables, but rather acts upon variables of the
40 | next-outermost scope (e.g. setting attributes). Using `typeset`
41 | within functions defined using ksh `function name {` syntax,
42 | variables follow roughly
43 | [lexical-scoping](http://community.schemewiki.org/?lexical-scope),
44 | except that functions themselves don't have scope, just like Bash.
45 | This means that even functions defined within a "function's
46 | scope" don't have access to non-local variables except through
47 | `namerefs`.
48 |
49 | ## See also
50 |
51 | - [The basics of shell scripting: Variable scope](../../scripting/basics.md#variable-scope)
52 |
--------------------------------------------------------------------------------
/docs/snipplets/kill_bg_job_without_message.md:
--------------------------------------------------------------------------------
1 | # Kill a background job without a message
2 |
3 | ---- dataentry snipplet ---- snipplet_tags: kill, process
4 | management, jobs LastUpdate_dt: 2010-07-31 Contributors: Jan Schampera
5 | type: snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | When you start background jobs from within a script (non-interactive
10 | shell) and kill it afterwards, you will get a message from the shell
11 | that the process was terminated.
12 |
13 | Example:
14 |
15 | #!/bin/bash
16 |
17 | # example background process
18 | sleep 300 &
19 |
20 | # get the PID
21 | BG_PID=$!
22 |
23 | # kill it, hard and mercyless
24 | kill -9 $BG_PID
25 |
26 | echo "Yes, we killed it"
27 |
28 | You will get something like this:
29 |
30 | $ ./bg_kill1.sh
31 | ./bg_kill1.sh: line 11: 3413 Killed sleep 300
32 | Yes, we killed it
33 |
34 | This is more or less a normal message. And it can't be easily
35 | redirected since it's the shell itself that yells this message, not the
36 | command `kill` or something else. You would have to redirect the whole
37 | script's output.
38 |
39 | It's also useless to temporarily redirect `stderr` when you call the
40 | `kill` command, since the successful termination of the job, the
41 | termination of the `kill` command and the message from the shell may not
42 | happen at the same time. And a blind `sleep` after the `kill` would be
43 | just a workaround.
44 |
45 | The solution is relatively easy: The shell spits that message because it
46 | controls the background job, and when it terminates, the shell will tell
47 | you whenever possible. Now you just need to tell your shell that it is
48 | no longer responsible for that background process. This is done by the
49 | `disown` command, which can take an internal shell job number (like
50 | `%1`) or a process ID as argument.
51 |
52 | #!/bin/bash
53 |
54 | # example background process
55 | sleep 300 &
56 |
57 | # get the PID
58 | BG_PID=$!
59 |
60 | ### HERE, YOU TELL THE SHELL TO NOT CARE ANY MORE ###
61 | disown $BG_PID
62 | ###
63 |
64 |
65 | # kill it, hard and mercyless, now without a trace
66 | kill -9 $BG_PID
67 |
68 | echo "Yes, we killed it"
69 |
70 | That way, you can run and kill background processes without disturbing
71 | messages.
72 |
--------------------------------------------------------------------------------
/docs/snipplets/wrapperargs.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - arguments
4 | - quoting
5 | - escape
6 | - quote
7 | - wrapper
8 | - generate
9 | ---
10 |
11 | # Generate code with own arguments properly quoted
12 |
13 | There are situations where Bash code needs to generate Bash code. A
14 | script that writes out another script the user or cron may start, for
15 | example.
16 |
17 | The general issue is easy, just write out text to the file.
18 |
19 | A specific detail of it is tricky: If the generated script needs to call
20 | a command using the arguments the first original script got, you have
21 | problem in writing out the correct code.
22 |
23 | I.e. if you run your generator script like
24 |
25 | ./myscript "give me 'some' water"
26 |
27 | then this script should generate code that looks like
28 |
29 | echo give me 'some' water"
30 |
31 | you need correct escapes or quotes to not generate shell special
32 | characters out of normal text (like embedded dollar signs `$`).
33 |
34 | **Solution:**
35 |
36 | A loop over the own arguments that writes out properly quoted/escaped
37 | code to the generated script file
38 |
39 | There are two (maybe more) easy options:
40 |
41 | - writing out singlequoted strings and handle the embedded
42 | singlequotes
43 | - the [printf command](../commands/builtin/printf.md) knows the `%q` format
44 | specification, which will print a string (like `%s` does), but with
45 | all shell special characters escaped
46 |
47 | ## Using singlequoted string
48 |
49 | #!/bin/bash
50 |
51 | # first option:
52 | # generate singlequoted strings out of your own arguments and handle embedded singlequotes
53 | # here to call 'echo' in the generated script
54 |
55 | {
56 | printf "#!/bin/bash\n\n"
57 | printf "echo "
58 | for arg; do
59 | arg=${arg/\'/\'\\\'\'}
60 | printf "'%s' " "${arg}"
61 | done
62 |
63 | printf "\n"
64 | } >s2
65 |
66 | The generated script will look like:
67 |
68 | #!/bin/bash
69 |
70 | echo 'fir$t' 'seco "ond"' 'thir'\''d'
71 |
72 | ## Using printf
73 |
74 | The second method is easier, though more or less Bash-only (due to the
75 | `%q` in printf):
76 |
77 | #!/bin/bash
78 |
79 | {
80 | printf "#!/bin/bash\n\n"
81 | printf "echo "
82 | for arg; do
83 | printf '%q ' "$arg"
84 | done
85 |
86 | printf "\n"
87 | } >s2
88 |
89 | The generated script will look like:
90 |
91 | #!/bin/bash
92 |
93 | echo fir\$t seco\ \"ond\" thir\'d
94 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/trap.txt:
--------------------------------------------------------------------------------
1 | ====== The trap builtin command ======
2 |
3 | ===== Synopsis =====
4 | trap [-lp] [[ARGUMENT] SIGNAL]
5 |
6 | ===== Description =====
7 | The ''trap'' command is used to "trap" signals and other events. In this context, "trapping" means to install handler code.
8 |
9 | The shell code ''ARGUMENT'' is to be read and executed whenever the shell receives a signal or another event ''SIGNAL''. The given ''SIGNAL'' specification can be
10 | * the name of a signal with the SIG prefix, e.g. ''SIGTERM''
11 | * the name of a signal without the SIG prefix, e.g. ''TERM''
12 | * the number of a signal (see ''trap -l''), e.g. ''15''
13 | * the name or number of a special event (see table below), e.g. ''EXIT''
14 |
15 | Without any options or operands, ''trap'' prints a list of installed traps in a reusable format (equivalent to the ''-p'' option).
16 |
17 | Special ''ARGUMENT''s
18 | * if ''ARGUMENT'' is absent or ''-'' (dash), the signal/event handler is reset to its original value
19 | * if ''ARGUMENT'' is the null string, the signal/event is ignored
20 |
21 | Special events
22 | ^Name ^Code ^Description ^
23 | |''EXIT'' |0 |executed on shell exit |
24 | |''DEBUG'' | |executed before every simple command |
25 | |''RETURN'' | |executed when a shell function or a sourced code finishes executing |
26 | |''ERR'' | |executed each time a command's failure would cause the shell to exit when the [[commands:builtin:set|''-e'' option (''errexit'')]] is enabled |
27 |
28 | ==== Options ====
29 |
30 | ^Option ^Description ^
31 | |''-l'' |print a list of signal names and their corresponding numbers |
32 | |''-p'' |display the trap commands associated with each signal specification in a reusable format |
33 |
34 | ==== Return status ====
35 |
36 | ^Status ^Reason ^
37 | |0 |no error/success |
38 | |!=0 |invalid option |
39 | |!=0 |invalid signal specification |
40 |
41 | ===== Examples =====
42 |
43 | ==== List installed traps ====
44 |
45 |
46 | trap
47 |
48 |
49 | ==== Ignore terminal interrupt (Ctrl-C, SIGINT) ====
50 |
51 |
52 | trap '' INT
53 |
54 |
55 | ===== Portability considerations =====
56 |
57 | * ''trap'' is specified by POSIX(R) without the ''-l'' and ''-p'' options
58 | * in POSIX(R), beside signals, only ''EXIT'' (0) is valid as an event
59 |
60 | ===== See also =====
61 |
62 | * [[commands:builtin:set|the set command]] for the ''-e'' (''errexit'') option
63 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/kill.txt:
--------------------------------------------------------------------------------
1 | ====== The kill builtin command ======
2 |
3 | ===== Synopsis =====
4 | kill [-s SIGNAL | -n SIGNALNUMBER | -SIGNAL] PID|JOB
5 | kill -l|-L [SIGNAL...]
6 |
7 | ===== Description =====
8 | The ''kill'' command is used to send signals to processes specified by their ''PID'' or their ''JOB''-specification.
9 |
10 | The signal(s) to be specified can have the following formats:
11 | * Numerical: The signal is specified using its constant numeric value. Be aware that not all systems have identical numbers for the signals.
12 | * Symbolic (long): The signal is specified using the same name that is used for the constant/macro in the C API (''SIG'')
13 | * Symbolic (short): The signal is specified using the name from the C API without the ''SIG''-prefix ('''')
14 |
15 | Without any specified signal, the command sends the ''SIGTERM''-signal.
16 |
17 | The ''kill'' command is a Bash builtin command instead of relying on the external ''kill'' command of the operating system to
18 | * be able to use shell job specifications instead of Unix process IDs
19 | * be able to send signals ("kill something") also, when your process limit is reached
20 |
21 | ==== Options ====
22 |
23 | ^Option ^Description ^
24 | |''-s SIGNAL'' |specifies the signal to send |
25 | |''-n SIGNALNUMBER'' |specifies the signal to send |
26 | |''-SIGNAL'' |specifies the signal to send |
27 | |''-l [SIGNAL...]'' |Lists supported/known signal numbers and their symbolic name. If ''SIGNAL'' is given, only list this signal, translated (if a number is given the symbolic name is printed, and vice versa) |
28 | |''-L [SIGNAL...]'' |Same as ''-l [SIGNAL]'' (compatiblity option) |
29 |
30 | ==== Return status ====
31 |
32 | ^Status ^Reason ^
33 | |0 |no error/success |
34 | |!=0 |invalid option |
35 | |!=0 |invalid signal specification |
36 | |!=0 |error returned by the system function (e.g. insufficient permissions to send to a specific process) |
37 |
38 | ===== Examples =====
39 |
40 | ==== List supported signals ====
41 |
42 |
43 | kill -l
44 |
45 |
46 | ==== Send KILL to a process ID ====
47 |
48 |
49 | kill -9 12345
50 |
51 |
52 |
53 | kill -KILL 12345
54 |
55 |
56 |
57 | kill -SIGKILL 12345
58 |
59 |
60 | ===== Portability considerations =====
61 |
62 | * POSIX(R) and ISO C only standardize symbolic signal names (no numbers) and a default action
63 |
64 | ===== See also =====
65 |
66 |
--------------------------------------------------------------------------------
/docs/commands/builtin/exec.md:
--------------------------------------------------------------------------------
1 | # The exec builtin command
2 |
3 | ## Synopsis
4 |
5 | exec [-a NAME] [-cl] [COMMAND] [ARG...] [REDIRECTION...]
6 |
7 | ## Description
8 |
9 | The `exec` builtin command is used to
10 |
11 | - **replace** the shell with a given program (executing it, **not as
12 | new process**)
13 | - set redirections for the program to execute or for the current shell
14 |
15 | If only redirections are given, the redirections affect the current
16 | shell without executing any program.
17 |
18 | ### Options
19 |
20 | |Option|Description|
21 | |------|-----------|
22 | |`-a NAME`|Passes `NAME` as zeroth argument for the program to be executed|
23 | |`-c`|Execute the program with an empty (cleared) environment|
24 | |`-l`|Prepends a dash (`-`) to the zeroth argument of the program to be executed, similar to what the `login` program does|
25 |
26 | ### Exit status
27 |
28 | - on redirection errors it returns 1, otherwise 0
29 | - on exec failures:
30 | - a non-interactive shell terminates; if the [shell option
31 | execfail](../../internals/shell_options.md#execfail) is set `exec`
32 | returns failure
33 | - in an interactive shell, `exec` returns failure
34 |
35 | ## Examples
36 |
37 | ### Wrapper around a program
38 |
39 | ``` bash
40 | myprog=/bin/ls
41 | echo "This is the wrapper script, it will exec $myprog"
42 |
43 | # do some vodoo here, probably change the arguments etc.
44 | # well, stuff a wrapper is there for
45 |
46 | exec "$myprog" "$@"
47 | ```
48 |
49 | ### Open a file as input for the script
50 |
51 | ``` bash
52 | # open it
53 | exec 3< input.txt
54 |
55 | # for example: read one line from the file(-descriptor)
56 | read -u 3 LINE
57 | # or
58 | read LINE <&3
59 |
60 | # finally, close it
61 | exec 3<&-
62 | ```
63 |
64 | ### Overall script logfile
65 |
66 | To redirect the whole `stdout` and `stderr` of the shell or shellscript
67 | to a file, you can use the `exec` builtin command:
68 |
69 | ``` bash
70 | exec >/var/adm/my.log 2>&1
71 |
72 | # script continues here...
73 | ```
74 |
75 | ## Portability considerations
76 |
77 | *POSIX(r) specifies error code ranges:
78 | * if ''exec'' can't find the program to execute, the error code shall be 126
79 | * on a redirection error, the error code shall be between 1 and 125
80 | * the ''-a NAME'' option appeared in Bash 4.2-alpha
81 | * POSIX(r) does **not** specify any options for ''exec'' (like ''-c'', ''-l'', ''-a NAME'').
82 |
83 | ## See also
84 |
85 | - [redirection](../../syntax/redirection.md)
86 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/exec.txt:
--------------------------------------------------------------------------------
1 | ====== The exec builtin command ======
2 |
3 | ===== Synopsis =====
4 | exec [-a NAME] [-cl] [COMMAND] [ARG...] [REDIRECTION...]
5 |
6 | ===== Description =====
7 | The ''exec'' builtin command is used to
8 | * **replace** the shell with a given program (executing it, **not as new process**)
9 | * set redirections for the program to execute or for the current shell
10 |
11 | If only redirections are given, the redirections affect the current shell without executing any program.
12 |
13 | ==== Options ====
14 |
15 | ^Option^Description^
16 | |''-a NAME'' |Passes ''NAME'' as zeroth argument for the program to be executed |
17 | |''-c'' |Execute the program with an empty (cleared) environment |
18 | |''-l'' |Prepends a dash (''-'') to the zeroth argument of the program to be executed, similar to what the ''login'' program does |
19 |
20 | ==== Exit status ====
21 |
22 | * on redirection errors it returns 1, otherwise 0
23 | * on exec failures:
24 | * a non-interactive shell terminates; if the [[internals:shell_options#execfail | shell option execfail]] is set ''exec'' returns failure
25 | * in an interactive shell, ''exec'' returns failure
26 |
27 | ===== Examples =====
28 |
29 | ==== Wrapper around a program ====
30 |
31 | myprog=/bin/ls
32 | echo "This is the wrapper script, it will exec $myprog"
33 |
34 | # do some vodoo here, probably change the arguments etc.
35 | # well, stuff a wrapper is there for
36 |
37 | exec "$myprog" "$@"
38 |
39 |
40 | ==== Open a file as input for the script ====
41 |
42 | # open it
43 | exec 3< input.txt
44 |
45 | # for example: read one line from the file(-descriptor)
46 | read -u 3 LINE
47 | # or
48 | read LINE <&3
49 |
50 | # finally, close it
51 | exec 3<&-
52 |
53 |
54 | ==== Overall script logfile ====
55 |
56 | To redirect the whole ''stdout'' and ''stderr'' of the shell or shellscript to a file, you can use the ''exec'' builtin command:
57 |
58 | exec >/var/adm/my.log 2>&1
59 |
60 | # script continues here...
61 |
62 |
63 | ===== Portability considerations =====
64 |
65 | *POSIX(r) specifies error code ranges:
66 | * if ''exec'' can't find the program to execute, the error code shall be 126
67 | * on a redirection error, the error code shall be between 1 and 125
68 | * the ''-a NAME'' option appeared in Bash 4.2-alpha
69 | * POSIX(r) does **not** specify any options for ''exec'' (like ''-c'', ''-l'', ''-a NAME'').
70 |
71 | ===== See also =====
72 | * [[syntax:redirection]]
73 |
--------------------------------------------------------------------------------
/docs/howto/testing-your-scripts.md:
--------------------------------------------------------------------------------
1 | The one of the simplest way to check your bash/sh scripts is run it and
2 | check it output or run it and check the result. This tutorial shows
3 | how-to use [bashtest](https://github.com/pahaz/bashtest) tool for
4 | testing your scripts.
5 |
6 | ### Write simple util
7 |
8 | We have a simple **stat.sh** script:
9 |
10 | #!/usr/bin/env bash
11 |
12 | if [ -z "$1" ]
13 | then
14 | DIR=./
15 | else
16 | DIR=$1
17 | fi
18 |
19 | echo "Evaluate *.py statistics"
20 | FILES=$(find $DIR -name '*.py' | wc -l)
21 | LINES=$((find $DIR -name '*.py' -print0 | xargs -0 cat) | wc -l)
22 | echo "PYTHON FILES: $FILES"
23 | echo "PYTHON LINES: $LINES"
24 |
25 | This script evaluate the number of python files and the number of python
26 | code lines in the files. We can use it like **`./stat.sh `**
27 |
28 | ### Create testsuit
29 |
30 | Then make test suits for **stat.sh**. We make a directory **testsuit**
31 | which contain test python files.
32 |
33 | **testsuit/main.py**
34 |
35 | import foo
36 | print(foo)
37 |
38 | **testsuit/foo.py**
39 |
40 | BAR = 1
41 | BUZ = BAR + 2
42 |
43 | Ok! Our test suit is ready! We have 2 python files which contains 4
44 | lines of code.
45 |
46 | ### Write bashtests
47 |
48 | Lets write tests. We just write a shell command for testing our work.
49 |
50 | Create file **tests.bashtest**:
51 |
52 | $ ./stat.sh testsuit/
53 | Evaluate *.py statistics
54 | PYTHON FILES: 2
55 | PYTHON LINES: 4
56 |
57 | This is our test! This is simple. Try to run it.
58 |
59 | # install bashtest if required!
60 | $ pip install bashtest
61 |
62 | # run tests
63 | $ bashtest *.bashtest
64 | 1 items passed all tests:
65 | 1 tests in tests.bashtest
66 | 1 tests in 1 items.
67 | 1 passed and 0 failed.
68 | Test passed.
69 |
70 | Thats all. We wrote one test. You can write more tests if you want.
71 |
72 | $ ls testsuit/
73 | foo.py main.py
74 |
75 | $ ./stat.sh testsuit/
76 | Evaluate *.py statistics
77 | PYTHON FILES: 2
78 | PYTHON LINES: 4
79 |
80 | And run tests again:
81 |
82 | $ bashtest *.bashtest
83 | 1 items passed all tests:
84 | 2 tests in tests.bashtest
85 | 2 tests in 1 items.
86 | 2 passed and 0 failed.
87 | Test passed.
88 |
89 | You can find more **.bashtest** examples in the [bashtest github
90 | repo](https://github.com/pahaz/bashtest). You can also write your
91 | question or report a bug
92 | [here](https://github.com/pahaz/bashtest/issues).
93 |
94 | Happy testing!
95 |
--------------------------------------------------------------------------------
/original_source/snipplets/wrapperargs.txt:
--------------------------------------------------------------------------------
1 | ====== Generate code with own arguments properly quoted ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags: arguments, quoting, escaping, wrapper
5 | LastUpdate_dt: 2010-07-31
6 | Contributors: Jan Schampera
7 | type: snipplet
8 | ----
9 |
10 | ^ Keywords: | arguments,escape,quote,wrapper,generate |
11 | ^ Contributor: | self |
12 |
13 | There are situations where Bash code needs to generate Bash code. A script that writes out another script the user or cron may start, for example.
14 |
15 | The general issue is easy, just write out text to the file.
16 |
17 | A specific detail of it is tricky: If the generated script needs to call a command using the arguments the first original script got, you have problem in writing out the correct code.
18 |
19 | I.e. if you run your generator script like
20 | ./myscript "give me 'some' water"
21 | then this script should generate code that looks like
22 | echo give me 'some' water"
23 | you need correct escapes or quotes to not generate shell special characters out of normal text (like embedded dollar signs ''$'').
24 |
25 |
26 | **__Solution:__**
27 |
28 | A loop over the own arguments that writes out properly quoted/escaped code to the generated script file
29 |
30 | There are two (maybe more) easy options:
31 | * writing out singlequoted strings and handle the embedded singlequotes
32 | * the [[commands:builtin:printf | printf command]] knows the ''%q'' format specification, which will print a string (like ''%s'' does), but with all shell special characters escaped
33 |
34 | ===== Using singlequoted string =====
35 |
36 |
37 | #!/bin/bash
38 |
39 | # first option:
40 | # generate singlequoted strings out of your own arguments and handle embedded singlequotes
41 | # here to call 'echo' in the generated script
42 |
43 | {
44 | printf "#!/bin/bash\n\n"
45 | printf "echo "
46 | for arg; do
47 | arg=${arg/\'/\'\\\'\'}
48 | printf "'%s' " "${arg}"
49 | done
50 |
51 | printf "\n"
52 | } >s2
53 |
54 |
55 | The generated script will look like:
56 |
57 |
58 | #!/bin/bash
59 |
60 | echo 'fir$t' 'seco "ond"' 'thir'\''d'
61 |
62 |
63 | ===== Using printf =====
64 |
65 | The second method is easier, though more or less Bash-only (due to the ''%q'' in printf):
66 |
67 |
68 | #!/bin/bash
69 |
70 | {
71 | printf "#!/bin/bash\n\n"
72 | printf "echo "
73 | for arg; do
74 | printf '%q ' "$arg"
75 | done
76 |
77 | printf "\n"
78 | } >s2
79 |
80 |
81 | The generated script will look like:
82 |
83 |
84 | #!/bin/bash
85 |
86 | echo fir\$t seco\ \"ond\" thir\'d
87 |
88 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/caller.txt:
--------------------------------------------------------------------------------
1 | ====== The caller builtin command ======
2 |
3 | ===== Synopsis =====
4 | caller [FRAMENUMBER]
5 |
6 | ===== Description =====
7 | The ''caller'' builtin command is used to print execution frames of subroutine calls. Without giving a framenumber, the topmost execution frame information is printed ("who called me") wile linenumber and filename.
8 |
9 | When an execution frame number is given (0 - topmost), the linenumber, the subroutine (function) and the filename is printed. When an invalid execution frame number is given, it exists ''FALSE''. This way it can be used in a loop (see the examples section below).
10 |
11 | ===== Examples =====
12 |
13 | ==== Simple stack trace ====
14 |
15 | The code below defines a function ''die'' that is used to exit the program. It prints a list of execution frames, starting with the topmost frame (0). The topmost frame is the "caller of the die function", in this case function "f1".
16 |
17 | This way, you can print a "stack trace" for debugging or logging purposes.
18 |
19 | The code is made very simple, just to show the basic purposes.
20 |
21 |
22 | #!/bin/bash
23 |
24 | die() {
25 | local frame=0
26 | while caller $frame; do
27 | ((++frame));
28 | done
29 | echo "$*"
30 | exit 1
31 | }
32 |
33 | f1() { die "*** an error occured ***"; }
34 | f2() { f1; }
35 | f3() { f2; }
36 |
37 | f3
38 |
39 |
40 | **Output**
41 |
42 | 12 f1 ./callertest.sh
43 | 13 f2 ./callertest.sh
44 | 14 f3 ./callertest.sh
45 | 16 main ./callertest.sh
46 | *** an error occured ***
47 |
48 |
49 | ===== Notes =====
50 | * ''caller'' produces no output unless used within a script that's run from a real file. It isn't particularly useful for interactive use, but can be used to create a decent ''die'' function to track down errors in moderately complex scripts. { bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'
51 | * For more sophisticated debugging, Bash extended debugging features are available and a number of special parameters that give more detail than caller (e.g. BASH_ARG{C,V}). Tools such as [[ http://bashdb.sourceforge.net/|Bashdb ]] can assist in using some of Bash's more advanced debug features.
52 | * The Bash manpage and help text specifies that the argument to ''caller'' is an "expr" (whatever that means). Only an integer is actually allowed, with no special interpretation of an "expression" as far as we can tell.
53 |
54 | ===== Portability considerations =====
55 | * ''caller'' is not specified by POSIX(R)
56 | * the ''caller'' builtin command appeared in Bash version 3.0
57 |
58 | ===== See also =====
--------------------------------------------------------------------------------
/docs/commands/builtin/caller.md:
--------------------------------------------------------------------------------
1 | # The caller builtin command
2 |
3 | ## Synopsis
4 |
5 | caller [FRAMENUMBER]
6 |
7 | ## Description
8 |
9 | The `caller` builtin command is used to print execution frames of
10 | subroutine calls. Without giving a framenumber, the topmost execution
11 | frame information is printed ("who called me") wile linenumber and
12 | filename.
13 |
14 | When an execution frame number is given (0 - topmost), the linenumber,
15 | the subroutine (function) and the filename is printed. When an invalid
16 | execution frame number is given, it exists `FALSE`. This way it can be
17 | used in a loop (see the examples section below).
18 |
19 | ## Examples
20 |
21 | ### Simple stack trace
22 |
23 | The code below defines a function `die` that is used to exit the
24 | program. It prints a list of execution frames, starting with the topmost
25 | frame (0). The topmost frame is the "caller of the die function", in
26 | this case function "f1".
27 |
28 | This way, you can print a "stack trace" for debugging or logging
29 | purposes.
30 |
31 | The code is made very simple, just to show the basic purposes.
32 |
33 | ``` bash
34 | #!/bin/bash
35 |
36 | die() {
37 | local frame=0
38 | while caller $frame; do
39 | ((++frame));
40 | done
41 | echo "$*"
42 | exit 1
43 | }
44 |
45 | f1() { die "*** an error occured ***"; }
46 | f2() { f1; }
47 | f3() { f2; }
48 |
49 | f3
50 | ```
51 |
52 | **Output**
53 |
54 | 12 f1 ./callertest.sh
55 | 13 f2 ./callertest.sh
56 | 14 f3 ./callertest.sh
57 | 16 main ./callertest.sh
58 | *** an error occured ***
59 |
60 | ## Notes
61 |
62 | - `caller` produces no output unless used within a script that's run
63 | from a real file. It isn't particularly useful for interactive use,
64 | but can be used to create a decent `die` function to track down
65 | errors in moderately complex scripts.
66 | `{ bash /dev/stdin; } <<<$'f(){ g; }\ng(){ h; }\nh(){ while caller $((n++)); do :; done; }\nf'`
67 | - For more sophisticated debugging, Bash extended debugging features
68 | are available and a number of special parameters that give more
69 | detail than caller (e.g. BASH_ARG{C,V}). Tools such as
70 | [Bashdb](http://bashdb.sourceforge.net/) can assist in using some of
71 | Bash's more advanced debug features.
72 | - The Bash manpage and help text specifies that the argument to
73 | `caller` is an "expr" (whatever that means). Only an integer is
74 | actually allowed, with no special interpretation of an
75 | "expression" as far as we can tell.
76 |
77 | ## Portability considerations
78 |
79 | - `caller` is not specified by POSIX(R)
80 | - the `caller` builtin command appeared in Bash version 3.0
81 |
82 | ## See also
83 |
--------------------------------------------------------------------------------
/original_source/howto/testing-your-scripts.txt:
--------------------------------------------------------------------------------
1 | The one of the simplest way to check your bash/sh scripts is run it and check it output or run it and check the result. This tutorial shows how-to use [[https://github.com/pahaz/bashtest|bashtest]] tool for testing your scripts.
2 |
3 | ==== Write simple util ====
4 |
5 | We have a simple **stat.sh** script:
6 |
7 |
8 | #!/usr/bin/env bash
9 |
10 | if [ -z "$1" ]
11 | then
12 | DIR=./
13 | else
14 | DIR=$1
15 | fi
16 |
17 | echo "Evaluate *.py statistics"
18 | FILES=$(find $DIR -name '*.py' | wc -l)
19 | LINES=$((find $DIR -name '*.py' -print0 | xargs -0 cat) | wc -l)
20 | echo "PYTHON FILES: $FILES"
21 | echo "PYTHON LINES: $LINES"
22 |
23 |
24 | This script evaluate the number of python files and the number of python code lines in the files.
25 | We can use it like **./stat.sh **
26 |
27 | ==== Create testsuit ====
28 |
29 | Then make test suits for **stat.sh**. We make a directory **testsuit** which contain test python files.
30 |
31 | **testsuit/main.py**
32 |
33 | import foo
34 | print(foo)
35 |
36 |
37 | **testsuit/foo.py**
38 |
39 | BAR = 1
40 | BUZ = BAR + 2
41 |
42 |
43 | Ok! Our test suit is ready!
44 | We have 2 python files which contains 4 lines of code.
45 |
46 | ==== Write bashtests ====
47 |
48 | Lets write tests. We just write a shell command for testing our work.
49 |
50 | Create file **tests.bashtest**:
51 |
52 |
53 | $ ./stat.sh testsuit/
54 | Evaluate *.py statistics
55 | PYTHON FILES: 2
56 | PYTHON LINES: 4
57 |
58 |
59 |
60 | This is our test! This is simple. Try to run it.
61 |
62 |
63 | # install bashtest if required!
64 | $ pip install bashtest
65 |
66 |
67 |
68 | # run tests
69 | $ bashtest *.bashtest
70 | 1 items passed all tests:
71 | 1 tests in tests.bashtest
72 | 1 tests in 1 items.
73 | 1 passed and 0 failed.
74 | Test passed.
75 |
76 |
77 | Thats all. We wrote one test. You can write more tests if you want.
78 |
79 |
80 | $ ls testsuit/
81 | foo.py main.py
82 |
83 | $ ./stat.sh testsuit/
84 | Evaluate *.py statistics
85 | PYTHON FILES: 2
86 | PYTHON LINES: 4
87 |
88 |
89 |
90 | And run tests again:
91 |
92 |
93 | $ bashtest *.bashtest
94 | 1 items passed all tests:
95 | 2 tests in tests.bashtest
96 | 2 tests in 1 items.
97 | 2 passed and 0 failed.
98 | Test passed.
99 |
100 |
101 | You can find more **.bashtest** examples in the [[https://github.com/pahaz/bashtest | bashtest github repo]]. You can also write your question or report a bug [[https://github.com/pahaz/bashtest/issues | here]].
102 |
103 | Happy testing!
104 |
--------------------------------------------------------------------------------
/docs/misc/readthesourceluke.md:
--------------------------------------------------------------------------------
1 | Comments extracted from the bash source and therefore Copyright (C)
2 | 1987-2004 Free Software Foundation, Inc. under the terms of the GNU
3 | General Public License etc..
4 |
5 | from `mailcheck.c`:
6 |
7 | ``` C
8 | /* check_mail () is useful for more than just checking mail. Since it has
9 | the paranoids dream ability of telling you when someone has read your
10 | mail, it can just as easily be used to tell you when someones .profile
11 | file has been read, thus letting one know when someone else has logged
12 | in. Pretty good, huh? */
13 | ```
14 |
15 | From `builtins/read.def`:
16 |
17 | ``` C
18 | /* If there are no variables, save the text of the line read to the
19 | variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
20 | so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
21 | same way, but I believe that the difference in behaviors is useful
22 | enough to not do it. Without the bash behavior, there is no way
23 | to read a line completely without interpretation or modification
24 | unless you mess with $IFS (e.g., setting it to the empty string).
25 | If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
26 | ```
27 |
28 | from `variables.c`:
29 |
30 | ``` C
31 | /*
32 | * 24 October 2001
33 | *
34 | * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
35 | * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
36 | * isnetconn() to avoid running the startup files more often than wanted.
37 | * That will, of course, only work if the user's login shell is bash, so
38 | * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
39 | * in config-top.h.
40 | */
41 | ```
42 |
43 | From `shell.h`:
44 |
45 | ``` C
46 | /* Values that can be returned by execute_command (). */
47 | #define EXECUTION_FAILURE 1
48 | #define EXECUTION_SUCCESS 0
49 |
50 | /* Usage messages by builtins result in a return status of 2. */
51 | #define EX_BADUSAGE 2
52 |
53 | /* Special exit statuses used by the shell, internally and externally. */
54 | #define EX_RETRYFAIL 124
55 | #define EX_WEXPCOMSUB 125
56 | #define EX_BINARY_FILE 126
57 | #define EX_NOEXEC 126
58 | #define EX_NOINPUT 126
59 | #define EX_NOTFOUND 127
60 |
61 | #define EX_SHERRBASE 256 /* all special error values are > this. */
62 |
63 | #define EX_BADSYNTAX 257 /* shell syntax error */
64 | #define EX_USAGE 258 /* syntax error in usage */
65 | #define EX_REDIRFAIL 259 /* redirection failed */
66 | #define EX_BADASSIGN 260 /* variable assignment error */
67 | #define EX_EXPFAIL 261 /* word expansion failed */
68 | ```
69 |
--------------------------------------------------------------------------------
/original_source/syntax/ccmd/if_clause.txt:
--------------------------------------------------------------------------------
1 | ====== The if-clause ======
2 |
3 | ===== Synopsis =====
4 |
5 | if ; then
6 |
7 | fi
8 |
9 |
10 | if ; then
11 |
12 | else
13 |
14 | fi
15 |
16 |
17 | if ; then
18 |
19 | elif ; then
20 |
21 | else
22 |
23 | fi
24 |
25 |
26 | ===== Description =====
27 | The ''if''-clause can control the script's flow (what's executed) by looking at the exit codes of other commands.
28 |
29 | All commandsets '''' are interpreted as [[syntax:basicgrammar#lists | command lists]], thus they can contain the whole palette from [[syntax:basicgrammar#simple_commands | simple commands]] over [[syntax:basicgrammar#pipelines | pipelines]] to [[syntax:basicgrammar#compound_commands | compound commands]] (and their combination) as condition.
30 |
31 | ==== Operation ====
32 | The **''if ''** commands are executed. If the exit code was 0 (TRUE) then the **''then ''** commands are executed, otherwise the **''elif ''** commands and their **''then ''** statements are executed in turn, if all down to the last one fails, the **''else ''** commands are executed, if one of the ''elif'' succeeds, its ''then'' thread is executed, and the ''if''-clause finishes.
33 |
34 | Basically, the ''elif'' clauses are just additional conditions to test (like a chain of conditions) if the very first condition failed. If one of the conditions fails, the ''else'' commands are executed, otherwise the commands of the condition that succeeded.
35 |
36 |
37 | ===== Examples =====
38 | **Check if a specific user exists in /etc/passwd :-)**
39 |
40 | if grep ^myuser: /etc/passwd >/dev/null 2>&1; then
41 | echo "Yes, it seems I'm real"
42 | else
43 | echo "Uh - am I a ghost?"
44 | fi
45 |
46 |
47 | **Mount with check**
48 |
49 | if ! mount /mnt/backup >/dev/null 2>&1; then
50 | echo "FATAL: backup mount failed" >&2
51 | exit 1
52 | fi
53 |
54 |
55 | **Multiple commands as condition**
56 |
57 | It's perfectly valid to do:
58 |
59 | if echo "I'm testing!"; [ -e /some/file ]; then
60 | ...
61 | fi
62 |
63 | The exit code that dictates the condition's value is the exit code of the very last command executed in the condition-list (here: The ''[ -e /some/file ]'')
64 |
65 | **A complete pipe as condition**
66 |
67 | A complete pipe can also be used as condition. It's very similar to the example above (multiple commands):
68 |
69 | if echo "Hello world!" | grep -i hello >/dev/null 2>&1; then
70 | echo "You just said 'hello', yeah?"
71 | fi
72 |
73 |
74 | ===== Portability considerations =====
75 |
76 |
77 | ===== See also =====
78 | * Internal: [[commands:classictest | the classic test command]]
79 |
--------------------------------------------------------------------------------
/original_source/misc/readthesourceluke.txt:
--------------------------------------------------------------------------------
1 | Comments extracted from the bash source and therefore Copyright (C) 1987-2004 Free Software Foundation, Inc. under
2 | the terms of the GNU General Public License etc..
3 |
4 | from ''mailcheck.c'':
5 |
6 | /* check_mail () is useful for more than just checking mail. Since it has
7 | the paranoids dream ability of telling you when someone has read your
8 | mail, it can just as easily be used to tell you when someones .profile
9 | file has been read, thus letting one know when someone else has logged
10 | in. Pretty good, huh? */
11 |
12 |
13 | From ''builtins/read.def'':
14 |
15 |
16 | /* If there are no variables, save the text of the line read to the
17 | variable $REPLY. ksh93 strips leading and trailing IFS whitespace,
18 | so that `read x ; echo "$x"' and `read ; echo "$REPLY"' behave the
19 | same way, but I believe that the difference in behaviors is useful
20 | enough to not do it. Without the bash behavior, there is no way
21 | to read a line completely without interpretation or modification
22 | unless you mess with $IFS (e.g., setting it to the empty string).
23 | If you disagree, change the occurrences of `#if 0' to `#if 1' below. */
24 |
25 |
26 | from ''variables.c'':
27 |
28 | /*
29 | * 24 October 2001
30 | *
31 | * I'm tired of the arguing and bug reports. Bash now leaves SSH_CLIENT
32 | * and SSH2_CLIENT alone. I'm going to rely on the shell_level check in
33 | * isnetconn() to avoid running the startup files more often than wanted.
34 | * That will, of course, only work if the user's login shell is bash, so
35 | * I've made that behavior conditional on SSH_SOURCE_BASHRC being defined
36 | * in config-top.h.
37 | */
38 |
39 |
40 | From ''shell.h'':
41 |
42 | /* Values that can be returned by execute_command (). */
43 | #define EXECUTION_FAILURE 1
44 | #define EXECUTION_SUCCESS 0
45 |
46 | /* Usage messages by builtins result in a return status of 2. */
47 | #define EX_BADUSAGE 2
48 |
49 | /* Special exit statuses used by the shell, internally and externally. */
50 | #define EX_RETRYFAIL 124
51 | #define EX_WEXPCOMSUB 125
52 | #define EX_BINARY_FILE 126
53 | #define EX_NOEXEC 126
54 | #define EX_NOINPUT 126
55 | #define EX_NOTFOUND 127
56 |
57 | #define EX_SHERRBASE 256 /* all special error values are > this. */
58 |
59 | #define EX_BADSYNTAX 257 /* shell syntax error */
60 | #define EX_USAGE 258 /* syntax error in usage */
61 | #define EX_REDIRFAIL 259 /* redirection failed */
62 | #define EX_BADASSIGN 260 /* variable assignment error */
63 | #define EX_EXPFAIL 261 /* word expansion failed */
64 |
65 |
66 |
--------------------------------------------------------------------------------
/docs/syntax/ccmd/if_clause.md:
--------------------------------------------------------------------------------
1 | # The if-clause
2 |
3 | ## Synopsis
4 |
5 | if ; then
6 |
7 | fi
8 |
9 | if ; then
10 |
11 | else
12 |
13 | fi
14 |
15 | if ; then
16 |
17 | elif ; then
18 |
19 | else
20 |
21 | fi
22 |
23 | ## Description
24 |
25 | The `if`-clause can control the script's flow (what's executed) by
26 | looking at the exit codes of other commands.
27 |
28 | All commandsets `` are interpreted as [command
29 | lists](../../syntax/basicgrammar.md#lists), thus they can contain the whole
30 | palette from [simple commands](../../syntax/basicgrammar.md#simple_commands)
31 | over [pipelines](../../syntax/basicgrammar.md#pipelines) to [compound
32 | commands](../../syntax/basicgrammar.md#compound_commands) (and their
33 | combination) as condition.
34 |
35 | ### Operation
36 |
37 | The **`if `** commands are executed. If the exit code was 0 (TRUE)
38 | then the **`then `** commands are executed, otherwise the
39 | **`elif `** commands and their **`then `** statements are
40 | executed in turn, if all down to the last one fails, the
41 | **`else `** commands are executed, if one of the `elif` succeeds,
42 | its `then` thread is executed, and the `if`-clause finishes.
43 |
44 | Basically, the `elif` clauses are just additional conditions to test
45 | (like a chain of conditions) if the very first condition failed. If one
46 | of the conditions fails, the `else` commands are executed, otherwise the
47 | commands of the condition that succeeded.
48 |
49 | ## Examples
50 |
51 | **Check if a specific user exists in /etc/passwd :-)**
52 |
53 | if grep ^myuser: /etc/passwd >/dev/null 2>&1; then
54 | echo "Yes, it seems I'm real"
55 | else
56 | echo "Uh - am I a ghost?"
57 | fi
58 |
59 | **Mount with check**
60 |
61 | if ! mount /mnt/backup >/dev/null 2>&1; then
62 | echo "FATAL: backup mount failed" >&2
63 | exit 1
64 | fi
65 |
66 | **Multiple commands as condition**
67 |
68 | It's perfectly valid to do:
69 |
70 | if echo "I'm testing!"; [ -e /some/file ]; then
71 | ...
72 | fi
73 |
74 | The exit code that dictates the condition's value is the exit code of
75 | the very last command executed in the condition-list (here: The
76 | `[ -e /some/file ]`)
77 |
78 | **A complete pipe as condition**
79 |
80 | A complete pipe can also be used as condition. It's very similar to the
81 | example above (multiple commands):
82 |
83 | if echo "Hello world!" | grep -i hello >/dev/null 2>&1; then
84 | echo "You just said 'hello', yeah?"
85 | fi
86 |
87 | ## Portability considerations
88 |
89 | ## See also
90 |
91 | - Internal: [the classic test command](../../commands/classictest.md)
92 |
--------------------------------------------------------------------------------
/original_source/syntax/expansion/arith.txt:
--------------------------------------------------------------------------------
1 | ====== Arithmetic expansion ======
2 |
3 |
4 | $(( ))
5 |
6 | $[ ]
7 |
8 |
9 | The [[syntax:arith_expr | arithmetic expression]] '''' is evaluated and expands to the result. The output of the arithmetic expansion is guaranteed to be one word and a digit in Bash.
10 |
11 | Please **do not use the second form ''$[ ... ]''**! It's deprecated. The preferred and standardized form is ''$(( ... ))''!
12 |
13 | Example
14 |
15 | function printSum {
16 | typeset -A args
17 | typeset name
18 | for name in first second; do
19 | [[ -t 0 ]] && printf 'Enter %s positive integer: ' "$name" >&2
20 | read -r ${BASH_VERSION+-e} "args[$name]"
21 | [[ ${args[$name]} == +([[:digit:]]) ]] || return 1 # Validation is extremely important whenever user input is used in arithmetic.
22 | done
23 | printf 'The sum is %d.' $((${args[first]} + ${args[second]}))
24 | }
25 |
26 |
27 | **Note** that in Bash you don't need the arithmetic expansion to check for the boolean value of an arithmetic expression. This can be done using the [[syntax:ccmd:arithmetic_eval | arithmetic evaluation compound command]]:
28 |
29 |
30 | printf %s 'Enter a number: ' >&2
31 | read -r number
32 | if ((number == 1234)); then
33 | echo 'Good guess'
34 | else
35 | echo 'Haha... :-P'
36 | fi
37 |
38 |
39 | **Variables** used inside the arithmetic expansion, as in all arithmetic contexts, can be used with or without variable expansion:
40 |
41 |
42 | x=1
43 |
44 | echo $((x)) # Good.
45 | echo $(($x)) # Ok. Avoid expansions within arithmetic. Use variables directly.
46 | echo $(("$x")) # Error. There is no quote-removal in arithmetic contexts. It expands to $(("1")), which is an invalid arithmetic expression.
47 | echo $((x[0])) # Good.
48 | echo $((${x[0]})) # Ok. Nested expansion again.
49 | echo $((${x[$((${x[!$x]}-$x))]})) # Same as above but more ridiculous.
50 | echo $(($x[0])) # Error. This expands to $((1[0])), an invalid expression.
51 |
52 |
53 | ===== Bugs and Portability considerations =====
54 | * The original Bourne shell doesn't have arithmetic expansions. You have to use something like ''expr(1)'' within backticks instead. Since ''expr'' is horrible (as are backticks), and arithmetic expansion is required by POSIX, you should not worry about this, and preferably fix any code you find that's still using ''expr''.
55 |
56 | ===== See also =====
57 | * [[syntax:arith_expr | arithmetic expressions]]
58 | * [[syntax:ccmd:arithmetic_eval | arithmetic evaluation compound command]]
59 | * [[syntax:expansion:intro | Introduction to expansion and substitution]]
60 | * [[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04 | POSIX definition]]
61 |
--------------------------------------------------------------------------------
/docs/syntax/expansion/arith.md:
--------------------------------------------------------------------------------
1 | # Arithmetic expansion
2 |
3 | $(( ))
4 |
5 | $[ ]
6 |
7 | The [arithmetic expression](../../syntax/arith_expr.md) `` is
8 | evaluated and expands to the result. The output of the arithmetic
9 | expansion is guaranteed to be one word and a digit in Bash.
10 |
11 | Please **do not use the second form `$[ ... ]`**! It's deprecated. The
12 | preferred and standardized form is `$(( ... ))`!
13 |
14 | Example
15 |
16 | ``` bash
17 | function printSum {
18 | typeset -A args
19 | typeset name
20 | for name in first second; do
21 | [[ -t 0 ]] && printf 'Enter %s positive integer: ' "$name" >&2
22 | read -r ${BASH_VERSION+-e} "args[$name]"
23 | [[ ${args[$name]} == +([[:digit:]]) ]] || return 1 # Validation is extremely important whenever user input is used in arithmetic.
24 | done
25 | printf 'The sum is %d.' $((${args[first]} + ${args[second]}))
26 | }
27 | ```
28 |
29 | **Note** that in Bash you don't need the arithmetic expansion to check
30 | for the boolean value of an arithmetic expression. This can be done
31 | using the [arithmetic evaluation compound
32 | command](../../syntax/ccmd/arithmetic_eval.md):
33 |
34 | ``` bash
35 | printf %s 'Enter a number: ' >&2
36 | read -r number
37 | if ((number == 1234)); then
38 | echo 'Good guess'
39 | else
40 | echo 'Haha... :-P'
41 | fi
42 | ```
43 |
44 | **Variables** used inside the arithmetic expansion, as in all arithmetic
45 | contexts, can be used with or without variable expansion:
46 |
47 | ``` bash
48 | x=1
49 |
50 | echo $((x)) # Good.
51 | echo $(($x)) # Ok. Avoid expansions within arithmetic. Use variables directly.
52 | echo $(("$x")) # Error. There is no quote-removal in arithmetic contexts. It expands to $(("1")), which is an invalid arithmetic expression.
53 | echo $((x[0])) # Good.
54 | echo $((${x[0]})) # Ok. Nested expansion again.
55 | echo $((${x[$((${x[!$x]}-$x))]})) # Same as above but more ridiculous.
56 | echo $(($x[0])) # Error. This expands to $((1[0])), an invalid expression.
57 | ```
58 |
59 | ## Bugs and Portability considerations
60 |
61 | - The original Bourne shell doesn't have arithmetic expansions. You
62 | have to use something like `expr(1)` within backticks instead. Since
63 | `expr` is horrible (as are backticks), and arithmetic expansion is
64 | required by POSIX, you should not worry about this, and preferably
65 | fix any code you find that's still using `expr`.
66 |
67 | ## See also
68 |
69 | - [arithmetic expressions](../../syntax/arith_expr.md)
70 | - [arithmetic evaluation compound
71 | command](../../syntax/ccmd/arithmetic_eval.md)
72 | - [Introduction to expansion and
73 | substitution](../../syntax/expansion/intro.md)
74 | - [POSIX
75 | definition](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04)
76 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/shift.txt:
--------------------------------------------------------------------------------
1 | ====== The shift builtin command ======
2 |
3 | ===== Synopsis =====
4 | shift [n]
5 |
6 | ===== Description =====
7 |
8 | The ''shift'' builtin command is used to "shift" the positional parameters by the given number ''n'' or by 1, if no number is given.
9 |
10 | This means, the number and the position of the positional parameters are changed.
11 | The very first positional parameter is discarded, the second becomes the first one, etc.
12 |
13 | Imagine the following set of positional parameters (''$1'' to ''$4''):
14 |
15 | ^1 |This |
16 | ^2 |is |
17 | ^3 |a |
18 | ^4 |test |
19 |
20 | When you use ''shift 1'', they will be changed to:
21 |
22 | ^1 |is |
23 | ^2 |a |
24 | ^3 |test |
25 |
26 | The [[syntax:shellvars#special_parameters|special parameter]] ''$#'' will reflect the final number of positional parameters.
27 |
28 | If the number given is 0, no changes are made to the positional parameters.
29 |
30 |
31 | ==== Options ====
32 |
33 | There are no options.
34 |
35 | ==== Return status ====
36 |
37 | ^Status ^Reason ^
38 | |0 |no error |
39 | |1 |non-numeric argument |
40 | |1 |given number (or the default 1) is bigger than the number of actually present positional parameters |
41 | |1 |given number is negative |
42 |
43 |
44 | ===== Examples =====
45 |
46 | ===== Portability considerations =====
47 |
48 | * The ''shift'' builtin command is specified by POSIX(r).
49 | * Many shells will throw a fatal error when attempting to ''shift'' more than the number of positional parameters. **POSIX does not require that behavior**. Bash (even in POSIX mode) and Zsh return 1 when there are no args, and no error output is produced unless the [[internals/shell_options#shift_verbose | shift_verbose]] [[commands/builtin/shopt | shopt]] option is enabled. Ksh93, pdksh, posh, mksh, and dash, all throw useless fatal shell errors.
50 | $ dash -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f'
51 | dash: 1: shift: can't shift that many
52 | In most shells, you can work around this problem using the [[commands:builtin:command | command]] builtin to suppress fatal errors caused by //special builtins//. $ dash -c 'f() { if command shift 2>/dev/null; then echo "$1"; else echo "no args"; fi; }; f'
53 | no args
54 | While, POSIX requires this behavior, it isn't very obvious and some shells don't do it correctly. To work around this, you can use something like:
55 |
56 | $ mksh -c 'f() { if ! ${1+false} && shift; then echo "$1"; else echo "no args"; fi; }; f'
57 | no args
58 |
59 | The mksh maintainer refuses to change either the ''shift'' or ''command'' builtins. [[https://github.com/MirBSD/mksh/commit/996e05548ab82f7ef2dea61f109cc7b6d13837fa | Fixed]]. (Thanks!)
60 | * Perhaps almost as bad as the above, busybox sh's ''shift'' always returns success, even when attempting to shift beyond the final argument. $ bb -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f'
61 | (no output)
62 | The above mksh workaround will work in this case too.
63 |
64 | ===== See also =====
65 |
66 |
--------------------------------------------------------------------------------
/original_source/howto/collapsing_functions.txt:
--------------------------------------------------------------------------------
1 | ====== Collapsing Functions ======
2 |
3 | {{keywords>bash shell scripting example function collapse}}
4 |
5 | ===== What is a "Collapsing Function"? =====
6 | A collapsing function is a function whose behavior changes depending upon the circumstances under which it's run. Function collapsing is useful when you find yourself repeatedly checking a variable whose value never changes.
7 |
8 | ===== How do I make a function collapse? =====
9 | Function collapsing requires some static feature in the environment. A common example is a script that gives the user the option of having "verbose" output.
10 |
11 | #!/bin/bash
12 |
13 | [[ $1 = -v || $1 = --verbose ]] && verbose=1
14 |
15 | chatter() {
16 | if [[ $verbose ]]; then
17 | chatter() {
18 | echo "$@"
19 | }
20 | chatter "$@"
21 | else
22 | chatter() {
23 | :
24 | }
25 | fi
26 | }
27 |
28 | echo "Waiting for 10 seconds."
29 | for i in {1..10}; do
30 | chatter "$i"
31 | sleep 1
32 | done
33 |
34 |
35 | ===== How does it work? =====
36 | The first time you run chatter(), the function redefines itself based on the value of verbose. Thereafter, chatter doesn't check $verbose, it simply is. Further calls to the function reflect its collapsed nature. If verbose is unset, chatter will echo nothing, with no extra effort from the developer.
37 | ===== More examples =====
38 | FIXME Add more examples!
39 |
40 | # Somewhat more portable find -executable
41 | # FIXME/UNTESTED (I don't have access to all of the different versions of find.)
42 | # Usage: find PATH ARGS -- use find like normal, except use -executable instead of
43 | # various versions of -perm /+ blah blah and hacks
44 | find() {
45 | hash find || { echo 'find not found!'; exit 1; }
46 | # We can be pretty sure "$0" should be executable.
47 | if [[ $(command find "$0" -executable 2> /dev/null) ]]; then
48 | unset -f find # We can just use the command find
49 | elif [[ $(command find "$0" -perm /u+x 2> /dev/null) ]]; then
50 | find() {
51 | typeset arg args
52 | for arg do
53 | [[ $arg = -executable ]] && args+=(-perm /u+x) || args+=("$arg")
54 | done
55 | command find "${args[@]}"
56 | }
57 | elif [[ $(command find "$0" -perm +u+x 2> /dev/null) ]]; then
58 | find() {
59 | typeset arg args
60 | for arg do
61 | [[ $arg = -executable ]] && args+=(-perm +u+x) || args+=("$arg")
62 | done
63 | command find "${args[@]}"
64 | }
65 | else # Last resort
66 | find() {
67 | typeset arg args
68 | for arg do
69 | [[ $arg = -executable ]] && args+=(-exec test -x {} \; -print) || args+=("$arg")
70 | done
71 | command find "${args[@]}"
72 | }
73 | fi
74 | find "$@"
75 | }
76 |
77 |
78 |
79 | #!/bin/bash
80 | # Using collapsing functions to turn debug messages on/off
81 |
82 | [ "--debug" = "$1" ] && dbg=echo || dbg=:
83 |
84 |
85 | # From now on if you use $dbg instead of echo, you can select if messages will be shown
86 |
87 | $dbg "This message will only be displayed if --debug is specified at the command line
88 |
89 |
--------------------------------------------------------------------------------
/docs/commands/builtin/shift.md:
--------------------------------------------------------------------------------
1 | # The shift builtin command
2 |
3 | ## Synopsis
4 |
5 | shift [n]
6 |
7 | ## Description
8 |
9 | The `shift` builtin command is used to "shift" the positional
10 | parameters by the given number `n` or by 1, if no number is given.
11 |
12 | This means, the number and the position of the positional parameters are
13 | changed. The very first positional parameter is discarded, the second
14 | becomes the first one, etc.
15 |
16 | Imagine the following set of positional parameters (`$1` to `$4`):
17 |
18 | |Positional Parameter|Value|
19 | |-|-|
20 | |1|This
21 | |2|is|
22 | |3|a|
23 | |4|test|
24 |
25 | When you use `shift 1`, they will be changed to:
26 |
27 | |Positional Parameter|Value|
28 | |-|-|
29 | |1|is|
30 | |2|a|
31 | |3|test|
32 |
33 | The [special parameter](../../syntax/shellvars.md#special_parameters) `$#` will
34 | reflect the final number of positional parameters.
35 |
36 | If the number given is 0, no changes are made to the positional
37 | parameters.
38 |
39 | ### Options
40 |
41 | There are no options.
42 |
43 | ### Return status
44 |
45 | |Status|Reason|
46 | |------|------|
47 | |0|no error|
48 | |1|non-numeric argument|
49 | |1|given number (or the default 1) is bigger than the number of actually present positional parameters|
50 | |1|given number is negative|
51 |
52 | ## Examples
53 |
54 | ## Portability considerations
55 |
56 | - The `shift` builtin command is specified by POSIX(r).
57 | - Many shells will throw a fatal error when attempting to `shift` more
58 | than the number of positional parameters. **POSIX does not require
59 | that behavior**. Bash (even in POSIX mode) and Zsh return 1 when
60 | there are no args, and no error output is produced unless the
61 | [shift_verbose](../../internals/shell_options.md#shift_verbose)
62 | [shopt](../../commands/builtin/shopt.md) option is enabled. Ksh93, pdksh,
63 | posh, mksh, and dash, all throw useless fatal shell
64 | errors.
65 | ```
66 | $ dash -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f'
67 | dash: 1: shift: can't shift that many
68 | ```
69 | In most shells, you can work around this problem using the
70 | `command` builtin to suppress fatal
71 | errors caused by *special builtins*.
72 | ```
73 | $ dash -c 'f() { if command shift 2>/dev/null; then echo "$1"; else echo "no args"; fi; }; f'
74 | no args
75 | ```
76 | While, POSIX requires this behavior, it isn't very
77 | obvious and some shells don't do it correctly. To work around this, you
78 | can use something like:
79 | ```
80 | $ mksh -c 'f() { if ! ${1+false} && shift; then echo "$1"; else echo "no args"; fi; }; f'
81 | no args
82 | ```
83 | The mksh maintainer refuses to change either the `shift` or `command` builtins.
84 | [Fixed](https://github.com/MirBSD/mksh/commit/996e05548ab82f7ef2dea61f109cc7b6d13837fa).
85 | (Thanks!)
86 |
87 | - Perhaps almost as bad as the above, busybox sh's `shift` always
88 | returns success, even when attempting to shift beyond the final
89 | argument.
90 | ```
91 | $ bb -c 'f() { if shift; then echo "$1"; else echo "no args"; fi; }; f'
92 | (no output)
93 | ```
94 | The above mksh workaround will work in this case
95 | too.
96 |
97 | ## See also
98 |
--------------------------------------------------------------------------------
/original_source/syntax/expansion/tilde.txt:
--------------------------------------------------------------------------------
1 | ====== Tilde expansion ======
2 |
3 | {{keywords>bash shell scripting expansion substitution tilde home homedir shortcut}}
4 |
5 |
6 | ~
7 | ~/...
8 |
9 | ~NAME
10 | ~NAME/...
11 |
12 | ~+
13 | ~+/...
14 |
15 | ~-
16 | ~-/...
17 |
18 |
19 | The tilde expansion is used to expand to several specific pathnames:
20 | * home directories
21 | * current working directory
22 | * previous working directory
23 |
24 | Tilde expansion is only performed, when the tilde-construct is at the beginning of a word, or a separate word.
25 |
26 | If there's nothing to expand, i.e., in case of a wrong username or any other error condition, the tilde construct is not replaced, it stays what it is.
27 |
28 | Tilde expansion is also performed everytime a variable is assigned:
29 | * after the **first** ''='': ''TARGET=~moonman/share''
30 | * after **every** '':'' (colon) in the assigned value: ''TARGET=file:~moonman/share''
31 |
32 |
33 | As of now (Bash 4.3-alpha) the following constructs **also** works, though it's not a variable assignment:
34 |
35 | echo foo=~
36 | echo foo=:~
37 |
38 | I don't know yet, if this is a bug or intended.
39 |
40 |
41 | This way you can correctly use the tilde expansion in your [[syntax:shellvars#PATH|PATH]]:
42 |
43 | PATH=~/mybins:~peter/mybins:$PATH
44 |
45 |
46 | **Spaces in the referenced pathes?** A construct like...
47 |
48 | ~/"my directory"
49 |
50 | ...is perfectly valid and works!
51 |
52 | ===== Home directory =====
53 |
54 | ~
55 | ~
56 |
57 |
58 | This form expands to the home-directory of the current user (''~'') or the home directory of the given user (''~'').
59 |
60 | If the given user doesn't exist (or if his home directory isn't determinable, for some reason), it doesn't expand to something else, it stays what it is. The requested home directory is found by asking the operating system for the associated home directory for ''''.
61 |
62 | To find the home directory of the current user (''~''), Bash has a precedence:
63 | * expand to the value of [[syntax:shellvars#HOME|HOME]] if it's defined
64 | * expand to the home directory of the user executing the shell (operating system)
65 | That means, the variable ''HOME'' can override the "real" home directory, at least regarding tilde expansion.
66 |
67 |
68 | ===== Current working directory =====
69 |
70 | ~+
71 |
72 |
73 | This expands to the value of the [[syntax:shellvars#PWD|PWD]] variable, which holds the currect working directory:
74 |
75 | echo "CWD is $PWD"
76 |
77 | is equivalent to (note it **must** be a separate word!):
78 |
79 | echo "CWD is" ~+
80 |
81 |
82 |
83 | ===== Previous working directory =====
84 |
85 |
86 | ~-
87 |
88 |
89 | This expands to the value of the [[syntax:shellvars#OLDPWD|OLDPWD]] variable, which holds the previous working directory (the one before the last ''cd''). If ''OLDPWD'' is unset (never changed the directory), it is not expanded.
90 |
91 |
92 | $ pwd
93 | /home/bash
94 | $ cd /etc
95 | $ echo ~-
96 | /home/bash
97 |
98 |
99 |
100 | ===== See also =====
101 | * Internal: [[syntax:expansion:intro | Introduction to expansion and substitution]]
102 |
--------------------------------------------------------------------------------
/original_source/snipplets/add_color_to_your_scripts.txt:
--------------------------------------------------------------------------------
1 | ====== Add Color to your scripts ======
2 |
3 | ---- dataentry snipplet ----
4 | snipplet_tags : terminal, color
5 | LastUpdate_dt : 2013-03-23
6 | Contributors : Frank Lazzarini, Dan Douglas
7 | type : snipplet
8 | ----
9 |
10 | Make your scripts output more readable using bash colors. Simply add these variables to your script, and you will be able to echo in color. (I haven't added all the colors available, just some basics)
11 |
12 |
13 | # Colors
14 | ESC_SEQ="\x1b["
15 | COL_RESET=$ESC_SEQ"39;49;00m"
16 | COL_RED=$ESC_SEQ"31;01m"
17 | COL_GREEN=$ESC_SEQ"32;01m"
18 | COL_YELLOW=$ESC_SEQ"33;01m"
19 | COL_BLUE=$ESC_SEQ"34;01m"
20 | COL_MAGENTA=$ESC_SEQ"35;01m"
21 | COL_CYAN=$ESC_SEQ"36;01m"
22 |
23 |
24 |
25 | Now if you want to output some text in color use //echo -e// instead of just echo. And always remember to use the //$COL_RESET// variable to reset the color changes in bash. Like so ....
26 |
27 |
28 | echo -e "$COL_RED This is red $COL_RESET"
29 | echo -e "$COL_BLUE This is blue $COL_RESET"
30 | echo -e "$COL_YELLOW This is yellow $COL_RESET"
31 |
32 |
33 |
34 | But also see the notes in [[scripting:terminalcodes | the article about using terminalcodes]] about generating codes and hardwiring codes.
35 |
36 | This snipplet sets up associative arrays for basic color codes using ''tput'' for Bash, ksh93 or zsh. You can pass it variable names to correspond with a collection of codes. There's a ''main'' function with example usage.
37 |
38 | #!/usr/bin/env bash
39 |
40 | ${ZSH_VERSION+false} || emulate ksh
41 | ${BASH_VERSION+shopt -s lastpipe extglob}
42 |
43 | # colorSet [ --setaf | --setab | --misc ] var
44 | # Assigns the selected set of escape mappings to the given associative array names.
45 | function colorSet {
46 | typeset -a clrs msc
47 | typeset x
48 | clrs=(black red green orange blue magenta cyan grey darkgrey ltred ltgreen yellow ltblue ltmagenta ltcyan white)
49 | msc=(sgr0 bold dim smul blink rev invis)
50 |
51 | while ! ${2:+false}; do
52 | ${KSH_VERSION:+eval typeset -n "$2"=\$2}
53 | case ${1#--} in
54 | setaf|setab)
55 | for x in "${!clrs[@]}"; do
56 | eval "$2"'[${clrs[x]}]=$(tput "${1#--}" "$x")'
57 | done
58 | ;;
59 | misc)
60 | for x in "${msc[@]}"; do
61 | eval "$2"'[$x]=$(tput "$x")'
62 | done
63 | ;;
64 | *)
65 | return 1
66 | esac
67 | shift 2
68 | done
69 | }
70 |
71 | # Example code
72 | function main {
73 | typeset -A fgColors bgColors miscEscapes
74 | if colorSet --setaf fgColors --setab bgColors --misc miscEscapes; then
75 | if ! ${1:+${fgColors[$1]:+false}}; then
76 | printf '%s%s%s\n' "${fgColors[$1]}" "this text is ${1}" "${miscEscapes[sgr0]}" >&3
77 | else
78 | printf '%s, %s\n' "${1:-Empty}" 'no such color.'
79 | typeset x y
80 | for x in fgColors bgColors miscEscapes; do
81 | typeset -a keys
82 | eval 'keys=("${!'"$x"'[@]}")'
83 | printf '%s=( ' "$x"
84 | for y in "${keys[@]}"; do
85 | eval 'printf "[%q]=%q " "$y" "${'"$x"'[$y]}"'
86 | done
87 | printf ')\n'
88 | done
89 | return 1
90 | fi
91 | else
92 | echo 'Failed setting color arrays.'
93 | return 1
94 | fi 3>&1 >&2
95 | }
96 |
97 | main "$@"
98 |
99 | # vim: set fenc=utf-8 ff=unix ft=sh :
100 |
--------------------------------------------------------------------------------
/docs/howto/collapsing_functions.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - bash
4 | - shell
5 | - scripting
6 | - example
7 | - function
8 | - collapse
9 | ---
10 |
11 | # Collapsing Functions
12 |
13 | ## What is a "Collapsing Function"?
14 |
15 | A collapsing function is a function whose behavior changes depending
16 | upon the circumstances under which it's run. Function collapsing is
17 | useful when you find yourself repeatedly checking a variable whose value
18 | never changes.
19 |
20 | ## How do I make a function collapse?
21 |
22 | Function collapsing requires some static feature in the environment. A
23 | common example is a script that gives the user the option of having
24 | "verbose" output.
25 |
26 | #!/bin/bash
27 |
28 | [[ $1 = -v || $1 = --verbose ]] && verbose=1
29 |
30 | chatter() {
31 | if [[ $verbose ]]; then
32 | chatter() {
33 | echo "$@"
34 | }
35 | chatter "$@"
36 | else
37 | chatter() {
38 | :
39 | }
40 | fi
41 | }
42 |
43 | echo "Waiting for 10 seconds."
44 | for i in {1..10}; do
45 | chatter "$i"
46 | sleep 1
47 | done
48 |
49 | ## How does it work?
50 |
51 | The first time you run chatter(), the function redefines itself based on
52 | the value of verbose. Thereafter, chatter doesn't check `$verbose`, it
53 | simply is. Further calls to the function reflect its collapsed nature.
54 | If verbose is unset, chatter will echo nothing, with no extra effort
55 | from the developer.
56 |
57 | ## More examples
58 |
59 | !!! warning "FIXME"
60 | Add more examples!
61 |
62 | ```bash
63 | # Somewhat more portable find -executable
64 | # FIXME/UNTESTED (I don't have access to all of the different versions of find.)
65 | # Usage: find PATH ARGS -- use find like normal, except use -executable instead of
66 | # various versions of -perm /+ blah blah and hacks
67 | find() {
68 | hash find || { echo 'find not found!'; exit 1; }
69 | # We can be pretty sure "$0" should be executable.
70 | if [[ $(command find "$0" -executable 2> /dev/null) ]]; then
71 | unset -f find # We can just use the command find
72 | elif [[ $(command find "$0" -perm /u+x 2> /dev/null) ]]; then
73 | find() {
74 | typeset arg args
75 | for arg do
76 | [[ $arg = -executable ]] && args+=(-perm /u+x) || args+=("$arg")
77 | done
78 | command find "${args[@]}"
79 | }
80 | elif [[ $(command find "$0" -perm +u+x 2> /dev/null) ]]; then
81 | find() {
82 | typeset arg args
83 | for arg do
84 | [[ $arg = -executable ]] && args+=(-perm +u+x) || args+=("$arg")
85 | done
86 | command find "${args[@]}"
87 | }
88 | else # Last resort
89 | find() {
90 | typeset arg args
91 | for arg do
92 | [[ $arg = -executable ]] && args+=(-exec test -x {} \; -print) || args+=("$arg")
93 | done
94 | command find "${args[@]}"
95 | }
96 | fi
97 | find "$@"
98 | }
99 | ```
100 |
101 | ```bash
102 | #!/bin/bash
103 | # Using collapsing functions to turn debug messages on/off
104 |
105 | [ "--debug" = "$1" ] && dbg=echo || dbg=:
106 |
107 |
108 | # From now on if you use $dbg instead of echo, you can select if messages will be shown
109 |
110 | $dbg "This message will only be displayed if --debug is specified at the command line
111 | ```
112 |
--------------------------------------------------------------------------------
/docs/syntax/expansion/tilde.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - bash
4 | - shell
5 | - scripting
6 | - expansion
7 | - substitution
8 | - tilde
9 | - home
10 | - homedir
11 | - shortcut
12 | ---
13 |
14 | # Tilde expansion
15 |
16 | ~
17 | ~/...
18 |
19 | ~NAME
20 | ~NAME/...
21 |
22 | ~+
23 | ~+/...
24 |
25 | ~-
26 | ~-/...
27 |
28 | The tilde expansion is used to expand to several specific pathnames:
29 |
30 | - home directories
31 | - current working directory
32 | - previous working directory
33 |
34 | Tilde expansion is only performed, when the tilde-construct is at the
35 | beginning of a word, or a separate word.
36 |
37 | If there's nothing to expand, i.e., in case of a wrong username or any
38 | other error condition, the tilde construct is not replaced, it stays
39 | what it is.
40 |
41 | Tilde expansion is also performed everytime a variable is assigned:
42 |
43 | - after the **first** `=`: `TARGET=~moonman/share`
44 | - after **every** `:` (colon) in the assigned value:
45 | `TARGET=file:~moonman/share`
46 |
47 | !!! info "Note"
48 | As of now (Bash 4.3-alpha) the following constructs
49 | **also** works, though it's not a variable assignment:
50 |
51 | echo foo=~
52 | echo foo=:~
53 |
54 | I don't know yet, if this is a bug or intended.
55 |
56 | This way you can correctly use the tilde expansion in your
57 | [PATH](../../syntax/shellvars.md#PATH):
58 |
59 | PATH=~/mybins:~peter/mybins:$PATH
60 |
61 | **Spaces in the referenced pathes?** A construct like...
62 |
63 | ~/"my directory"
64 |
65 | ...is perfectly valid and works!
66 |
67 | ## Home directory
68 |
69 | ~
70 | ~
71 |
72 | This form expands to the home-directory of the current user (`~`) or the
73 | home directory of the given user (`~`).
74 |
75 | If the given user doesn't exist (or if his home directory isn't
76 | determinable, for some reason), it doesn't expand to something else, it
77 | stays what it is. The requested home directory is found by asking the
78 | operating system for the associated home directory for ``.
79 |
80 | To find the home directory of the current user (`~`), Bash has a
81 | precedence:
82 |
83 | - expand to the value of [HOME](../../syntax/shellvars.md#HOME) if it's
84 | defined
85 | - expand to the home directory of the user executing the shell
86 | (operating system)
87 |
88 | That means, the variable `HOME` can override the "real" home
89 | directory, at least regarding tilde expansion.
90 |
91 | ## Current working directory
92 |
93 | ~+
94 |
95 | This expands to the value of the [PWD](../../syntax/shellvars.md#PWD) variable,
96 | which holds the currect working directory:
97 |
98 | echo "CWD is $PWD"
99 |
100 | is equivalent to (note it **must** be a separate word!):
101 |
102 | echo "CWD is" ~+
103 |
104 | ## Previous working directory
105 |
106 | ~-
107 |
108 | This expands to the value of the [OLDPWD](../../syntax/shellvars.md#OLDPWD)
109 | variable, which holds the previous working directory (the one before the
110 | last `cd`). If `OLDPWD` is unset (never changed the directory), it is
111 | not expanded.
112 |
113 | $ pwd
114 | /home/bash
115 | $ cd /etc
116 | $ echo ~-
117 | /home/bash
118 |
119 | ## See also
120 |
121 | - Internal: [Introduction to expansion and
122 | substitution](../../syntax/expansion/intro.md)
123 |
--------------------------------------------------------------------------------
/docs/misc/bashphorisms.md:
--------------------------------------------------------------------------------
1 | # The Bashphorisms
2 |
3 | Bashphorisms are aphorisms for the IRC channel `#bash` on Freenode. Keep
4 | in mind that this version is a snapshot, the bashphorisms are changed
5 | here and there. Also, [another
6 | snapshot](http://mywiki.wooledge.org/BashFAQ/064).
7 |
8 | I think `greycat` was the first one who had the idea, but I'm not sure.
9 |
10 | Our bashphorisms can be queried from `greybot` using `!bN`, where `N` is
11 | the bashphorism number.
12 |
13 | And yes, these bashphorisms reflect the daily reality in `#bash`.
14 |
15 | |Number|Bashphorism|
16 | |------|-----------|
17 | |0|The questioner will never tell you what they are really doing the first time they ask.|
18 | |1|The questioner's first description of the problem/question will be misleading.|
19 | |2|The questioner will keep changing the question until it drives the helpers in the channel insane.|
20 | |3|Offtopicness will continue until someone asks a bash question that falls under bashphorisms 1 and/or 2, and `greycat` gets pissed off.|
21 | |4|The questioner will not read and apply the answers he is given but will instead continue to practice bashphorism #1 and bashphorism #2.|
22 | |5|The ignorant will continually mis-educate the other noobies.|
23 | |6|When given a choice of solutions, the newbie will always choose the wrong one.|
24 | |7|The newbie will always find a reason to say, "It doesn't work."|
25 | |8|If you don't know to whom the bashphorism's referring, it's you.|
26 | |9|All examples given by the questioner will be broken, misleading, wrong, and not representative of the actual question.|
27 | |10|See B1|
28 | |11|Please apply `(( % 10 ))` to the bashphorism value.|
29 | |12|All logic is deniable; however, some logic will *plonk* you if you deny it.|
30 | |13|Everyone ignores greycat when he is right. When he is wrong, it is !b1|
31 | |14|The newbie doesn't actually know what he's asking. If he did, he wouldn't need to ask.|
32 | |15|The more advanced you are, the more likely you are to be overcomplicating it.|
33 | |16|The more beginner you are, the more likely you are to be overcomplicating it.|
34 | |17|A newbie comes to #bash to get his script confirmed. He leaves disappointed.|
35 | |18|The newbie will not accept the answer you give, no matter how right it is.|
36 | |19|The newbie is a bloody loon.|
37 | |20|The newbie will always have some excuse for doing it wrong.|
38 | |21|When the newbie's question is ambiguous, the proper interpretation will be whichever one makes the problem the hardest to solve.|
39 | |22|The newcomer will abuse the bot's factoid triggers for their own entertainment until someone gets annoyed enough to ask them to message it privately instead.|
40 | |23|Everyone is a newcomer.|
41 | |24|The newcomer will address greybot as if it were human.|
42 | |25|The newbie won't accept any answer that uses practical or standard tools.|
43 | |26|The newbie will not TELL you about this restriction until you have wasted half an hour.|
44 | |27|The newbie will lie.|
45 | |28|When the full horror of the newbie's true goal is revealed, the newbie will try to restate the goal to trick you into answering. Newbies are stupid.|
46 | |29|It's always git. Or python virtualenv. Or docker. One of those pieces of shit. ALWAYS.|
47 | |30|They won't show you the homework assignment. That would make it too easy.|
48 | |31|Your teacher is a f**king idiot.|
49 | |32|The more horrifyingly wrong a proposed solution is, the more likely it will be used.|
50 | |33|The newbie cannot explain what he is doing, or why. He will show you incomprehensible, nonworking code instead. What? You can't read his mind?!|
51 |
52 | Please feel free to correct or extend this page whenever needed.
53 |
--------------------------------------------------------------------------------
/original_source/syntax/expansion/intro.txt:
--------------------------------------------------------------------------------
1 | ====== Expansions and substitutions ======
2 |
3 | {{keywords>bash shell scripting expansion substitution text variable filename macro wildcard}}
4 |
5 | Before executing your commands, Bash checks whether there are any syntax elements in the command line that should be interpreted rather than taken literally. After splitting the command line into tokens (words), Bash scans for these special elements and interprets them, resulting in a changed command line: the elements are said to be **expanded** to or **substituted** to **new text and maybe new tokens** (words).
6 |
7 | The most simple example of this behaviour is a referenced variable:
8 |
9 | mystring="Hello world"
10 | echo "$mystring"
11 |
12 | The ''echo'' program definitely doesn't care about what a shell variable is. It is Bash's job to deal with the variable. Bash **expands** the string "''$mystring''" to "''Hello world''", so that ''echo'' will only see ''Hello world'', not the variable or anything else!
13 |
14 | After all these expansions and substitutions are done, all quotes that are not meant literally (i.e., [[syntax:quoting | the quotes that marked contiguous words]], as part of the shell syntax) are removed from the commandline text, so the called program won't see them. This step is called **quote-removal**.
15 |
16 | ===== Overview =====
17 |
18 | Saw a possible expansion syntax but don't know what it is? Here's a small list.
19 |
20 | * [[syntax:pe | Parameter expansion]] (it has its own [[syntax:pe#overview | overview section]])
21 | * ''$WORD''
22 | * ''${STUFF...}''
23 | * [[syntax:expansion:globs | Pathname expansion]]
24 | * ''*.txt''
25 | * ''page_1?.html''
26 | * [[syntax:expansion:arith | Arithmetic expansion]]
27 | * ''$(( EXPRESSION ))''
28 | * ''$[ EXPRESSION ]''
29 | * [[syntax:expansion:cmdsubst | Command substitution]]
30 | * ''$( COMMAND )''
31 | * ''` COMMAND `''
32 | * [[syntax:expansion:tilde | Tilde expansion]]
33 | * ''~''
34 | * ''~+''
35 | * ''~-''
36 | * [[syntax:expansion:brace | Brace expansion]]
37 | * ''{X,Y,Z}''
38 | * ''{X..Y}''
39 | * ''{X..Y..Z}''
40 | * [[syntax:expansion:proc_subst | Process substitution]]
41 | * ''<( COMMAND )''
42 | * ''>( COMMAND )''
43 |
44 | ===== Order =====
45 | Bash performs expansions and substitutions in a defined order. This explains why globbing (pathname expansion), for example, is safe to use on filenames with spaces (because it happens **after** the final word splitting!).
46 |
47 | The order is (from first to last):
48 |
49 | * [[syntax:expansion:brace | Brace expansion]]
50 | * [[syntax:expansion:tilde | Tilde expansion]]
51 | * The following expansions happen at the same time, in a left-to-right fashion on the commandline (see below)
52 | * [[syntax:pe | Parameter expansion]]
53 | * [[syntax:expansion:arith | Arithmetic expansion]]
54 | * [[syntax:expansion:cmdsubst | Command substitution]]
55 | * [[syntax:expansion:wordsplit | Word splitting]]
56 | * [[syntax:expansion:globs | Pathname expansion]]
57 |
58 | [[syntax:expansion:proc_subst | Process substitution]] is performed **simultaneously** with [[syntax:pe | parameter expansion]], [[syntax:expansion:cmdsubst | command substitution]] and [[syntax:expansion:arith | arithmetic expansion]]. It is only performed when the underlying operating system supports it.
59 |
60 | The 3 steps [[syntax:pe | parameter expansion]], [[syntax:expansion:arith | arithmetic expansion]] and [[syntax:expansion:cmdsubst | command substitution]] happen at the same time in a left-to-right fashion on nthe commandline. This means
61 |
62 | i=1
63 | echo $i $((i++)) $i
64 |
65 | will output ''1 1 2'' and not ''1 1 1''.
66 |
--------------------------------------------------------------------------------
/docs/snipplets/add_color_to_your_scripts.md:
--------------------------------------------------------------------------------
1 | # Add Color to your scripts
2 |
3 | ---- dataentry snipplet ---- snipplet_tags : terminal, color
4 | LastUpdate_dt : 2013-03-23 Contributors : Frank Lazzarini, Dan Douglas
5 | type : snipplet
6 |
7 | ------------------------------------------------------------------------
8 |
9 | Make your scripts output more readable using bash colors. Simply add
10 | these variables to your script, and you will be able to echo in color.
11 | (I haven't added all the colors available, just some basics)
12 |
13 | # Colors
14 | ESC_SEQ="\x1b["
15 | COL_RESET=$ESC_SEQ"39;49;00m"
16 | COL_RED=$ESC_SEQ"31;01m"
17 | COL_GREEN=$ESC_SEQ"32;01m"
18 | COL_YELLOW=$ESC_SEQ"33;01m"
19 | COL_BLUE=$ESC_SEQ"34;01m"
20 | COL_MAGENTA=$ESC_SEQ"35;01m"
21 | COL_CYAN=$ESC_SEQ"36;01m"
22 |
23 | Now if you want to output some text in color use *echo -e* instead of
24 | just echo. And always remember to use the *\$COL_RESET* variable to
25 | reset the color changes in bash. Like so \....
26 |
27 | echo -e "$COL_RED This is red $COL_RESET"
28 | echo -e "$COL_BLUE This is blue $COL_RESET"
29 | echo -e "$COL_YELLOW This is yellow $COL_RESET"
30 |
31 | But also see the notes in [the article about using
32 | terminalcodes](../scripting/terminalcodes.md) about generating codes and
33 | hardwiring codes.
34 |
35 | This snipplet sets up associative arrays for basic color codes using
36 | `tput` for Bash, ksh93 or zsh. You can pass it variable names to
37 | correspond with a collection of codes. There's a `main` function with
38 | example usage.
39 |
40 | ``` bash
41 | #!/usr/bin/env bash
42 |
43 | ${ZSH_VERSION+false} || emulate ksh
44 | ${BASH_VERSION+shopt -s lastpipe extglob}
45 |
46 | # colorSet [ --setaf | --setab | --misc ] var
47 | # Assigns the selected set of escape mappings to the given associative array names.
48 | function colorSet {
49 | typeset -a clrs msc
50 | typeset x
51 | clrs=(black red green orange blue magenta cyan grey darkgrey ltred ltgreen yellow ltblue ltmagenta ltcyan white)
52 | msc=(sgr0 bold dim smul blink rev invis)
53 |
54 | while ! ${2:+false}; do
55 | ${KSH_VERSION:+eval typeset -n "$2"=\$2}
56 | case ${1#--} in
57 | setaf|setab)
58 | for x in "${!clrs[@]}"; do
59 | eval "$2"'[${clrs[x]}]=$(tput "${1#--}" "$x")'
60 | done
61 | ;;
62 | misc)
63 | for x in "${msc[@]}"; do
64 | eval "$2"'[$x]=$(tput "$x")'
65 | done
66 | ;;
67 | *)
68 | return 1
69 | esac
70 | shift 2
71 | done
72 | }
73 |
74 | # Example code
75 | function main {
76 | typeset -A fgColors bgColors miscEscapes
77 | if colorSet --setaf fgColors --setab bgColors --misc miscEscapes; then
78 | if ! ${1:+${fgColors[$1]:+false}}; then
79 | printf '%s%s%s\n' "${fgColors[$1]}" "this text is ${1}" "${miscEscapes[sgr0]}" >&3
80 | else
81 | printf '%s, %s\n' "${1:-Empty}" 'no such color.'
82 | typeset x y
83 | for x in fgColors bgColors miscEscapes; do
84 | typeset -a keys
85 | eval 'keys=("${!'"$x"'[@]}")'
86 | printf '%s=( ' "$x"
87 | for y in "${keys[@]}"; do
88 | eval 'printf "[%q]=%q " "$y" "${'"$x"'[$y]}"'
89 | done
90 | printf ')\n'
91 | done
92 | return 1
93 | fi
94 | else
95 | echo 'Failed setting color arrays.'
96 | return 1
97 | fi 3>&1 >&2
98 | }
99 |
100 | main "$@"
101 |
102 | # vim: set fenc=utf-8 ff=unix ft=sh :
103 | ```
104 |
--------------------------------------------------------------------------------
/original_source/commands/builtin/echo.txt:
--------------------------------------------------------------------------------
1 | ====== The echo builtin command ======
2 |
3 | ===== Synopsis =====
4 |
5 | echo [-neE] [arg ...]
6 |
7 |
8 | ===== Description =====
9 | ''echo'' outputs it's args to stdout, separated by spaces, followed by a newline. The return status is always ''0''. If the [[commands:builtin:shopt|shopt]] option ''xpg_echo'' is set, Bash dynamically determines whether echo should expand escape characters (listed below) by default based on the current platform. ''echo'' doesn't interpret ''--'' as the end of options, and will simply print this string if given.
10 |
11 | ==== Options ====
12 | ^Option ^Description ^
13 | | ''-n'' | The trailing newline is suppressed. |
14 | | ''-e'' | Interpretation of the following backslash-escaped characters (below) is enabled. |
15 | | ''-E'' | Disables the interpretation of these escape characters, even on systems where they are interpreted by default. |
16 |
17 | ==== Escape sequences ====
18 | ^Escape ^Description ^
19 | | ''\a'' | alert (bell) |
20 | | ''\b'' | backspace |
21 | | ''\c'' | suppress further output |
22 | | ''\e'' | |
23 | | ''\E'' | an escape character |
24 | | ''\f'' | form feed |
25 | | ''\n'' | new line |
26 | | ''\r'' | carriage return |
27 | | ''\t'' | horizontal tab |
28 | | ''\v'' | vertical tab |
29 | | ''\\'' | backslash |
30 | | ''\0nnn'' | the eight-bit character whose value is the octal value nnn (zero to three octal digits) |
31 | | ''\xHH'' | the eight-bit character whose value is the hexadecimal value HH (one or two hex digits) |
32 | | ''\uHHHH'' | the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits) |
33 | | ''\UHHHHHHHH'' | the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits) |
34 |
35 | ===== Examples =====
36 |
37 |
38 | ===== Portability considerations =====
39 | * ''echo'' is a portability train wreck. No major shell follows POSIX completely, and any shell that attempts to do so should be considered horribly broken. [[http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37|SUSv4]] specifies that ''echo'' **shall not** include any options. Further, it specifies that the behavior of ''-n'' as a first argument shall be determined by the implementation, unless XSI is followed, in which case ''-n'' is always treated as a string, and backslash escapes are interpreted by default. ''dash'' has the misfeature of following this and interpreting escapes by default, but includes a ''-n'' feature for suppressing newlines nevertheless.\\ \\ In practice, if you're able to assume a korn-like shell including bash, mksh, or zsh, ''echo'' when used in simple cases is generally reliable. For example, in the very common situation in which echo is supplied with a single argument and whose output is to have a newline appended, using ''echo'' is considered common practice.
40 |
41 | * **Never use options to ''echo''! //Ever//!** Any time you feel tempted to use ''echo -e'', ''-n'', or any other special feature of echo, **use [[commands:builtin:printf|printf]] instead!** If portability is a requirement, you should consider using ''printf'' //exclusively// and just ignore that ''echo'' even exists. If you must use ''echo -e'' and refuse to use ''printf'', it is usually acceptable to use ''echo $'...' ''if targeting only shells that support this special quoting style.
42 |
43 | * ''ksh93'' has a ''print'' command, which if coding specifically for ''ksh93'' should be preferred over ''echo''. [[commands:builtin:printf|printf]] still includes most of the functionality of both, and should usually be the most preferred option.
44 |
45 | ===== See also =====
46 | * [[commands:builtin:printf]]
47 | * http://cfajohnson.com/shell/cus-faq.html#Q0b
48 | * http://www.in-ulm.de/~mascheck/various/echo+printf/
--------------------------------------------------------------------------------
/docs/commands/builtin/echo.md:
--------------------------------------------------------------------------------
1 | # The echo builtin command
2 |
3 | ## Synopsis
4 |
5 | echo [-neE] [arg ...]
6 |
7 | ## Description
8 |
9 | `echo` outputs it's args to stdout, separated by spaces, followed by a
10 | newline. The return status is always `0`. If the
11 | [shopt](../../commands/builtin/shopt.md) option `xpg_echo` is set, Bash
12 | dynamically determines whether echo should expand escape characters
13 | (listed below) by default based on the current platform. `echo` doesn't
14 | interpret `--` as the end of options, and will simply print this string
15 | if given.
16 |
17 | ### Options
18 |
19 | Option|Description|
20 | ------|-----------|
21 | |`-n`|The trailing newline is suppressed.|
22 | |`-e`|Interpretation of the following backslash-escaped characters (below) is enabled.|
23 | |`-E`|Disables the interpretation of these escape characters, even on systems where they are interpreted by default.|
24 |
25 | ### Escape sequences
26 |
27 | |Escape|Description|
28 | |------|-----------|
29 | |`\a`|alert (bell)|
30 | |`\b`|backspace|
31 | |`\c`|suppress further output|
32 | |`\e`|
33 | |`\E`|an escape character|
34 | |`\f`|form feed|
35 | |`\n`|new line|
36 | |`\r`|carriage return|
37 | |`\t`|horizontal tab|
38 | |`\v`|vertical tab|
39 | |`\\`|backslash|
40 | |`\0nnn`|the eight-bit character whose value is the octal value nnn (zero to three octal digits)|
41 | |`\xHH`|the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)|
42 | |`\uHHHH`|the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHH (one to four hex digits)|
43 | |`\UHHHHHHHH`|the Unicode (ISO/IEC 10646) character whose value is the hexadecimal value HHHHHHHH (one to eight hex digits)|
44 |
45 | ## Examples
46 |
47 | ## Portability considerations
48 |
49 | - `echo` is a portability train wreck. No major shell follows POSIX
50 | completely, and any shell that attempts to do so should be
51 | considered horribly broken.
52 | [SUSv4](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37)
53 | specifies that `echo` **shall not** include any options. Further, it
54 | specifies that the behavior of `-n` as a first argument shall be
55 | determined by the implementation, unless XSI is followed, in which
56 | case `-n` is always treated as a string, and backslash escapes are
57 | interpreted by default. `dash` has the misfeature of following this
58 | and interpreting escapes by default, but includes a `-n` feature for
59 | suppressing newlines nevertheless.
60 |
61 | In practice, if you're able to assume a korn-like shell including
62 | bash, mksh, or zsh, `echo` when used in simple cases is generally
63 | reliable. For example, in the very common situation in which echo is
64 | supplied with a single argument and whose output is to have a
65 | newline appended, using `echo` is considered common practice.
66 |
67 | - **Never use options to `echo`! *Ever*!** Any time you feel tempted
68 | to use `echo -e`, `-n`, or any other special feature of echo, **use
69 | [printf](../../commands/builtin/printf.md) instead!** If portability is a
70 | requirement, you should consider using `printf` *exclusively* and
71 | just ignore that `echo` even exists. If you must use `echo -e` and
72 | refuse to use `printf`, it is usually acceptable to use \'\'echo
73 | \$\'\...\' \'\'if targeting only shells that support this special
74 | quoting style.
75 |
76 | - `ksh93` has a `print` command, which if coding specifically for
77 | `ksh93` should be preferred over `echo`.
78 | [printf](../../commands/builtin/printf.md) still includes most of the
79 | functionality of both, and should usually be the most preferred
80 | option.
81 |
82 | ## See also
83 |
84 | - [printf](../../commands/builtin/printf.md)
85 | -
86 | -
87 |
--------------------------------------------------------------------------------
/docs/syntax/expansion/intro.md:
--------------------------------------------------------------------------------
1 | ---
2 | tags:
3 | - bash
4 | - shell
5 | - scripting
6 | - expansion
7 | - substitution
8 | - text
9 | - variable
10 | - filename
11 | - macro
12 | - wildcard
13 | ---
14 |
15 | # Expansions and substitutions
16 |
17 | Before executing your commands, Bash checks whether there are any syntax
18 | elements in the command line that should be interpreted rather than
19 | taken literally. After splitting the command line into tokens (words),
20 | Bash scans for these special elements and interprets them, resulting in
21 | a changed command line: the elements are said to be **expanded** to or
22 | **substituted** to **new text and maybe new tokens** (words).
23 |
24 | The most simple example of this behaviour is a referenced variable:
25 |
26 | mystring="Hello world"
27 | echo "$mystring"
28 |
29 | The `echo` program definitely doesn't care about what a shell variable
30 | is. It is Bash's job to deal with the variable. Bash **expands** the
31 | string "`$mystring`" to "`Hello world`", so that `echo` will only
32 | see `Hello world`, not the variable or anything else!
33 |
34 | After all these expansions and substitutions are done, all quotes that
35 | are not meant literally (i.e., [the quotes that marked contiguous
36 | words](../../syntax/quoting.md), as part of the shell syntax) are removed from
37 | the commandline text, so the called program won't see them. This step
38 | is called **quote-removal**.
39 |
40 | ## Overview
41 |
42 | Saw a possible expansion syntax but don't know what it is? Here's a
43 | small list.
44 |
45 | - [Parameter expansion](../../syntax/pe.md) (it has its own [overview
46 | section](../../syntax/pe.md#overview))
47 | - `$WORD`
48 | - `${STUFF...}`
49 | - [Pathname expansion](../../syntax/expansion/globs.md)
50 | - `*.txt`
51 | - `page_1?.html`
52 | - [Arithmetic expansion](../../syntax/expansion/arith.md)
53 | - `$(( EXPRESSION ))`
54 | - `$[ EXPRESSION ]`
55 | - [Command substitution](../../syntax/expansion/cmdsubst.md)
56 | - `$( COMMAND )`
57 | - `` ` COMMAND ` ``
58 | - [Tilde expansion](../../syntax/expansion/tilde.md)
59 | - `~`
60 | - `~+`
61 | - `~-`
62 | - [Brace expansion](../../syntax/expansion/brace.md)
63 | - `{X,Y,Z}`
64 | - `{X..Y}`
65 | - `{X..Y..Z}`
66 | - [Process substitution](../../syntax/expansion/proc_subst.md)
67 | - `<( COMMAND )`
68 | - `>( COMMAND )`
69 |
70 | ## Order
71 |
72 | Bash performs expansions and substitutions in a defined order. This
73 | explains why globbing (pathname expansion), for example, is safe to use
74 | on filenames with spaces (because it happens **after** the final word
75 | splitting!).
76 |
77 | The order is (from first to last):
78 |
79 | - [Brace expansion](../../syntax/expansion/brace.md)
80 | - [Tilde expansion](../../syntax/expansion/tilde.md)
81 | - The following expansions happen at the same time, in a left-to-right
82 | fashion on the commandline (see below)
83 | - [Parameter expansion](../../syntax/pe.md)
84 | - [Arithmetic expansion](../../syntax/expansion/arith.md)
85 | - [Command substitution](../../syntax/expansion/cmdsubst.md)
86 | - [Word splitting](../../syntax/expansion/wordsplit.md)
87 | - [Pathname expansion](../../syntax/expansion/globs.md)
88 |
89 | [Process substitution](../../syntax/expansion/proc_subst.md) is performed
90 | **simultaneously** with [parameter expansion](../../syntax/pe.md), [command
91 | substitution](../../syntax/expansion/cmdsubst.md) and [arithmetic
92 | expansion](../../syntax/expansion/arith.md). It is only performed when the
93 | underlying operating system supports it.
94 |
95 | The 3 steps [parameter expansion](../../syntax/pe.md), [arithmetic
96 | expansion](../../syntax/expansion/arith.md) and [command
97 | substitution](../../syntax/expansion/cmdsubst.md) happen at the same time in a
98 | left-to-right fashion on nthe commandline. This means
99 |
100 | i=1
101 | echo $i $((i++)) $i
102 |
103 | will output `1 1 2` and not `1 1 1`.
104 |
--------------------------------------------------------------------------------