Operating System Automation: POSIX Shell, AppleScript, PowerShell

a side-by-side reference sheet

grammar and invocation | variables and expression | arithmetic and logic | strings | regexes | dates and time
arrays | functions | execution control | exceptions | files | directories | processes and environment
libraries and namespaces | objects | reflection

posix shell applescript powershell
version used
dash; POSIX 2008 2.1 2.0
show version
$ osascript -e \
  "AppleScript's version"
grammar and invocation
posix shell applescript powershell
$ dash foo.sh $ osascript foo.scpt PS> .\foo.ps1

DOS> powershell -file foo.ps1
$ dash none > powershell
execute command and exit $ dash -c 'echo hi' $ osascript -e 'say "hi"' > powershell -command 'write-host "hi"'
statement separator pipelines separated by
; & && ||

lists of pipelines separated by newlines unless newline is preceded by a backslash or inside these characters:
"" '' `` ()
newline; use ⌥l (option lowercase L) to escape newline and continue statement on following line ; or newline; a newline can be escaped with a backtick: ` newlines are permitted in double quotes and after a pipe: |
word separators | & ; ( ) < > space tab
block delimiters {}
do done
keyword end keyword
on funcName end funcName
{ }
are expressions statements no yes yes
end-of-line comment
# comment -- comment # comment
comment out multiple lines <<EOF
another comment
(* comment
another comment *)
<# comment
another comment #>
variables and expressions
posix shell applescript powershell
assignment a=1
whitespace next to = not permitted
set a to 1
copy 1 to a
$a = 1
parallel assignment
none set {a,b} to {1,2} $a, $b = 1, 2
swap tmp=$a
set {a,b} to {b,a} $a, $b = $b, $a
compound assignment operators: arithmetic, string, bit none none += -= *= /= %=
+= *=
increment and decrement none none $x = 1
variable declaration
assignment, export, readonly assignment, local, global assignment
are identifiers case sensitive? yes no no
'' null $null
null test
[ -z $v ] v = null $v -eq $null
undefined variable access '' error to access uninitialized variable $null
undefined test f [ ${foo+1} ]; then
  echo "defined"
  echo "undefined"
  set t to foo
  display dialog ("defined")
on error
  display dialog ("undefined")
end try
test-path variable:\foo
arithmetic and logic
posix shell applescript powershell
true and false
status codes:
true false

inside [ ]:
1 ''
true false $true $false
falsehoods status codes:
nonzero integers

inside [ ]:
only integers convert to booleans:
false 0
0 0.0 "" ''
logical operators
status codes:
&& || !

inside [ ]:
-a -o !
and or not -and -or -not
conditional expression
$(( x>0 ? x : -x )) none none
relational expression
[ $a -gt 3 ] a > 3 $a -gt 3
relational operators
-eq -ne -gt -lt -ge -le

= != > < none none
= /= > < >= <= -eq -ne -gt -lt -ge -le
arithmetic expression
$(( 1 + 3 )) 1 + 3 1 + 3
arithmetic operators
+ - * none / % ** + - * / div mod ^ + - * / ?? % ??
integer division
$(( $a / $b )) a div b $rem = $null
$quot = [Math]::DivRem($a, $b, [ref] $rem)
integer division by zero writes "division by 0" error message; statement terminates with a 1 status error: Attempted to divide by zero
float division
`echo " scale=5; $a / $b " | bc` a / b $a / $b
float division by zero writes "division by 0" error message; statement terminates with a 1 status evaluates to Infinity which is not a float literal
[Math]::pow(2, 32)
sqrt -2
no sqrt evaluates to NaN which is not a float literal
transcendental functions e l s c none none none a none
how to use:
`echo 'e(2)' | bc -l`
[Math]::exp [Math]::log
[Math]::sin [Math]::cos [Math]::tan
[Math]::asin [Math]::acos [Math]::atan
float truncation
round towards zero, round to nearest integer, round down, round up
none and no floats [Math]::truncate(3.14)
absolute value
and signum
integer overflow
modular arithmetic converts to float
float overflow
no floats evaluates to Infinity which is not a float literal
random integer, uniform float echo $RANDOM 15 bit integer random number from 0 to 99
random number from 0.0 to 1.0
random 100
random 1.0
seed random numbers RANDOM=17
set r to random number with seed 17 $r = random -setseed 17
bit operators
<< >> & | ^ ~ none none none -band -bor -bxor -bnot

# powershell 3.0:
-lsl -lsr
posix shell applescript powershell
string literal 'don'\''t say "no"'
"don't say \"no\""
$'don\'t say "no"'
"don't say \"no\"" 'don''t say "no"'
"don't say `"no`""
newline in literal yes yes yes
escapes in double quotes
\\ \"
in $' ' quotes:
\a \b \e \f \n \r \t \v \\ \' \cc \xhh \ooo
\\ \"
\n \t \r
other backslash sequences cause syntax error
`' `" ``
`0 `a `b `f `n `r `t `v
in other backtick sequences the backtick is ignored
variable interpolation count=3
"$count ${item}s"
none $count = 3
$item = "ball"
"$count $($item)s"
length s="hello"
set s to "hello"
count s
$s = "hello"
string comparison [ $USER = foo ]
[ $USER != foo ]
# case insensitive:
-eq -ne -gt -lt -ge -le

