MySVC
an open source UNIX framework for shell script based web services provider
»Home
»Tools
»Man Page
»User Guide
»ChangeLog
»Installation
»Source Code
»Downloads
»FAQ
»Support
»License

»My Apps

Table of Contents

Summary

myste is an open source UNIX standalone tool part of MySVC framework.

It is a bourne shell script as template engine to handle template files having features of other UNIX tools such as C preprocessor, m4 macro processor, awk, tar, ftp and other original features useful into ICT environments such as (N,K) combinations and disposition generator, capitalized strings converter or readable archive of text file creator

Introduction

MySTE (My Service Template Engine) is a template engine, an open source UNIX tool to handle template files.

It has features of other UNIX tools such as C preprocessor, m4 macro processor, awk and tar, but is more simple to use and add other original features useful into ICT environments; e.g.:

  • filter copying from stdin to stdout where input can contains directives (identified by lines beginning with "@"), such as parameter definitions, and normal text referencing those parameters, e.g.:

 ...
 @define username myusr
 @define password mypwd
 login is @username@/@password@...
 ...
  • tool to handle configuration files from shell script, e.g.:

 ...
 usr=`myste myconfigfile username`
 pwd=`myste myconfigfile password`
 ...
  • expand a definition referencing numbered or named fields for each instance record read from file, from standard input or from another definition:

input

 @define sim_activate_prepaid(msisdn,imsi)
 SIM:ACTIVATE:PREPAID:@msisdn[3]@:@imsi@:TIMESTAMP:@$(date '+%Y%m%d%H%M%S')@
 @end
 @define sim_list_postpaid
 222981122334455 393801234567
 222981122334456 393801234568
 222981122334457 393801234569
 @end
 @define sim_list_prepaid
 393801234567 222981122334455
 393801234568 222981122334456
 393801234569 222981122334457
 @end
 @foreach sim_list_postpaid
 SIM:ACTIVATE:POSTPAID:@2[3]@:@1@:TIMESTAMP:@$(date '+%Y%m%d%H%M%S')@
 @end
 @foreach sim_list_prepaid
 @sim_activate_prepaid(@1@,@2@)@
 @end

output

 SIM:ACTIVATE:POSTPAID:3801234567:222981122334455:TIMESTAMP:20090406231917
 SIM:ACTIVATE:POSTPAID:3801234568:222981122334456:TIMESTAMP:20090406231917
 SIM:ACTIVATE:POSTPAID:3801234569:222981122334457:TIMESTAMP:20090406231917
 SIM:ACTIVATE:PREPAID:3801234567:222981122334455:TIMESTAMP:20090406231917
 SIM:ACTIVATE:PREPAID:3801234568:222981122334456:TIMESTAMP:20090406231917
 SIM:ACTIVATE:PREPAID:3801234569:222981122334457:TIMESTAMP:20090406231917
  • to handle ftp put get del dir from command line with or without recursion on subdirectories, e.g.:

 @dir ftp://myusername:mypassword@myremotehost/my/remote/file
 @dir ftp://myusername:mypassword@myremotehost/my/remote/dir *.txt
 @get ftp://myusername:mypassword@myremotehost/my/remote/file /my/local/dir
 @get ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
 @put ftp://myusername:mypassword@myremotehost/my/remote/file /my/local/dir
 @put ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
 @del ftp://myusername:mypassword@myremotehost/my/remote/file
 @del ftp://myusername:mypassword@myremotehost/my/remote/dir
  • generating all (or random) N,K combinations or dispositions (or a subset defined by an external process as sequence validator):

input

 @sequence 5,4
 ...
 @sequence 3^2
 ...
 @sequence 6,4 /my/external/validator
 ...
 @random 7 4
 ...
 @foreach 4,3
 the items of sequence are @1@, @2@ and @3@ (sequence @0@)
 @end

output

 1 2 3 4
 1 2 3 5
 1 2 4 5
 1 3 4 5
 2 3 4 5
 ...
 1,1
 1,2
 1,3
 2,1
 2,2
 2,3
 3,1
 3,2
 3,3
 ...
 1 4 5 6
 2 3 4 5
 ...
 3
 2
 7
 1
 ...
 the items of sequence are 1, 2 and 3 (sequence 1 2 3)
 the items of sequence are 1, 2 and 4 (sequence 1 2 4)
 the items of sequence are 1, 3 and 4 (sequence 1 3 4)
 the items of sequence are 2, 3 and 4 (sequence 2 3 4)
  • handling an archive of text files (such tar cvf, tvf or xvf…):

