Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
syntax:basicgrammar [2015/08/10 02:55]
bill_thomson
syntax:basicgrammar [2019/04/01 21:45] (current)
ddebhw Fix a little typo.
Line 17: Line 17:
 Sounds harder than it actually is. It is what you do daily. You enter simple commands with parameters, and the shell executes them. Sounds harder than it actually is. It is what you do daily. You enter simple commands with parameters, and the shell executes them.
  
-Every complex Bash operationcan ​be split into simple commands:+Every complex Bash operation can be split into simple commands:
 <​code>​ <​code>​
 ls ls
Line 80: Line 80:
  
 ^Operator^Description^ ^Operator^Description^
-|''<​PIPELINE1>​ **<​newline>​** <​PIPELINE2>''​|Newlines completely separate pipelines. The next pipeline is executed without any checks. You enter a command and press ''<​RETURN>''​!)|+|''<​PIPELINE1>​ **<​newline>​** <​PIPELINE2>''​|Newlines completely separate pipelines. The next pipeline is executed without any checks. ​(You enter a command and press ''<​RETURN>''​!)|
 |''<​PIPELINE1>​ **;** <​PIPELINE2>''​|The semicolon does what ''<​newline>''​ does: It separates the pipelines| |''<​PIPELINE1>​ **;** <​PIPELINE2>''​|The semicolon does what ''<​newline>''​ does: It separates the pipelines|
 |''<​PIPELINE>​ **&** <​PIPELINE>''​|The pipeline in front of the ''&''​ is executed **asynchronously** ("in the background"​). If a pipeline follows this, it is executed immediately after the async pipeline starts| |''<​PIPELINE>​ **&** <​PIPELINE>''​|The pipeline in front of the ''&''​ is executed **asynchronously** ("in the background"​). If a pipeline follows this, it is executed immediately after the async pipeline starts|
Line 93: Line 93:
  
 There are two forms of compound commands: There are two forms of compound commands:
-  * forming ​a new syntax element using lists as "​body"​ +  * form a new syntax element using a list as "​body"​ 
-  * complete ​independant syntax elements +  * completly ​independant syntax elements 
-Basicallyit'​s ​everything else that's not described ​elsewhere ​in this article. Compound commands have the following characteristics:​+Essentially, everything else that's not described in this article. Compound commands have the following characteristics:​
   * they **begin** and **end** with a specific keyword or operator (e.g. ''​for ... done''​)   * they **begin** and **end** with a specific keyword or operator (e.g. ''​for ... done''​)
   * they can be redirected as a whole   * they can be redirected as a whole
  
-See the following table for a short overview (without ​details - really ​just a plain overview!):+See the following table for a short overview (no details - just an overview):
 ^Compound command syntax^Description^ ^Compound command syntax^Description^
 |''​( <​LIST>​ )''​|Execute ''<​LIST>''​ in an extra subshell => [[syntax:​ccmd:​grouping_subshell | article]]| |''​( <​LIST>​ )''​|Execute ''<​LIST>''​ in an extra subshell => [[syntax:​ccmd:​grouping_subshell | article]]|
Line 107: Line 107:
 |''​for <​NAME>​ in <​WORDS>​ ; do <​LIST>​ ; done''​|Executes ''<​LIST>''​ while setting the variable ''<​NAME>''​ to one of ''<​WORDS>''​ on every iteration (classic for-loop) => [[syntax:​ccmd:​classic_for | article]]| |''​for <​NAME>​ in <​WORDS>​ ; do <​LIST>​ ; done''​|Executes ''<​LIST>''​ while setting the variable ''<​NAME>''​ to one of ''<​WORDS>''​ on every iteration (classic for-loop) => [[syntax:​ccmd:​classic_for | article]]|
 |''​for <​nowiki>​((</​nowiki>​ <​EXPR1>​ ; <​EXPR2>​ ; <​EXPR3>​ )) ; do <​LIST>​ ; done''​|C-style for-loop (driven by arithmetic expressions) => [[syntax:​ccmd:​c_for | article]]| |''​for <​nowiki>​((</​nowiki>​ <​EXPR1>​ ; <​EXPR2>​ ; <​EXPR3>​ )) ; do <​LIST>​ ; done''​|C-style for-loop (driven by arithmetic expressions) => [[syntax:​ccmd:​c_for | article]]|
