Provided by: dish_1.19.1-1.1_all bug

NAME

       dish - tool for parallel sysadmin of multiple hosts

SYNOPSIS

       dish [option]... -e command {-g hosts_file | host_1 host_2 ...}
       dicp {-g hosts_file | -g "user@host_1 ..."} local_file :remote_file
       dicp {-g hosts_file | -g "user@host_1 ..."} :remote_file local_file

DESCRIPTION

       dish - the diligence shell executes commands on several hosts via ssh/rsh/telnet, and also makes easy the
       distribution of files by scp/rcp, a remote password change, etc. It can process hosts in parallel mode.

OPTIONS

       -h     Print help message describing shortly all command-line options

       -H, --help
              Comprehensive help including examples

       --version
              Print program version and copyright message, then exit

       -V     Display the version number and exit

       -C <dir>
              Configuration  directory  -  $HOME/.dish  is  default;  In  this  directory  are located following
              configuration files: 'hosts', 'rests', 'pass', and 'options'. When used, this option must  be  the
              first argument in the command line string, or be the second one if `-D' chosen! Alternatively, one
              can specify the configuration directory by defining the environment variable DISH_CONF.

       -CC <dir>
              Same  as  `-C'  with  fallback  to default if local config not found; This means that, in case the
              files 'pass', 'options' or 'rests' are absent in the given directory,  but  such  files  exist  in
              $HOME/.dish,  the  latter will be considered. The only exception is '$HOME/.dish/hosts' which will
              be ignored. Using this option is equivalent to changing  directory  to  the  opted  one  and  then
              executing `dish'.

       -c <name>
              Program  (alias  "connector")  and  its  options  used  for connecting to the remote host(s) - for
              example `rsh', whereas the spawned process will be "rsh $host <cmd>". Your  default  connector  is
              `ssh'.  Furthermore,  by  using  a relevant text-based client as connector, one can access various
              kinds of hosts - switches, databases, and so on.

       -e <cmd>
              Remote command to execute; It can be also set by the environment variable DISH_CMD.

       -E <cmd>
              Execute command where also the connection part is specified e.g. "-E 'ssh $host  date'"  which  is
              equal  to  "-e  date".   This option is incompatible with `-c' and `-e'. It can be also set by the
              environment variable DISH_FUEXE.

       -t     Force pseudo-tty allocation in ssh; This happens automatically in case of password change.

       -T <time>
              Timeout for command execution - default 30s (per host)

       -TT <time>
              Total timeout for command execution - default 300s (all hosts); This option is  useful  only  when
              hosts  are  processed  in  sequence  and the total processing time should not exceed the specified
              upper bound.

       -x <regex>
              Regular expression for the shell prompt; This value specifies which prompt is to  be  expected  in
              the program's shell after login into a system by `telnet', `mysql', `sqlplus' or other interactive
              command-line clients (see `-c').  The default value is `(%|\$|#|\>) ?$'.

       -X <regex>
              Regular  expression  for the password prompt; It is case-insensitive with default value `Password:
              *$'.

       -AD <regex>
              Regular expression for the ssh-prompt to add a new host key - `connecting (yes/no)?.*' is default

       -AC <str>
              String with the answer to the ssh-prompt to add a new host key - `yes' is default

       -g <file>
              File with list of hosts/ip's/accounts to target; The command will be executed  on  these  targets.
              The  default  host  file  is  '$HOME/.dish/hosts'  -  normally  per  line  one account of the form
              "user@host" (if ssh is your choice  for  connector).  In  order  to  join  lists  use  the  option
              repeatedly.  Alternatively, the environment variable DISH_HOSTS could be used to define the target
              hosts  whereas  in  the  specified  string  they have to be separated by blanks. By combining this
              option with `-r' or `-i' you can define various subsets of targeted hosts/accounts.

       -r <file>
              File with list of resting hosts/accounts to exclude; The default  one  is  '$HOME/.dish/rests'.  A
              "resting host" means one which will be excluded from the targets. The list of resting hosts or the
              file name could be specified also by the environment variable DISH_RESTS.

       -i <file>
              File  with  list  of hosts/accounts to overlap with targeted hosts; There is no default file. Only
              overlapping hosts, such included in this list and at the same time defined  as  targets,  will  be
              processed.

       -u <name>
              User  name  -  default is your local user name; It can be defined also by the environment variable
              DISH_USER.  Internally the value is accessible by the variable $user (see examples).  Further,  it
              is  irrelevant  in  case  that  accounts  of the form "user@host" are processed since they include
              already the user name.

       -p <passwd>
              Login password (-p "" = -pp = -a0) - alias "login authentic" or "a0";  If  no  authentication  for
              login  is  required (no user- and no password-prompt appear), then use `/dev/null' as password. If
              the user name is requested, yet the password is an empty string, then `/dev/empty' has to be given
              as password. The value of this option could be also a password file (see  `-P').  Eventually,  one
              can define the password by the environment variable DISH_PASS.

       -a <passwd>
              Additional  password  for  authentication  (-a  "" = -aa = -a1) - alias "first authentic" or "a1";
              Inside the spawn process, if a program like `smbmount', `su', `ssh', etc. asks for authentication,
              the a1-password is passed to it. This password  can  be  also  set  by  the  environment  variable
              DISH_PASS1.

       -A <passwd>
              One  more password for authentication (-A "" = -AA = -a2) - alias "second authentic" or "a2"; When
              a spawned process, after one authentication by the a1-password, asks again for a password, then a2
              is sent. This password can be also set by the environment variable DISH_PASS2.

       -n <passwd>
              New password in case of password change (-n "" = -nn = -ne)

       -p0    Login without authentication - the same as `-p /dev/null'

       -p1    Set the a1-password to be the same as the login password; This option should not be used  together
              with `-p0' and `-a1'.  See example d) bellow.

       -P <file>
              File  with password(s); The default password file is '$HOME/.dish/pass'.  It must be readable only
              for the user (file mode 600 or 700), otherwise the program exits with error,  but  see  also  next
              option.    Every    line    in   the   file   can   hold   a   password   entry   of   the   form:
              "password:username:hostname",       alternatively       "password:::username:::hostname",       or
              "password;;;username;;;hostname".   One  can  specify  a list of hosts separated by the `,' or `;'
              characters. Regular expressions for hostnames are also  allowed  (see  the  example  configuration
              files in the distribution).

       -m     Ignore the access permissions of the password file

       -s [<time>]
              Sequential  processing  of hosts (default mode); If a time interval (measured in floating seconds)
              is specified, then the program is waiting this amount of time before starting to process the  next
              host in the sequence.

       -F     Spawn  processes in background - fork and disconnect; This way all hosts are processed essentially
              in parallel!  It's a very powerful option - depending on you RAM size and memory  utilization,  it
              shouldn't be a problem to process a few hundreds of hosts in parallel. Anyway, be careful - if you
              have  too  many  hosts  on  the  list,  your could put your system under load. The stdout's of the
              background processes are redirected to '/dev/null', however you can use `-l' or `-L' to write  the
              output to files. See also 'bugs and known problems' in the manual page.

       -f     Spawn  processes  in  background without disconnecting from tty; It's the same as `-F' whereas the
              stdout's of the spawned processes are sent to the terminal. Also the parent process waits for  his
              children to finish. See also 'bugs and known problems' in the manual page.

       -q     Be  quiet  -  skip  output  from  spawn  and login; When working with the secure shell, it is also
              convenient to use `ssh' with the `-q' option.

       -Q     Be QUIET - skip any output

       -v     Be verbose (default) - overrides `-q' and `-Q'

       -l <file>
              Log command output to file; The output of the spawned processes is appended to the file.

       -L <name>
              Write a separate log for every host where <name> denotes the base name of the log file.  The  full
              name of a log file is defined as "<name>_<user@host>.log".

       -j     Record  the  invoked command into a journal file with the name '$HOME/.dish/journal'; It keeps the
              history of the executed commands and their time of execution. An unique identifier  is  associated
              with every command.

       -J     Record  the  invoked  command  and  the spawned processes as well; Write into the journal file the
              executed command as well as the single processes spawned and their time of execution.

       -o <file>
              File with command line options passed to the  program  -  default  is  '$HOME/.dish/options';  The
              options  must  be  written  in  the  file separated - one per line. By means of this file, one can
              modify the standard configuration: set up fork mode to be default, change the  default  connector,
              and   so   forth.  When  working  in  "copy  mode",  i.e.  by  invoking  the  program  as  'dicp',
              '$HOME/.dish/options.dicp' is considered to be the default options file.

       -d     enable expect's diagnostic output (look at `man expect')

       -D     Debug mode (dry-run); Print out environment variables, config file names, and commands to execute,
              then exit. This option should be used as first in the command line.

EXAMPLES

       You should consider that the variables $host and $user are evaluated. Thus $host changes dynamically  its
       value to the actual host/account name before a new process is spawned. The same is true for $user.

       a) Check the date and uptime on hosts 192.168.0.1 and 192.168.0.2

              dish -e 'date \; uptime' root@192.168.0.1 root@192.168.0.2

       b) Distribute '.profile' and '.bashrc' to guest accounts on 'host1' and 'host2'

              dish -E "scp $HOME/.profile $HOME/.bashrc guest@\$host:" host1 host2

              or

              dicp -e "$HOME/.profile $HOME/.bashrc guest@:" host1 host2

              or

              dicp -g "host1 host2" $HOME/.profile $HOME/.bashrc guest@:

              or

              dicp -g "guest@host1 guest@host2" $HOME/.profile $HOME/.bashrc :

       c) Copy remote '.profile' files into the local directory on localhost

              dicp -g "guest@host1 guest@host2 admin@host2" :.profile .profile.\$host

              Here,  the name of the target file (local file) will include the remote account name in order that
              the local files have unique names.

       d) Use `ssh' to login on 'host1' and copy from there '.profile' to 'host2'

              Since the list of hosts can not be empty, a dummy host is used to initiate the process.  The  `-t'
              option  is necessary to force pseudo-tty allocation in `ssh', otherwise `ssh' will fail with error
              on login. A second password (a1-password) is required for scp-authentication on 'host2':

              dish -a '' -E 'ssh -t user1@host1 scp .profile user2@host2:' dummy_host

              In case the password of 'user1' and 'user2' is the same, you will be asked only once for  a  login
              password for user1@host1 if you use `-p1':

              dish -p1 -E 'ssh -t user1@host1 scp .profile user2@host2:' dummy_host

              Or equivalently, and more simple:

              dish -p1 -t -e 'scp .profile user2@host2:' user1@host1

       e) Substitute lines with `START_XNTPD=' by `START_XNTPD="yes"' in /etc/rc.config

              This command is executed as root user on every host listed in 'Hosts.root':

              dish  -u  root -E 'ssh $user@$host "perl -pi -e \"s/^START_XNTPD=.*\$/START_XNTPD=\\\"yes\\\"/g;\"
              /etc/rc.config"' -g Hosts.root

       f) Freeze accounts of users on a termination list

              By using a script called `FreezeUser.sh', all accounts of users found on 'Terminate.User.lst' will
              be frozen today at 24:00 o'clock  on  both  server  groups  as  defined  in  files  'Hosts.1'  and
              'Hosts.2':

              dish  -E  'ssh  root@$host  "cat  Terminate.User.lst  |  while  read  UN;  do echo \"su - admin -c
              \\\$HOME/bin/FreezeUser.sh \$UN\" | at 24:00 ; done"' -g Hosts.1 -g Hosts.2

       g) Print out remote configuration file of an automounter

              Login as 'admin' user on host 192.168.0.1, switch to 'root', then cat the file '/etc/auto.net' and
              print out the date. The `-a' option causes the program to ask you for the root-password on  remote
              host:

              dish -u admin -a '' -E 'rsh -l $user $host su - root -c \"cat /etc/auto.net\; date\"' 192.168.0.1

       h) Install a package on Debian GNU/Linux hosts

              After  mounting  a  fileserver over samba, install from there a debian dish-package on all running
              servers, yet skip hosts on maintenance.  Three different passwords are needed for authentication -
              one for login, next for su-root, and the last for mounting the fileserver:

              dish  -a0  -a1  -a2  -g   Debian.up   -r   Debian.maint   -e   'su   -   -c   \"mount   -t   smbfs
              //FILESERVER/Packages.Dir /mnt/smb ; dpkg -i /mnt/smb/dish_1.19.1_all.deb\"'

       i) Check for system load >2 using default 'hosts' and 'pass' config files

              dish '(uptime |egrep \" (\[2-9\]|1\[0-9\])\\.\" && hostname) |paste - -'

       j) Query a MySQL database on remote host 10.0.0.1

              dish -pp -c 'mysql -p -u $user -h' -e 'use mysql; show tables; describe user;' -u root 10.0.0.1

       k) Change password concurrently on all hosts/accounts

              We  assume that the list of user accounts is contained in file 'Accounts.lst', whereas an entry in
              the list is of the form "user@hostname". After command execution, you will be asked first for  the
              login  password  (old  password),  and  then for the new password which eventually have to retyped
              correctly:

              dish -p '' -n '' -e passwd -g Accounts.lst

              Or alternatively, processing concurrently and quietly all hosts:

              dish -pp -nn -f -Q -e passwd -g Accounts.lst

              When you want to change password and use `-nn', then the a1-password is implicitly  set  equal  to
              the login password (a0-password).

       l) Change password from 'root' account (don't use the `-a0' option)

              If you are going to change the root-password on 'remotehost', then try:

              dish -nn -e passwd root@remotehost

              The  same  as  previous,  but  login  as  user  'admin'  (login  password),  then switch to 'root'
              (a1-password), and finally update the root-password:

              dish -a1 -nn -e 'su -c passwd' admin@remotehost

              Changing the password for 'admin' on 'localhost', after login as 'root' via `telnet', is done by:

              dish -nn -c telnet -u root -e 'passwd admin' localhost

       Notice that for password change, when `-p ""' (or equivalently `-a0' or `-pp') is  not  explicitly  used,
       the  assumption  is made that `passwd' will not ask for the old password, as in case of a password change
       by 'root'. The same is true also if you can login into an account without typing  a  password,  but  then
       `passwd'  prompts  you  to type the old one - this situation occurs when one is using a ssh-key for login
       without password-authentication. For such scenario the correct choice of options is `-p0 -aa -nn'.

       In case of properly prepared configuration files in '$HOME/.dish', one can  use  dish  as  a  distributed
       shell  for  a  virtual  cluster of hosts, and run it without specifying any program parameters but merely
       issuing a command, as for instance `dish df -k /' or `dicp .profile :'.

       As a very last note, one should be aware that in case of authentication  by  password,  dish's  automated
       login  process  is  based  on the expectation that the login prompt send to the terminal will include the
       case-insensitive regex-string `Password: *$' (but see also `-X'). Otherwise the authentication  procedure
       will fail.

BUGS AND KNOWN PROBLEMS

       If Tcl is compiled with thread support, the program hangs when executed in parallel mode (options `-f' or
       `-F')  -  it  seems  to be a Tcl problem.  Generally, at present Debian GNU/Linux (and other debian-based
       Linux distros as Ubuntu, Knoppix, etc.) pre-package Tcl with multi-thread support enabled.  Therefore, on
       such systems dish fails to process hosts in parallel. In this case you can  download  the  debian  source
       package  of  Tcl,  remove  the  option  "--enable-threads"  in  ´debian/rules´,  rebuild the package with
       `dpkg-buildpackage -rfakeroot', and eventually install it. It could be a good idea  to  put  the  freshly
       installed package on hold. Otherwise, you should recompile it on every tcl upgrade.

REPORTING BUGS

       Report bugs to <gnu@mirendom.net>

COPYRIGHT

       Copyright © 2003-2013 Dimitar Ivanov

       License: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
       This  is  free software: you are free to change and redistribute it.  There is NO WARRANTY, to the extent
       permitted by law.

SEE ALSO

       expect(1), tcl(3), ssh(1), rsh(1), telnet(1)

dish 1.19.1                                      September 2013                                          DISH(1)