Man Linux: Main Page and Category List


       dish - tool for parallel sysadmin of multiple hosts


       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


       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.


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

       -H, --help
              Comprehensive help including examples

              Print program version and copyright message, then exit

       -V     Display the version number and exit

       -C <dir>
              Configuration  directory  (default  is  $HOME/.dish)  where  the
              config  files  -  ’hosts’,  ’rests’, ’pass’, and ’options’ - are
              located. When used, this option must be the  first  argument  in
              the   command  line  string,  or  the  second  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;
              that is, in case the files  ’pass’,  ’options’  or  ’rests’  are
              absent  in  the  given  directory,  however  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 connect;
              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>
              Command to execute

       -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’.

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

       -T <time>
              Time out for command execution - default are 30 sec.

       -x <regex>
              Regular expression for the shell  prompt;  After  login  into  a
              system   by   telnet,   mysql,  sqlplus,  or  other  interactive
              command-line clients, this value specifies which prompt is to be
              expected  in  the  program’s  shell.  It  is  relevant only when
              ssh/rsh, or scp/rcp are not used as connectors (see  ‘-c’).  The
              default value is ‘(%|\$|#|\>) ?$’.

       -X <regex>
              Regular    expression   for   the   password   prompt;   It   is
              case-insensitive with default value ‘Password:’.

       -g <file>
              File with list of hosts/ip’s/accounts  to  target;  the  command
              will   be   executed   on   those.  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 defined to specify the
              target hosts separated by blanks. By using  this  option  within
              combination  of  ‘-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

       -u <name>
              User  name  - default is your local user name; it can be defined
              also by the external 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  setting an environment variable:
              export DISH_PASS=<password>

       -p0    Login without authentication: the same as ‘-p /dev/null’

       -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 status,
              but  see  also  next  option.  Every line in the file can hold a
              password  of  the  form  "password[:username[:host]]".  One  can
              specify  a list of hosts separated by the ‘,’ or ‘;’ characters.
              Regular expressions for host names are  also  allowed  (see  the
              example configuration files in the distribution).

       -m     Ignore the access permissions of the password file

       -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. In case that ‘-a’ and ‘-n’  are
              not  involved options, and the login password a0 is not an empty
              one, then the a1-password is equal to it (see example c) below).

       -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.

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

       -s [<time>]
              Sequential processing of hosts (default mode) If a time interval
              in  seconds  is  specified  then  processing of next host, after
              current host is finished, is delayed by this amount of time.

       -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  man

       -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 man 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’

       -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; the
              options must be one per line, whereas the default option file is
              ’$HOME/.dish/options’.  By means of this file one can modify the
              standard configuration - set up fork mode as 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  as  default  options

       -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.


       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 and

              dish -e ’date \; uptime’ root@ root@

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

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


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


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


              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

              Here, the name of the target file include the  account  name  in
              order that the emerging local files have unique names.

       d)  Use  ssh  to  login  on  ’host1’  and copy from there ’.profile’ to

              Since the list of hosts can not be empty, a dummy host  is  used
              to initiate the process. The ‘-t’ option for ssh 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:’

              In  case  the  password  of ’user1’ and ’user2’ is the same, you
              will be asked only once for a login password for user1@host1:

              dish  -E  ’ssh  -t  user1@host1   scp   .profile   user2@host2:’

              Or equivalently, and more simple:

              dish -e ’scp .profile user2@host2:’ user1@host1

       e)  Substitute  lines  with  ‘START_XNTPD=’  by  ‘START_XNTPD="yes"’ in

              This command is executed as root user on every  host  listed  in

              dish    -u    root    -E   ’ssh   $user@$host   "perl   -pi   -e
              /etc/rc.config"’ -g Hosts.root

       f) Freeze accounts of users on a termination list

              By  using a script called ‘’, 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

              dish -E ’ssh root@$host "cat Terminate.User.lst | while read UN;
              do  echo  \"su - admin -c \\\$HOME/bin/ \$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, switch  to  root,  then
              cat  the  file  ’/etc/’ 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/\; date\"’

       h) Install a package on Debian GNU/Linux hosts

              After mounting a fileserver over samba,  install  from  there  a
              debian  dish-package  on  all  Debian  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

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

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

       j) Query a MySQL database on remote host

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

       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 one
              time for a login password, and  one  more  for  the  a1-password
              (which,  in  this case, must be the same as the login password).
              Then you have to type the new password, and  finally  retype  it

              dish -p ’’ -a ’’ -n ’’ -e passwd -g Accounts.lst

              Or,   alternatively,   without   retyping  the  login  password,
              processing concurrently and quietly all hosts:

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

       l) Change root password (don’t use the ‘-a0’ option)

              If you are going to change the root password on remotehost, then

              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

              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

       Note 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.  This example is valid also if you can login into account without
       typing a password, but then ‘passwd’ prompts you to  type  the  current
       one   -   such   situation  occurs  when  using  a  ssh-key  for  login
       authentication. Alternatively, the options ‘-p0 -aa  -nn’  would  yield
       the same result.

       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 dish’s  automated  login
       process  is  based  on the premise that in case a program is asking for
       password,  the  prompt  send  to  the   terminal   will   include   the
       case-insensitive   string  ‘Password:’.  Otherwise  the  authentication
       procedure will fail. You can change this, in fact  regular  expression,
       by using the option ‘-X’.


       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


       Report bugs to <>


       Copyright © 2003-2009 Dimitar Ivanov

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


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