-|''​select <​NAME>​ in <​WORDS>​ ; do <​LIST>​ ; done''​|Providing ​simple menus => [[syntax:​ccmd:​user_select | article]]| +|''​select <​NAME>​ in <​WORDS>​ ; do <​LIST>​ ; done''​|Provides ​simple menus => [[syntax:​ccmd:​user_select | article]]| 
-|''​case <​WORD>​ in <​PATTERN>​) <​LIST>​ ;; ... esac''​|Decicions ​based on pattern matching - executing ''<​LIST>''​ on match => [[syntax:​ccmd:​case | article]]| +|''​case <​WORD>​ in <​PATTERN>​) <​LIST>​ ;; ... esac''​|Decisions ​based on pattern matching - executing ''<​LIST>''​ on match => [[syntax:​ccmd:​case | article]]| 
-|''​if <​LIST>​ ; then <​LIST>​ ; else <​LIST>​ ; fi''​|The if-clause: ​making ​decisions based on exit codes => [[syntax:​ccmd:​if_clause | article]]|+|''​if <​LIST>​ ; then <​LIST>​ ; else <​LIST>​ ; fi''​|The if clause: ​makes decisions based on exit codes => [[syntax:​ccmd:​if_clause | article]]|
 |''​while <​LIST1>​ ; do <​LIST2>​ ; done''​|Execute ''<​LIST2>''​ while ''<​LIST1>''​ returns TRUE (exit code) => [[syntax:​ccmd:​while_loop | article]]| |''​while <​LIST1>​ ; do <​LIST2>​ ; done''​|Execute ''<​LIST2>''​ while ''<​LIST1>''​ returns TRUE (exit code) => [[syntax:​ccmd:​while_loop | article]]|
 |''​until <​LIST1>​ ; do <​LIST2>​ ; done''​|Execute ''<​LIST2>''​ until ''<​LIST1>''​ returns TRUE (exit code) => [[syntax:​ccmd:​until_loop | article]]| |''​until <​LIST1>​ ; do <​LIST2>​ ; done''​|Execute ''<​LIST2>''​ until ''<​LIST1>''​ returns TRUE (exit code) => [[syntax:​ccmd:​until_loop | article]]|
Line 117: Line 117:
  
 ===== Shell Function Definitions ===== ===== Shell Function Definitions =====
-FIXME Missing an additional ​extra article about shell functions+FIXME Missing an additional article about shell functions
  