input

 first file...
 @file a/b/f1.txt
 this is the first file content...
 @define A
 11 22 33
 44 55 66
 @end
 A value is @A@
 @end a/b/f1.txt
 second file...
 @define mysecondfile f2.txt
 @file @mysecondfile@
 this is the content...
 ... of the second file
 containing two templates...
 @template t1
 @define X 11
 @define Y 12
 @end t1
 @template t2
 @define X 21
 @define Y 22
 @end t2
 @end @mysecondfile@
 last file...
 @file f3.txt
 last file content...
 @end f3.txt
 @extract

output

 first file...
 second file...
 last file...

file f1.txt

  this is the first file content...
  @define A
  11 22 33
  44 55 66
  @end
  A value is @A@

file f2.txt

  this is the content...
  ... of the second file
  containing two templates...
  @template t1
  @define X 11
  @define Y 12
  @end t1
  @template t2
  @define X 21
  @define Y 22
  @end t2

file f3.txt

  last file content...

It is implemented as (bourne) shell script using only standard UNIX commands and is designed as a front end of its engine, an internal shell function awk based called smp (Simple Macro Processor).

By default, when executed without command line parameters, myste is a filter that copies standard input to standard output and could contains one of the following:

  • normal text (not copied on standard output when myste is executed with command line parameters) containing also references to parameter values enclosed between two "@" characters (e.g. "myparameter value is @myparameter@"), being "@" the only special character handled by myste

  • processing instructions specified with a "@" character at begin of a line followed by a command and parameters (e.g. "@define myparameter 1")

Command line

myste [-t "<template>"]
      [-f "<inputfile>"]
      [-p <arguments>]
      [-H "<header>"]
      [-F "<footer>"]]
      [-d "<separator>"]
      [-o <outputfile>]]
      [-D "<name>[=<value>]"]*
      [-s <n>,<k> [<validator>]]
      [-s <n>^<k> [<validator>]]
      [-r <n>,<k> [<repetion>]]
      [-r <n>^<k> [<repetion>]]
      [-r <n> [<repetion>]]
      [dir ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<remotefiles>=*]]
      [get ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<localdir>=.] [<remotefiles>=*]]
      [put ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>] [<localdir>=.|<localfile>] [<localfiles>=*]]
      [del ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<remotefiles>=*]]
      [-e]
      [-x]
      [-C]
      [-T]
      [-X]
      [-l]
      [[-c]<configfile>]
      ["<parameter>"]
-e => foreach
-x => export
-C => create archive
-T => list archive
-X => extract archive
-l => extract on stdout
-s <n>,<k> => (valid) combinations (n>k)
-s <n>^<k> => (valid) dispositions
-r <n>,<k> => combination(s) (n>k)
-r <n>^<k> => disposition(s)
-r <n> => random integer between 1 and <n>
-n => not execute

Syntax