# case sensitive:
-ceq -cne -cgt -clt -cge -cle
index of substring none set s to "foo bar"
offset of "bar" in s
returns -1 if not found:
"foo bar".indexof("bar")
extract substring s="foo bar"
set s to "foo bar"
characters 5 thru 7 of s as text
"foo bar".substring(4,3)
string concatenation c="hello, ""world" set c to "hello, " & "world" $c = "hello, " + "world"
string replication $hbar = "-" * 80
split none "foo,bar,baz" -split ","
join none @("foo","bar","baz") -join ","
sprintf `printf "tie: %s %d %f" "Spain" 13 3.7` $a = "Spain", 13, 3.7
"tie: {0} {1} {2}" -f $a
case manipulation echo "hello" | tr [a-z] [A-Z]
echo "HELLO" | tr [A-Z] [a-z]
echo -n ${A:0:1} | tr [a-z] [A-Z]; echo -n ${A:1}
strip none " hello ".trim()
pad on right, pad on left `printf "%-10s" "hello"`
`printf "%10s" "hello"`
$s = "hello"
$s + " " * (10 - $s.length)
" " * (10 - $s.length) + $s
string to number A="12"
$(( 7 + $A ))

`echo 73.9 + $B | bc`
set a to "12"
7 + a as integer

set b = ".037"
73.9 + b as real
7 + "12"

73.9 + ".037"
number to string
all values are strings 7 as text & " items" [convert]::tostring(7) + " items"