-A shell function definition ​basically ​makes a [[basicgrammar#​compound_commands | compound command]] available ​under a new name. The speciality now is, that function, ​when ran, has its own "​private"​ set of positional parameters and I/O descriptors. It acts like a script ​in the script. ​Simple said: **You create ​a new command.**+A shell function definition makes a [[basicgrammar#​compound_commands | compound command]] available ​via a new name. When the function ​runsit has its own "​private"​ set of positional parameters and I/O descriptors. It acts like a script-within-the-script. ​Simply stated: **You've created ​a new command.**
  
-The definition is easy (one of more possibilities):​+The definition is easy (one of many possibilities):​
  
 ''<​NAME>​ () <​COMPOUND_COMMAND>​ <​REDIRECTIONS>''​ ''<​NAME>​ () <​COMPOUND_COMMAND>​ <​REDIRECTIONS>''​
  
-which usually ​is used with the ''​{...;​ }''​ compound command, and thus looks like+which is usually ​used with the ''​{...;​ }''​ compound command, and thus looks like:
 <​code>​ <​code>​
 print_help() { echo "​Sorry,​ no help available";​ } print_help() { echo "​Sorry,​ no help available";​ }
 </​code>​ </​code>​
  
-Like told above, a function definition can have any [[basicgrammar#​compound_commands | compound command]] as body. Structures like+As above, a function definition can have any [[basicgrammar#​compound_commands | compound command]] as body. Structures like
 <​code>​ <​code>​
 countme() for ((x=1;​x<​=9;​x++));​ do echo $x; done countme() for ((x=1;​x<​=9;​x++));​ do echo $x; done
 </​code>​ </​code>​
-are unusual, but perfectly valid since the for-loop construct is a compound command!+are unusual, but perfectly validsince the for loop construct is a compound command!
  
-If there are **redirections** specified, ​these are not performed ​on function ​definition, they are performed ​on function ​execution:+If **redirection** is specified, ​the redirection is not performed ​when the function ​is defined. It is performed ​when the function ​runs:
 <​code>​ <​code>​
-# this will NOT perform the redirection (on definition time)+# this will NOT perform the redirection (at definition time)
 f() { echo ok ; } > file f() { echo ok ; } > file
  
Line 152: Line 152:
 </​code>​ </​code>​
  
-The space between ''​NAME''​ and ''​()''​ is optional, usually you just see it without.+The space between ''​NAME''​ and ''​()''​ is optional, usually you see it without ​the space.
  
-I suggest ​to use the first form. It's specified in POSIX and all Bourne-like shells seem to support it.+I suggest ​using the first form. It's specified in POSIX and all Bourne-like shells seem to support it.
  
-__**Note:​**__ Before version ''​2.05-alpha1'',​ Bash only recognized the definition using curly braces (''​name() { ... }''​), also, other shells allow the definition using **any** command (not only compound command set).+__**Note:​**__ Before version ''​2.05-alpha1'',​ Bash only recognized the definition using curly braces (''​name() { ... }''​),​ other shells allow the definition using **any** command (not just the compound command set).
  
-To execute a function like a regular shell script you would put it together like this:+To execute a function like a regular shell script you put it together like this:
  
 <​code>​ <​code>​
Line 166: Line 166:
 mycmd() mycmd()
 { {
-  # this $1 is the one of the function!+  # this $1 belongs to the function!
   find / -iname "​$1"​   find / -iname "​$1"​
 } }
  
-# this $1 is the one of the script itself!+# this $1 belongs ​the script itself!
 mycmd "​$1"​ # Execute command immediately after defining function ​ mycmd "​$1"​ # Execute command immediately after defining function ​
  
Line 178: Line 178:
 **Just informational(1):​** **Just informational(1):​**
  
-Internally, for forking, Bash stores ​the function definitions in environment variables. Variables with the content "//() ....//"​.+Internally, for forking, Bash stores function definitions in environment variables. Variables with the content "//() ....//"​.
  
-Something ​like the following works without "​officially"​ declaring a function:+Something ​similar to the following works without "​officially"​ declaring a function:
 <​code>​ <​code>​
 $ export testfn="​() { echo test; }" $ export testfn="​() { echo test; }"
Line 190: Line 190:
 **Just informational(2):​** **Just informational(2):​**
  
-It is possible to set function names containing slashes:+It is possible to create ​function names containing slashes:
  
 <​code>​ <​code>​
Line 198: Line 198:
 </​code>​ </​code>​
  
-The elements of this name aren't subject to path search, of course.+The elements of this name aren't subject to path search.
  
-The weird names a function ​can have should not be used. Quote from the maintainer:+Weird function ​names should not be used. Quote from the maintainer:
   * //   * //
 It was a mistake to allow such characters in function names (`unset'​ doesn'​t It was a mistake to allow such characters in function names (`unset'​ doesn'​t
Line 209: Line 209:
  
 ===== Grammar summary ===== ===== Grammar summary =====
-Not much of correct definitions,​ just some short **slogans**:​ 
   * a [[basicgrammar#​simple_commands | simple command]] is just a command and its arguments   * a [[basicgrammar#​simple_commands | simple command]] is just a command and its arguments
   * a [[basicgrammar#​pipelines | pipeline]] is one or more [[basicgrammar#​simple_commands | simple command]] probably connected in a pipe   * a [[basicgrammar#​pipelines | pipeline]] is one or more [[basicgrammar#​simple_commands | simple command]] probably connected in a pipe
   * a [[basicgrammar#​lists | list]] is one or more [[basicgrammar#​pipelines | pipelines]] connected by special operators   * a [[basicgrammar#​lists | list]] is one or more [[basicgrammar#​pipelines | pipelines]] connected by special operators
   * a [[basicgrammar#​compound_commands | compound command]] is a [[basicgrammar#​lists | list]] or a special command that forms a new meta-command   * a [[basicgrammar#​compound_commands | compound command]] is a [[basicgrammar#​lists | list]] or a special command that forms a new meta-command
-  * a [[basicgrammar#​shell_function_definitions | function definition]] makes a [[basicgrammar#​compound_commands | compound command]] available under a new name, and in some kind of separate environment+  * a [[basicgrammar#​shell_function_definitions | function definition]] makes a [[basicgrammar#​compound_commands | compound command]] available under a new name, and separate environment
  
  
Line 222: Line 221:
  
 ---- ----
-__A (very ;-)) simple command__+__A (very) simple command__
 <​code>​ <​code>​
 echo "Hello world..."​ echo "Hello world..."​
Line 238: Line 237:
 fi fi
 </​code>​ </​code>​
-  * the [[basicgrammar#​compound_commands | compound command]] for the ''​if''​-clause+  * the [[basicgrammar#​compound_commands | compound command]] for the ''​if''​ clause
   * the [[basicgrammar#​lists | list]] that ''​if''​ **checks** actually contains the [[basicgrammar#​simple_commands | simple command]] ''​[ -d /data/mp3 ]''​   * the [[basicgrammar#​lists | list]] that ''​if''​ **checks** actually contains the [[basicgrammar#​simple_commands | simple command]] ''​[ -d /data/mp3 ]''​
   * the [[basicgrammar#​lists | list]] that ''​if''​ **executes** contains a simple command (''​cp mymusic.mp3 /​data/​mp3''​)   * the [[basicgrammar#​lists | list]] that ''​if''​ **executes** contains a simple command (''​cp mymusic.mp3 /​data/​mp3''​)
  
  
-Let'​s ​reverse the exit code of the test command, only one thing changes:+Let'​s ​invert ​test command ​exit code, only one thing changes:
 <​code>​ <​code>​
 if ! [ -d /data/mp3 ]; then if ! [ -d /data/mp3 ]; then
  • syntax/basicgrammar.1439175311.txt
  • Last modified: 2015/08/10 02:55
  • by bill_thomson