myste input contains any text including one of the following commands, each starting at begin of the line:

  @template <name>[(<arg1>,...,<argN>)]
  ...
  <value>
  ...
  @end <name>

  @eval <name>[(<arg1>,...,<argN>)]

  @define <name>[(<arg1>,...,<argN>>)] <value>

  @define <name>[(<arg1>,...,<argN>>)]
  ...
  <value>
  ...
  @end

  @undef [<name>]

  @ifdef <name> [<value>]
  ...
  <value>
  ...
  @endif

  @ifdef <name> [<value>]
  ...
  <value>
  ...
  @else
  ...
  <value>
  ...
  @endif

  @ifndef <name> [<value>]
  ...
  <value>
  ...
  @endif

  @ifndef <name> [<value>]
  ...
  <value>
  ...
  @else
  ...
  <value>
  ...
  @endif

  @include <name>

  @foreach <name>[(<arg1>,...,<argN>)] <value>

  @foreach <name>[(<arg1>,...,<argN>)]
  ...
  <value>
  ...
  @end

  @printf <name> [<value>]

  @system <value>

  @system
  ...
  <value>
  ...
  @end

  @env [<name>]

  @export [<value>]

  @sequence <value>,<value> [<value>]

  @sequence <value>^<value> [<value>]

  @random <value>,<value> [<value>]

  @random <value>^<value> [<value>]

  @random <value> [<value>]

  @exit [<code>] [<value>]

  @file <value>
  ...
  <value>
  ...
  @end <value>

  @extract [stdout] [<value>]

  @extract list

  @archive [<value>] [<value>]

  @dir <localdir>

  @dir ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<remotefiles>=*]

  @get ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<localdir>=.] [<remotefiles>=*]

  @put ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>] [<localdir>=.|<localfile>] [<localfiles>=*]

  @del ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [<remotefiles>=*]

  @foreach ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] [dir] [<remotefiles>=*]
  ...
  <value> (fields as "ls -l" output)
  ...
  @end

  @foreach ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] get [<localdir>=.] [<remotefiles>=*]
  ...
  <value>
  ...
  @end

  @foreach ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>] put [<localdir>=.|<localfile>] [<localfiles>=*]
  ...
  <value>
  ...
  @end

  @foreach ftp://<username>[:<password>]@<remotehost>[:<port>][/<remotedir>[/.]|<remotefile>] del [<remotefiles>=*]
  ...
  <value>
  ...
  @end

Notes

  • a template, defined with @template, could contains anything but others templates and is evaluated with @eval (similar to @include but with lines imported from template definition instead of file)

  • the text value of a macro, defined with @define, could contains references to other macro values, as:

    • @name@

    • @name(arg1,…,argN)@ ⇒ name (template or macro) value

    • @name[i]@

    • @name(arg1,…,argN)[i]@ ⇒ substring of each row of name value starting from i, with i>=1

    • @name[i,j]@

    • @name(arg1,…,argN)[i,j]@ ⇒ substring of each row of name value starting from i with length j

    • @name<list>@ ⇒ repeat the value of name for each row of list value, or for each row of csv file list if macro named list is not defined name definition could contains references to

    • @0@ for actual record (line)

    • @1@ for first field of record

    • @2@ for second field of record …

    • @n@ for n-th field of record

    • @NF@ for the number of field of actual record (with NF>=1)

    • @NR@ for the number of actual record (with NR>=1) the default field separator (spaces or tabs) can be changed defining a value for the FS reserved variable (e.g. @define FS ,)

    • @name<list>[i]@ ⇒ repeat substring (starting from i) for each row of list value, or for each row of file list if macro named list is not defined

    • @name<list>[i,j]@ ⇒ repeat substring (starting from i with length j) for each row of list value, or for each row of file list if macro named list is not defined

    • @$(command)@ ⇒ is the output generated from an external command

    • @?(command)@ ⇒ is the exit status generated from an external command

    • @name++@ ⇒ return value and then increment it

    • @name--@ ⇒ return value and then decrement it

    • @++name@ ⇒ increment value and then return it

    • @--name@ ⇒ decrement value and then return it

    • @>(string)@ ⇒ is the upper case version of string ("this Is a String" → "THIS IS A STRING")

    • @<(string)@ ⇒ is the lower case version of string ("this Is a String" → "this is a string")

    • @-(string)@ ⇒ is the word separated version of a capitalized string ("thisIsAString" → "this-is-a-string") the "-" character is used as default separator or WS ("word separator") value if is defined (e.g. @define WS _)

    • @.(string)@ ⇒ is the capitalized version of an word separated string ("this-is-a-string" → "thisIsAString") the "-" character is used as default separator or WS ("word separator") value if is defined (e.g. @define WS _)

  • @ifdef, @ifndef, @undef and @include have the usual meaning as the C preprocessor, but can be specified a regular expression as value for pattern matching with name value @foreach list, like @name<list>@, repeat the value specified for each row of list value, or for each row of file list if macro named list is not defined (having @0@, @1@,…, @NF@ and @NR@ in the value the same meaning as in @name<list>@)

  • @system execute external commands

  • @export create a bourne shell export script for all parameters

  • @export <regexp> create bourne shell export script for parameters whose name match with regular expression <regexp> or with regular expressions contained into value of <regexp>

  • @extract extract all @files

  • @extract [stdout] <regexp> extract all files (@file) whose path match with regular expression <regexp> or with regular expressions contained into value of <regexp>

  • if optional stdout option is specified after @extract then files are extracted on stdout

  • @sequence n,k generates all combinations with n and k parameters

  • @sequence n^k generates all dispositions with n and k parameters

  • for combination and disposition sequences can be specified the optional parameter <validator> which is a path to an external application called for each partial or complete sequence using sequence values as command line arguments: if the application return an exit status 0 then the sequence is valid else is not valid if a partial sequence is not valid then all sequences having this partial sequence as prefix are not generated

  • only valid sequences go to standard output (without <validator> than as default all sequences are valid)

  • @random n,k generates a random combination with n and k parameters

  • @random n^k generates a random disposition with n and k parameters

  • @random n generates a random number between 1 and n

  • for random combination and disposition can be specified the optional parameter <repetition> in order to specify the number of random sequences that has to be generated (default is 1)

  • define stdout reserverd variable to forward standard output to file or to a buffer if is defined

  • define stdout to empty or /dev/null value to suppress output

  • undef stdout to return on normal output

  • there is only one global scope

  • all environment variables are initially defined

  • to package (on stdout) more files (even myste configuration files) into one unique file can be used the -C option of myste followed by optionals parameters [<rootdir>] and [<path>] (same as find <rootdir> -path <path>) where each file content will be delimited between @file <path> and @end <path>

  • to extract all packaged files can be used -X option of ste, optionally followed by a regular expression of all path to be extracted

  • a @template can contains also @file definitions and a @file can contains everything (also other files and @template definitions)

  • if the last item of output of ftp @put, @get, @dir, @del or @foreach ftp://…; (field @9@) ends with / then is a directory else is a file

  • to obtain a log file with the trace of an ftp session define the stderr predefined variable with the path of log file