# or use variable interpolation
regular expressions
posix shell applescript powershell
regex match s=hello
if expr $s : $rx > /dev/null
if ("hello" -match "^[a-z][a-z]*$") {
single substitution s='do re mi mi mi'
s=$(echo $s | sed s/mi/ma/)
global substitution s='do re mi mi mi'
s=$(echo $s | sed s/mi/ma/g)
$s = "do re mi mi mi"
$s = $s -replace "mi", "ma"
dates and time
posix shell applescript powershell
sleep sleep 10 delay 10
posix shell applescript powershell
array literal nums=(1 2 3 4) set nums to {1,2,3,4} $nums = 1,2,3,4
$nums = @(1,2,3,4)
array size ${#nums[@]} count nums
length of nums
array lookup ${nums[0]} item 1 of nums $nums[0]
array modification nums[1]=5 set item 1 of nums to 5 $nums[0] = 5
array slice ${nums[@]:1:2} items 2 thru 3 of nums $nums[1..2]
concatenation a=(1 2 3)
b=(4 5 6)
c=(${a[@]} ${b[@]})
{1,2,3} & {4,5,6} @(1,2,3) + @(4,5,6)
manipulate back of array set a to {6,7,8}
set end of a to 9
cannot remove elements from a list
manipulate front of array set a to {6,7,8}
set beginning of a to 5
cannot remove elements from a list
array iteration for i in ${nums[@]}
do echo $i
repeat with i in nums
  display dialog(i as text)
end repeat
foreach ($i in $nums) {
  write-host $i
sort none $a = 3,2,4,1
$b = $a | Sort-Object
reverse set a to {1,2,3}
set b to reverse of a
$a = 1,2,3
posix shell applescript powershell
function definition add() { echo $(( $1 + $2 )); }
function add { echo $(( $1 + $2 )); }
on add(a, b)
  return a + b
end add
to add(a, b)
  return a + b
end add
function add {
  param ($a, $b)
  $a + $b
function invocation add 1 2 add(1,2) add 1 2
missing argument value '' error $null
extra arguments ignored ignored ignored
default argument value none none function add {
  param ($a=0, $b=0)
  $a + $b
named parameters none to displayNums from x to y
  set i to x
  repeat while i <= y
    display dialog (i as text)
    set i to i + 1
  end repeat
end displayNums
displayNums to 5 from 1
variable number of arguments args in $1, $2, … with number of args in $# none
return value return arg available in $? variable if a positive integer smaller than 256 argument of return or value of last statement executed
lambda declaration none none $x = { write-host "foo" }
lambda invocation none none & $x
default scope global local
nested function definition visible outside containing function disallowed
execution control
posix shell applescript powershell
if if [ $n -eq 0 ]
then echo "no hits"
elif [ $n -eq 1 ]
then echo "1 hit"
else echo $n " hits"
if n = 0 then
  display dialog ("0 hits")
else if n = 1 then
  display dialog ("1 hit")
  set s to n as text & " hits"
  display dialog (s)
end if
if ($n -eq 0) {
  write-host "no hits"
} elseif ($n -eq 1) {
  write-host "one hit"
} else {
  write-host "$n hits"
while i=0
while [ $i -lt 10 ]
do i=$(($i + 1))
echo $i
set i to 0
repeat while i < 10
  set i to i + 1
  display dialog (i as text)
end repeat
$i = 0
while ($i -lt 10) {
  write-host (++$i)
break/continue break continue exit none break continue
for for i in 1 2 3
do echo $i
repeat with i from 1 to 3
  display dialog (i as text)
end repeat
for ($i=1; $i -le 3; $i++) {
  write-host $i
posix shell applescript powershell
raise exception return nonzero status error "bam!" throw "bam!"
catch exception trap 'echo "risky failed"' ERR
  error "bam!"
on error msg
  display dialog ("error: " & msg)
end try
try {
  throw "bam!"
catch {
  write-host "caught!"
uncaught exception behavior stderr and continue display error and exits
posix shell applescript powershell
print to standard out echo "hi world" popup window:
display dialog("hi world")
write-host "hi world"
standard file handles /dev/stdin
read line `head -1 /etc/passwd` set f to POSIX file "/etc/passwd"
set a to read f as text using delimiter linefeed
item 1 of a
read file `cat /tmp/a` set f to POSIX file "/tmp/a"
set s to f as text
write to file echo "hello" > /tmp/a set f to POSIX file "/tmp/a"
open for access f with write permission
write "hello" to f
close access f
append to file echo "hello" >> /tmp/a set f to POSIX file "/tmp/a"
open for access f with write permission
write "hello" to f starting at eof
close access f
posix shell applescript powershell
processes and environment
posix shell applescript powershell
external command ls do shell script "ls" dir
backticks s=`ls` set s to do shell script "ls" $s=dir
command line args $#
must declare run handler:
on run argv
  length of argv
  item 1 of argv
  item 2 of argv
end run
speech depends on OS say "I'm a Mac" $sp = new-object -comobject "SAPI.SpVoice"
$sp.speak("I'm a PC")
environment variable shell variables are environment variables
system attribute "HOME" $env:home
command path which ping get-command ping
exit exit 0 none exit
set signal handler function int_handler {
  echo "exiting…";

trap int_handler INT
start job in background sleep 1000 & none
suspend current job ^Z none
list jobs jobs none
background suspended job bg %1 none
bring background job into foreground fg %1 none
disown job disown %1 none
libraries and namespaces
posix shell applescript powershell
library $ cat foo.sh
function add() {
  echo $(($1 + $2));
$ cat foo.applescript
on showText(theText)
  display dialog (theText)
end showText
$ osascript -o foo.scpt foo.applescript
import library source foo.sh
add 3 7
set f to "/path/to/foo.scpt"
set foo to (load script POSIX file f)
tell foo to showText("bar")
library path none
library path environment variable none
namespace declaration none
namespace separator none
posix shell applescript powershell
define class on makeInt(val)
  script theInt
    property value : val
    on addOne()
      set value to value + 1
    end addOne
  end script
  return theInt
end makeInt
create object set anInt to makeInt(7)
getter and setter get value of anInt
set value of anInt to 9
invoke method tell anInt to addOne()
posix shell applescript powershell
class set s to "hello"
display dialog class of s
list defined variables printenv get-variable
__________________________________________________________ __________________________________________________________ __________________________________________________________


version used

The version of the language used for verifying the examples in the reference sheet.

show version

How to get the version.

Grammar and Invocation


The customary name of the interpreter and how to invoke it.

posix shell:

On Unix, scripts are executing by passing the file containing the script to the interpreter as an argument:

$ dash ~/configure.sh

If the executable bit is set, the file can be run directly:

$ ~/configure.sh

To determine the name of the interpreter that will process the script, Unix will look for the presence of a shebang (#!) at the start of the file. If the pathname to a command follows the shebang, it will be used to interpret the script. If no shebang is present, the script will be interpreted with /bin/sh which is bash on Mac OS X and Cygwin and dash on Ubuntu.

Command line arguments which set the positional parameters $1, $2, and so on can be set upon invocation as follows:

$ dash ~/configure.sh arg1 arg2
$ ~/configure.sh arg1 arg2

Arguments can also be put on the shebang line, but this is only useful for passing options to the shell. If the file foo.sh contains

#!/bin/sh -x

then invoking it as


is equivalent to

/bin/sh -x foo.sh

Hardcoding a full path in a shebang is a common cause of portability problems because different systems may install the interpreter in different locations. The env command avoids the problem by searching the PATH directories for the command:

#!/usr/bin/env lua


On Windows, a file is a PowerShell script if it has a .ps1 suffix. There is no need to mark the script as executable. However, PowerShell is not configured to run scripts by default. To change the configuration, start a PowerShell as an Administrator and run the following command:

set-executionpolicy remotesigned

It is possible to invoke a PowerShell script by specifying the PowerShell interpreter as the command and the script as an argument, but the suffix of the file must still be ps1:

powershell -file .\test.ps1


How to invoke the REPL.


The closest to a AppleScript REPL is to launch the AppleScript Editor. Snippets of AppleScript code can be entered into the upper pane. When the Run button is clicked, the return value of the last statement executed will be displayed in the lower pane.

execute command and exit

How to pass a single command to be executed as a command line argument.

statement separator

How the parser determines the end of a statement.

posix shell:

A posix shell simple command consists of optional variable assignments, followed by a command and zero or more arguments and redirections. The command can be an external command, user defined function, or built-in.

A posix shell pipeline is a sequence of one or more simple commands joined by pipes |. The shell executes the commands in parallel and redirects the stdout of each command to the stdin of the following command. The exit status is the status of the last command.

The control operators ; & && || are pipeline separators. The semicolon ; enforces sequential execution. The ampersand & executes in parallel. The && executes to the first pipeline that returns a nonzero status. The || executes to the first pipeline that returns a zero status.

A list is one or more pipelines joined by control operators. A list can have a semicolon ; or ampersand & at the end. A list is terminated by a newline.

A newline does not terminate a list when:

  • inside single quotes '', double quotes "", backticks ``, or parens ()
  • inside a block started by the keywords: for, select, case, if, while, until

A newline that would normally terminate a statement can be escaped with a backslash.

Multiple lists can be grouped inside parens ( ) or curly brackets { }. When grouped inside parens, the lists are executed inside a subshell. The curly brackets, but not the parens, must be separated from their contents by white space. Also, within curly brackets, but not within parens, the last list must be terminated by a semicolon or newline.

word separators

block delimiters

How blocks are delimited.


Blocks can be delimited with {}, (), or the do,done keywords.

If a block is started with an open curly bracket {, then the block must be terminated with a line containing a close curly bracket by itself }.

If a block is delimited by (), then the commands in the block are executed in a subshell.

A block is delimited by do and done when using the execution control keywords for, select, while, and until.

The then and else keywords of an if statement start blocks which are terminated by a following elif, else, or fi.

The function and if keywords open blocks which are terminated by end keywords. The repeat keyword opens a block which is terminated by until.

to end-of-line comment

How to make the remainder of the line a comment.


The # syntax for comments is only available in non-interactive shells unless the INTERACTIVE_COMMENTS option is set. If an interactive shell encounters a # where a command is expected a command not found error will result.

multiline comment

How to comment out multiple lines.


The method described is the syntax for a here document, which is a multiline string literal.

Variables and Expressions


How to assign a value to a variable.


set and copy are not synonyms when operating on lists, records, or objects. The set command makes the left variable an alias of the right variable: the two variables then refer to the same array, record, or object. The copy command will put a copy of the array, record, or object contained in the left variable.

parallel assignment

How to assign values to variables in parallel.


How to exchange the values held by two variables.

compound assignment operators: arithmetic, string, bit

The compound assignment operators for arithmetic, string, and bit operations


Note that /= performs float division, even when both operands are integers.

When the left operand is a string, += concatenates the right operand to the left operand.

When the left operand is a string and the right operand an integer, *= concatenates the left operand with itself right operand times.

increment and decrement

The C-style increment and decrement operators which can be used in expressions.

variable declaration

How to declare a variable.


The following three lines have identical behavior:

A="hello, world"
declare A="hello, world"
typeset A="hello, world"

It is possible to make a read only variable. Again there are three ways:

readonly A="can't change"
declare -r A="can't change"
typeset -r A="can't change"

Variables are not exported to subprocesses unless declared to be exported:

export A="exported to subprocess"
declare -x A="exported to subprocess"
typeset -x A="exported to subprocess"

Variables assigned on the same line as a command are not created, only exported to the subprocess that instantiates the command:

EDITOR=emacs svn commit

By default variables defined inside functions are global. They can be declared to be local:

function foo () {
  local b=17
  # echoes 17:
  echo $b
# echoes nothing:
echo $b


Variables can be declared as local or global. It is not possible to initialize a variable in a declaration. Undeclared variables are local: in the example below, c and e are not visible outside the function foo:

on foo(a,b)
  local c
  global d
  set c to a+b
  set d to a+b
  set e to a+b
end foo

are identifiers case sensitive?


In AppleScript, identifiers are case insensitive. This holds for reserved keywords as well as user defined variable names. The AppleScript Editor converts all keywords and identifiers in the source code to lower case when it is compiled.


PowerShell identifiers are case insensitive.


The null literal.

null test

How to test if a value is null.

undefined variable access

The value of an undefined variable, or the system behavior if there is no such value.

undefined test

How to determine if a variable is undefined.

posix shell:

The expression ${var+val} is val if var is defined, otherwise it is the empty string ''.

The expression ${var:+val} is val if var is defined and not null, otherwise it is the empty string ''.

Arithmetic and Logic

posix shell:

The POSIX shell provides at least three different environments for logical expressions, each with their own operators and values for true and false.

Logical expressions are usually encountered in the conditionals of if, elif, while, and until. A command is expected as the conditional expression. The command is executed, and a return value of zero is treated as true and nonzero as false.

status codes [ ] $(( ))
where used command command argument
true true no canonical true value 1
false false '' 0
falsehoods nonzero exit status '' 0
logical operators && || ! -a -o ! && || !
grouping { } \( \) ( )
string relational operators none = != \< \> none
arithmetic relational operators none -eq -ne -lt -gt -le -ge == != < > <= >=
arithmetic operators none none + - * / % **
bit operators none none << >> & | ^ ~

posix shell: status codes:

Logical expressions can be formed using status codes returned by commands. The commands can be external, built-in, or user defined functions. A status code of zero is used to indicate success, and for the purpose of logic zero is treated as true and all other status codes as false.

The && and || operators are short circuit operators. An exclamation point ! can be used to negate the status code of a command. It is not necessary to separate && and || from their operands with whitespace, but it is necessary to mark off a ! used as negation with whitespace.

posix shell: test command:

posix shell: arithmetic expansion:

true and false

The literals for true and false.


Values which are false in conditional expressions.

logical operators

Logical and, or, and not.


&& || and ! are available inside [[ ]], (( )), and $(( )) expressions. Inside [ ] expressions use -a, -o, and !.

conditional expression

The syntax for a conditional expression.

are expressions statements

Whether an expression can be used where a statement is expected.

relational expressions


Bash has three types of relational expressions: [[ ]], [ ], and (( )). For a description of [ ], read the man page for test.

(( )) evaluates its contents in the same manner as the arithmetic expansion $(( )). If the result is zero, it returns 1 (false). Otherwise it returns 0 (true).

[[ $a == pattern ]] and [[ $a != pattern ]] interpret * and ? on the right side as patterns. Thus "hello" == "hell*" is true. For numeric comparison, use [ $a -eq num ] or [ $a -ne num ].

Bash expressions discusses the different types of bash expressions in more detail.

relational operators


If == and =! have an unquoted string on the right, then * and ? within the string will be treated as wild cards for matching.


Verbal synonyms for the relational operators are provided. For = the synonyms are equals, is equal, equal to, and is equal to.

convert from string


All values are strings. The $(( )) operator will interpolate any variables and then evaluate the resulting string as an arithmetic expression composed of integers. The variables are not limited to containing integers. The following script outputs 10:

echo $(($A))

To perform floating point arithmetic, bash must shell out to a floating point utility such as bc.

convert to string

arithmetic expressions

How to evaluate an arithmetic expression.


Bash arithmetic is available within $(( )) and (( )). The latter form evaluates the arithmetic expression and returns status 1 if the result zero, and 0 otherwise.

Bash only has integer arithmetic. For floating point arithmetic, use the external commands bc or dc.

arithmetic operators

The operators for addition, subtraction, multiplication, float division, integer division, modulus, and exponentiation. Some languages provide a function pow instead of an operator for exponentiation.


arithmetic operators are available in $(( )) and (( )).

integer division

How to perform integer division.

float division

How to perform floating point division, even if the operands might be integers.


The bash shell lacks built-in floating point arithmetic. bc is an arbitrary precision calculator, and scale is the number of digits to the right of the decimal point. If scale is not specified, it defaults to zero, which results in integer division.

It is also possible to use dc, which is a reverse polish notation arbitrary precision calculator:

`echo " 5 k $a $b / p " | dc`

arithmetic functions

Functions for computing square root, natural exponent, natural logarithm, sine, cosine, tangent, arcsine, arccosine, arctangent, and atan2.

The trigonometric functions are all in radians. atan2 takes two arguments which are the x and y co-ordinates of a vector in the Cartesian plane. It returns
the angle to the positive x-axis made by the vector.


There is a zsh module which provides the standard transcendental math functions. It is not installed by default on Mac OS X, the CentOS distribution of Linux, or Cygwin. The module can be compiled into the zsh, or it can be in a shared library which is loaded with the command zmodload mathfunc.

arithmetic truncation

division by zero

integer overflow

float overflow

sqrt -2

The result of taking the square root of -2.

random integer, uniform float

The examples show how to generate a uniform random integer in the range from 0 to 99, inclusive; how to generate a uniform float in the range 0.0 to 1.0; how to generate a float from a standard normal distribution


$RANDOM evaluates to a random integer between 0 and 32767 inclusive.


$RANDOM evaluates to a random integer between 0 and 32767 inclusive.

seed random numbers


Bash 3.2.48 seeds the random number at start up using the current time and the PID:

  /* Seed the random number generator. */
  sbrand (dollar_dollar_pid + shell_start_time);

Here is the random number generation code:

/* A linear congruential random number generator based on the example
   one in the ANSI C standard.  This one isn't very good, but a more
   complicated one is overkill. */

/* Returns a pseudo-random number between 0 and 32767. */
static int
brand ()
  rseed = rseed * 1103515245 + 12345;
  return ((unsigned int)((rseed >> 16) & 32767));    /* was % 32768 */


Zsh rand and srand from the standard C library to generate random numbers. It uses the current time at startup to seed the random number generator. Here is the source code from zsh 4.3.9:

    gettimeofday(&shtimer, &dummy_tz);    /* init $SECONDS */
    srand((unsigned int)(shtimer.tv_sec + shtimer.tv_usec)); /* seed $RANDOM */


The initial seed is set to a value that varies each time AppleScript is started up.

If a repeatable sequence of random numbers is desired, the seed can be set to a specific value using the with seed parameter on the first call to random.


The initial seed is set to a value that varies each time PowerShell is started up.

If a repeatable sequence of random numbers is desired, the seed can be set to a specific value using the -setseed option on the first call to random.

bit operators


The bit operators are available in $(( )) and (( )).


string literal

The syntax for a string literal and how to escape the delimiter.

newline in literal

Whether a newline character sequence can be included in a string.

For all the languages described in this reference sheet a string literal is permitted to encompass multiple lines in the source code and the resulting string will contain the same number of lines.


Character escape sequences which can be used in string literals.

variable interpolation

How to interpolate variables in a string.


A dollar sign $ can be backslash escaped to prevent variable interpolation:

echo "the value of \$a is $a"


A dollar sign $ can be backtick escaped to prevent variable interpolation:

write-host "the value of @@`@@$a is $a"


How to get the length of a string.

string comparison

How to determine if two strings are equal or unequal.

index substring

How to find the index of the start of a substring in a string.

extract substring

string concatenation

The string concatenation operator.


How to split a string into an array of strings.


When splitting a string into words, no delimiter need be specified and the string to be split can follow the -split operator:

-split "foo bar baz"


How to concatenate the elements of an array into a string with a separator.



How to create a string using a printf style format.

case manipulation


pad on right, pad on left

Regular Expressions

regex match

How to test whether a regular expression matches a string.

posix shell:

The double square bracket operator [[ ]] is not part of the POSIX standard but it is a feature of bash, ksh, and zsh. It supports a match test operator:

if [[ "hello" =~ ^[a-z][a-z]*$ ]]; then

single substitution

How to replace the first occurrence of a pattern in a string.

posix shell:

The following parameter expansion is not part of the POSIX standard but provided by bash, ksh, and zsh:

str='do re mi mi mi'
echo ${str/mi/ma}

global substitution

How to replace all occurrences of a pattern in a string.

posix shell:

The following parameter expansion is not part of the POSIX standard but provided by bash, ksh, and zsh:

str='do re mi mi mi'
echo ${str//mi/ma}

Dates and Time


bash zsh applescript powershell
array list array
dictionary record

array literal

Array literal syntax.

array size

How to get the number of elements in an array.

array lookup

How to access a value in an array by index.

array slice

How to slice a subarray from an array.

array iteration


How to test for membership in an array.


How to compute an intersection.





universal predicate

How to test whether a condition holds for all members of an array. Always true for an empty array.

existential predicate

How to test whether an item in an array exists for which a condition holds. Always false for an empty array.

dictionary literal

dictionary size

dictionary lookup

dictionary iteration

out of bounds behavior


Python has both functions and methods. Ruby only has methods: functions defined at the top level are in fact methods on a special main object. Perl subroutines can be invoked with a function syntax or a method syntax.

function definition


A bash function definition can alternately be preceded by the keyword function, and when used, the parens following the function name are prohibited.


A zsh function can be defined with the preceding keyword function, the trailing parens, or both.


Functions are called handlers in AppleScript.

function invocation


The syntax for invoking a function is the same as the syntax for invoking a command. If a function is defined with the same name as a command in the search path, the function will be executed.

missing argument value

Value of an argument variable if a function is invoked with fewer arguments than are declared.

extra arguments

If a function is invoked with more arguments than are declared, how the function can access them.

default argument value

How to declare a default value for an argument.

variable number of arguments

How to write a function which accepts a variable number of argument.

named parameters

How to write a function which uses named parameters.


Named parameters are called labeled parameters in the AppleScript documentation. The label must be one of the following prepositions:

about, above, against, apart from, around, aside from, at, below, beneath, beside, between, by, for, from,
instead of, into, on, onto, out of, over, since, thru/through, to, under

For readability the definite article the can be inserted in between the label and the argument in either the function definition or the invocation.

To use other names for parameters, the given keyword can be used in conjunction with colon syntax:

on displayNums given startAt:x, endAt:y
  set i to x
  repeat while i <= y
    display dialog (i as text)
    set i to i + 1
  end repeat
end displayNums

displayNums given startAt:1, endAt:5

When a given parameter takes a boolean value as an argument, the with or without keywords can be used when the handler is invoked. Consider the following handler definition:

on foo given flagLabel:flag
end foo

Here are two ways to invoke foo with flag set to true:

foo given flagLabel:true
foo with flagLabel

Here are two ways to invoke foo with flag set to false:

foo given flagLabel:false
foo without flagLabel

return value


Bash functions can only return small integers via return. However, a function can echo to stdout and the caller can invoke it with backticks to get a string value.

lambda declaration

How to define a lambda function.

lambda invocation

default scope


By default, bash and variables inside functions have global scope.

Execution Control


Some optional branching constructs:


case $a in (0) echo "no";; (1) echo "yes";; (2) echo "maybe";; (*) echo "error";; esac



Also has an until loop.


break exits a for or while loop immediately. continue goes to the next iteration of the loop. redo goes back to the beginning of the current iteration.



A C-style for loop:

for ((i=0; i<10; i++ )); do echo $i; done


If a block of code needs to be executed a set number of times but no index variable is needed, AppleScript provides this alternate syntax:

repeat 3 times
    display dialog ("tut")
end repeat


raise exception

How to raise an exception.


It is possible to associate an error code with the error using the number label:

error "bam!" number 7

If no error number is specified, then the value -2700 is used.

catch exception

How to handle an exception.


If a variable name is specified after on error the error message is stored in it. There can only be one error clause and it catches all errors. To perform conditional error handling, use the number label and provide a variable name after it. The error code will be stored in that variable.

  error "bam!" number 7
on error msg number errorCode
  if errorCode = 7 then
    display dialog ("error: " & msg)
    display dialog ("unknown error")
  end if
end try

A try block can be closed by end error in addition to end try.

uncaught exception behavior

System behavior if an exception goes uncaught. Most interpreters print the exception message to stderr and exit with a nonzero status.


The bash interpreter writes a message to stderr whenever a command returns a nonzero status. By default, the interpreter does not exit, but if this behavior is desired, then the following should be put at the top of the script:

trap exit ERR

wait on thread


print to standard out


To prevent echo from appending a newline to the output, use

echo -n "hello"

standard filehandles


AppleScript does not in general run with stdin and stdout filehandles. When osascript is invoked as a shebang it is possible to read from stdin and write to stdout, however:

#!/usr/bin/env osascript 
set stdin to do shell script "cat" 
"Received from stdin: " & stdin

Here is how the above script would be invoked:

$ echo "foo" | ./stdin-example.sh 
Received from stdin: foo

read line

read file

write to file

append to file


Processes and Environment

external command


The syntax for calling an external command is the same as the syntax for invoking a function. If a function is defined with the same name as an external command in the search path, the function is invoked.


command line args


How to make the computer talk.

bash, zsh:

On Mac OSX the command say can also be executed from the bash or zsh prompt:

say "I'm a Mac"

On Ubuntu Linux this command can be used:

espeak "I'm Unix"

environment variable

command path

The directory containing a command. Also indicates if the command is a built-in, alias, or function. Shows the definition of aliases and functions.


zsh has both which and which -a. The latter shows all occurrences of a command in the search path.



The exit status of a bash script is the return status of the last command executed, or the argument of exit.

set signal handler

Libraries and Namespaces


What a library looks like.

import library

library path

namespace declaration

namespace separator


define class

create object


define method

invoke method


default method





POSIX 2008
dash man page
ksh man page
bash man Page

On most modern systems if you invoke /bin/sh you get the bash shell. If your script might get run by the older Bourne shell (1977), here are the differences to think about.

A function and a variable can have the same name. User defined variable identifiers cannot start with a digit. Variables are normally global, but can be made local to a function with the local keyword, which is useful for recursive functions.

The behavior of a shell script is dependent on its environment. All environment variables that existed when the shell process starts become variables in the script’s namespace. If the name of a command does not resolve to a shell built-in command or a function defined by the script, the shell searches the $PATH variable for an external command to run. The shell will expand ?, *, and ~ in words using the local file system.

The shell is good at launching external processes and redirecting their stdin and stdout to files or other processes with >, >>, , 2>>, or 2>&1.


  • AppleScript Editor, osacompile, oascript
  • getting dictionary for application, sending commands to an application
  • I/O (display dialog, say, log)
  • applications, windows, tabs
  • open scripting architecture (OSA)


content of this page licensed under creative commons attribution-sharealike 3.0