Examples

  global (outside of templates) definitions...
  @define myglobalname this is the value of myglobalname
  @define myotherglobalname(x,y)
  this is the value of myotherglobalname(@x@,@y@)
  @end
  substring of myglobalname starting from 2nd character is
  @myglobalname[2]@
  substring of myglobalname starting from 2nd character
  with length 8
  @myglobalname[2,8]@
  The actual file and line are @__FILE__@ and @__LINE__@
  @@ this is a comment...
  defining first template...
  @template my-template-1
  this is the first line of template my-template-1
  @@ this is another comment...
  defining mylocalname with a single line value...
  @define mylocalname this is a single line value
  the value of mylocalname is @mylocalname@
  redefining mylocalname with a multiple line value...
  @define mylocalname
  this is
  a multiple line
  value
  @end
  the value of mylocalname is @mylocalname@
  @define mylist
  111 222 field11 field12 field13
  333 444 field21 field22 field23
  555 666 field31 field32 field33
  @end
  @foreach mylist
  the record @NR@ is @0@ and its first three fields are
    @1@, @2@ and @3@
  @end
  the number of records of mylist is @NR@
  defining printf commands...
  @define size-of-second-field 18
  @printf 1 %.10d
  @printf 2 %@size-of-second-field@.3f
  @printf 3 %-10s
  @printf NR %.15d
  defining "," as field separator...
  @define FS ,
  @@ myotherlist fields are separated by "," character
  @@ (FS = field separator)
  @define myotherlist
  field11,field12,field13
  field21,field22,field23
  field31,field32,field33
  @end
  @@ remove the previous printf...
  @printf 1
  @printf 2
  @printf 3
  @printf NR
  @foreach myotherlist(x,y)
  the record @NR@ is @0@ and its fields are
    @1@, @2@ and @3@
  the first field is @x@ and the second is @y@
  @end
  the number of records of mylist is @NR@
  @define mybody
    first field: @1@
    second field: @2@
  @end
  @define myschema
  this is the header
  of myschema
  @mybody<mylist>@
  this is the footer of myschema
  @end
  defining x with value y
  @define x y
  defining y with value z
  @define y z
  @undef @x@
  now y is undefined
  value of y is @y@
  @undef FS
  @@ spaces or tabs are the (default) field separator...
  the value of myschema is
  @myschema@
  this is the last line of template my-template-1
  @end my-template-1
  done
  defining second template...
  @define mytemplate2(myarg1,myarg2)
  this is the first line of template mytemplate2(@myarg1@,@myarg2@)
  @define myshellcommand echo "Hello World"
  the output of a shell command is @$(echo "Hello World")@
  the output of the same shell command is @$(@myshellcommand@)@
  the exit status of a shell command is @?(echo "Hello World")@
  the exit status of a shell command is @?(@myshellcommand@)@
  the upper case version of string "this Is a String" is
  @>(this Is a String)@
  the lower case version of string "this Is a String" is
  @<(this Is a String)@
  the word separated version of capitalized string
  thisIsAString is @-(thisIsAString)@
  change the default word separator with underscore...
  @define WS _
  the word separated version of capitalized string
  thisIsAString is @-(thisIsAString)@
  return to default word separator ("-")...
  @undef WS
  the capitalized version of the word separated string
  this-is-a-string is @.(this-is-a-string)@
  this is the last line of template mytemplate2
  @end mytemplate2
  done
  the value of myglobalname is @myglobalname@
  the value of myotherglobalname is @myotherglobalname(2,3)@
  evaluating template my-template-1...
  @eval my-template-1
  done
  evaluating template mytemplate2...
  @eval mytemplate2(arg1value,arg2value)
  @undef
  now all template and macro definitions are removed
  the value of myglobalname is @myglobalname@
  @env PATH
  now the PATH environment variable is defined
  the value of environment variable PATH is @PATH@
  forward (appending) standard output on file myoutput.txt...
  @define stdout myoutput.txt
  @env
  now all the environment variables are defined
  the value of environment variable HOME is @HOME@
  return to default standard output...
  @undef stdout
  executing the command ls -l...
  @system ls -l
  forwarding (appending) stardard output on buffer mybuffer...
  @define mybuffer
  @end
  @define stdout mybuffer
  creating dir1 and dir2 directories...
  @system
  if [ ! -d dir1 ]
  then
    mkdir dir1
  fi
  if [ ! -d dir2 ]
  then
    mkdir dir2
  fi
  @end
  done
  return to default standard output...
  @undef stdout
  the value of mybuffer is
  @mybuffer@
  @ifndef myid2
  the variable myid2 is not defined
  @end
  @define myid2 valueofmyid2
  @ifdef myid [a-z]+[a-z0-9]*
  there is pattern matching
  @else
  there is not pattern matching
  @end
  @ifndef myid2
  @exit -1 The variable myid2 is not defined
  @end
  this is the last line read from input
  generation of all combinations of length 4 with 5 objects...
  @sequence 5,4
  the combinations are:
  1 2 3 4
  1 2 3 5
  1 2 4 5
  1 3 4 5
  2 3 4 5
  generation of all dispositions of length 2 with 3 objects...
  @define FS ,
  @sequence 3^2
  the dispositions are:
  1,1
  1,2
  1,3
  2,1
  2,2
  2,3
  3,1
  3,2
  3,3
  @undef FS
  generation of 8 random combinations of length 4 with 5 objects...
  @random 5,4 8
  generation of a random dispositions of length 2 with 3 objects...
  @random 3^2
  generation of a random integer number between 1 and 9...
  @random 9
  @@exit
  if previous line was "@exit" this line is not read...
  archive automatically on stdout more (text) files into one file...
  @archive @HOME@/src *.c
  archive manually more (text) files into one file...
  first file...
  @define myfilename a/b/f1.txt
  @file @myfilename@
  this is the first file content...
  @define A
  11 22 33
  44 55 66
  @end
  A value is @A@
  @end @myfilename@
  done
  second file...
  @define mysecondfile f2.txt
  @file f2.txt
  this is the content...
  ... of the second file
  @end f2.txt
  last file...
  @file c2.txt
  last file content...
  @end c2.txt
  extracting first file...
  @extract a/b/f1.txt
  extracting second file...
  @extract @mysecondfile@
  extracting all files matching .*2.txt...
  @extract .*2.txt
  extracting all files...
  @extract
  extracting on stdout first file...
  @extract stdout a/b/f1.txt
  extracting on stdout all files...
  @extract stdout
  @@ get xml local directory tree...
  @dir /my/local/dir
  ...
  @@ get remote info of my/remote/file of myremotehost (as "ls -l")
  @@ using ftp with myusername and mypassword...
  @dir ftp://myusername:mypassword@myremotehost/my/remote/file
  ...
  @@ get remote directory tree of all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @dir ftp://myusername:mypassword@myremotehost/my/remote/dir
  ...
  @@ get remote directory tree of all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @dir ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  ...
  @@ get remote directory tree of all files *.txt under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername, mypassword and server port 1234...
  @dir ftp://myusername:mypassword@myremotehost:1234/my/remote/dir *.txt
  ...
  @@ get remote directory tree of all files *.txt under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @dir ftp://myusername:mypassword@myremotehost/my/remote/dir/. *.txt
  ...
  @@ get to current local directory all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir
  ...
  @@ get to current local directory all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  ...
  @@ get to current local directory file my/remote/file of myremotehost
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/file
  ...
  @@ get to local directory /my/local/dir all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir
  ...
  @@ get to local directory /my/local/dir all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir/. /my/local/dir
  ...
  @@ get to local directory /my/local/dir all files *.txt under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
  ...
  @@ get to local directory /my/local/dir all files *.txt under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @get ftp://myusername:mypassword@myremotehost/my/remote/dir/. /my/local/dir *.txt
  ...
  @@ put all local files under current local directory under my/remote/dir of myremotehost
  @@ with recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @put ftp://myusername:mypassword@myremotehost/my/remote/dir
  ...
  @@ put all local files under current local directory under my/remote/dir of myremotehost
  @@ without recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @put ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  ...
  @@ put all local files *.txt under current local directory to my/remote/dir of myremotehost
  @@ without recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @put ftp://myusername:mypassword@myremotehost/my/remote/dir . *.txt
  ...
  @@ put all local files *.txt under local directory /my/local/dir to my/remote/dir of myremotehost
  @@ with recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @put ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
  ...
  @@ del remote file my/remote/file of myremotehost
  @@ using ftp with myusername and mypassword...
  @del ftp://myusername:mypassword@myremotehost/my/remote/file
  ...
  @@ del remote directory my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @del ftp://myusername:mypassword@myremotehost/my/remote/dir
  ...
  @@ del remote directory my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @del ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  ...
  @@ del all files *.txt under remote directory my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @del ftp://myusername:mypassword@myremotehost/my/remote/dir *.txt
  ...
  @@ del all files *.txt under remote directory my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @del ftp://myusername:mypassword@myremotehost/my/remote/dir/. *.txt
  ...
  @@ get remote info of my/remote/file of myremotehost
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/file
  the info of file @9@ (@NF@) are <@0@> (as "ls -l")
  @end
  @@ the number of files is @NR@
  ...
  @@ get remote directory tree of all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get remote directory tree of all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get remote directory tree of all files *.txt under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername, mypassword and server port 1234...
  @foreach ftp://myusername:mypassword@myremotehost:1234/my/remote/dir *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get remote directory tree of all files *.txt under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/. *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to current local directory all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to current local directory all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to current local directory file my/remote/file of myremotehost
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/file
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to local directory /my/local/dir all files under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to local directory /my/local/dir all files under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/. /my/local/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to local directory /my/local/dir all files *.txt under my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ get to local directory /my/local/dir all files *.txt under my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/. /my/local/dir *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ put all local files under current local directory under my/remote/dir of myremotehost
  @@ with recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ put all local files under current local directory under my/remote/dir of myremotehost
  @@ without recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ put all local files *.txt under current local directory to my/remote/dir of myremotehost
  @@ without recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir . *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ put all local files *.txt under local directory /my/local/dir to my/remote/dir of myremotehost
  @@ with recursion on local subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir /my/local/dir *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ del remote file my/remote/file of myremotehost
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/file
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ del remote directory my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ del remote directory my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/.
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ del all files *.txt under remote directory my/remote/dir of myremotehost
  @@ with recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ del all files *.txt under remote directory my/remote/dir of myremotehost
  @@ without recursion on subdirectories
  @@ using ftp with myusername and mypassword...
  @foreach ftp://myusername:mypassword@myremotehost/my/remote/dir/. *.txt
  the info of file @9@ (@NF@) with size @5@ are <@0@>
  @end
  ...
  @@ to export on a log file an ftp session before the ftp commnad
  @@ define the stderr predefined variable with the path of log file...