(command.CommandList
  children: [
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:tid)
          op: assign_op.Equal
          rhs: {(DQ <'hostkey rotate'>)}
          spids: [7]
        )
      ]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:HOSTKEY_TYPES)
          op: assign_op.Equal
          rhs: {(DQ <'ecdsa-sha2-nistp256 ssh-ed25519 ssh-rsa ssh-dss'>)}
          spids: [16]
        )
      ]
    )
    (C {<rm>} {<-f>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.'> <Id.Lit_Star '*'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/ssh_proxy.orig'>}
    )
    (command.Simple
      words: [{<grep>} {<-vi>} {(SQ <hostkey>)} {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy'>}]
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy.orig'>}
        )
      ]
      do_fork: T
    )
    (command.Simple
      words: [{<echo>} {(DQ <'UpdateHostkeys=yes'>)}]
      redirects: [
        (redir
          op: <Id.Redir_DGreat '>>'>
          loc: (redir_loc.Fd fd:1)
          arg: {($ Id.VSub_DollarName '$OBJ') <'/ssh_proxy'>}
        )
      ]
      do_fork: T
    )
    (C {<rm>} {($ Id.VSub_DollarName '$OBJ') <'/known_hosts'>})
    (C {<trace>} {(DQ <'prepare hostkeys'>)})
    (command.ShAssignment
      pairs: [(assign_pair lhs:(sh_lhs_expr.Name name:nkeys) op:assign_op.Equal rhs:{<0>} spids:[73])]
    )
    (command.ShAssignment
      pairs: [
        (assign_pair
          lhs: (sh_lhs_expr.Name name:all_algs)
          op: assign_op.Equal
          rhs: {(DQ )}
          spids: [76]
        )
      ]
    )
    (command.ForEach
      iter_name: k
      iter_words: [
        {
          (command_sub
            left_token: <Id.Left_Backtick '`'>
            child: (C {(${ Id.VSub_Name SSH)} {<-Q>} {<key-plain>})
          )
        }
      ]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {(${ Id.VSub_Name SSHKEYGEN)} {<-qt>} {($ Id.VSub_DollarName '$k')} {<-f>} 
                  {($ Id.VSub_DollarName '$OBJ') <'/hkr.'> ($ Id.VSub_DollarName '$k')} {<-N>} {(SQ )}
                )
                (C {<fatal>} {(DQ <'ssh-keygen '> ($ Id.VSub_DollarName '$k'))})
              ]
            )
            (command.Simple
              words: [
                {<echo>}
                {(DQ <'Hostkey '> ($ Id.VSub_DollarName '$OBJ') <'/hkr.'> (${ Id.VSub_Name k))}
              ]
              redirects: [
                (redir
                  op: <Id.Redir_DGreat '>>'>
                  loc: (redir_loc.Fd fd:1)
                  arg: {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy.orig'>}
                )
              ]
              do_fork: T
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:nkeys)
                  op: assign_op.Equal
                  rhs: 
                    {
                      (command_sub
                        left_token: <Id.Left_Backtick '`'>
                        child: 
                          (C {<expr>} {($ Id.VSub_DollarName '$nkeys')} {<Id.Lit_Other '+'>} {<1>})
                      )
                    }
                  spids: [149]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {<test>} {(DQ <x> ($ Id.VSub_DollarName '$all_algs'))} {<Id.Lit_Equals '='>} {(DQ <x>)})
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:all_algs)
                      op: assign_op.Equal
                      rhs: {(DQ (${ Id.VSub_Name all_algs) <','>)}
                      spids: [178]
                    )
                  ]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:all_algs)
                  op: assign_op.Equal
                  rhs: {(DQ (${ Id.VSub_Name all_algs) ($ Id.VSub_DollarName '$k'))}
                  spids: [187]
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: dossh
      body: 
        (BraceGroup
          children: [
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {(${ Id.VSub_Name SSH)} {<-F>} {($ Id.VSub_DollarName '$OBJ') <'/ssh_proxy'>} 
                  {(DQ ($ Id.VSub_At '$@'))} {<x>} {<true>}
                )
                (C {<fail>} {(DQ <'ssh '> ($ Id.VSub_At '$@') <' failed'>)})
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: expect_nkeys
      body: 
        (BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:_expected)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [246]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:_message)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$2')}
                  spids: [250]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:_n)
                      op: assign_op.Equal
                      rhs: 
                        {
                          (command_sub
                            left_token: <Id.Left_Backtick '`'>
                            child: 
                              (command.Pipeline
                                children: [
                                  (C {<wc>} {<-l>} {($ Id.VSub_DollarName '$OBJ') <'/known_hosts'>})
                                  (C {<awk>} {(SQ <'{ print $1 }'>)})
                                ]
                                negated: F
                              )
                          )
                        }
                      spids: [254]
                    )
                  ]
                )
                (C {<fatal>} {(DQ <'wc failed'>)})
              ]
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {<Id.Lit_LBracket '['>} {(DQ <x> ($ Id.VSub_DollarName '$_n'))} {<Id.Lit_Equals '='>} 
                  {(DQ <x> ($ Id.VSub_DollarName '$_expected'))} {<Id.Lit_RBracket ']'>}
                )
                (C {<fail>} 
                  {
                    (DQ ($ Id.VSub_DollarName '$_message') <' (got '> ($ Id.VSub_DollarName '$_n') 
                      <' wanted '> ($ Id.VSub_DollarName '$_expected') <')'>
                    )
                  }
                )
              ]
            )
          ]
        )
    )
    (command.ShFunction
      name: check_key_present
      body: 
        (BraceGroup
          children: [
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:_type)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$1')}
                  spids: [322]
                )
              ]
            )
            (command.ShAssignment
              pairs: [
                (assign_pair
                  lhs: (sh_lhs_expr.Name name:_kfile)
                  op: assign_op.Equal
                  rhs: {($ Id.VSub_Number '$2')}
                  spids: [326]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DAmp]
              children: [
                (C {<test>} {(DQ <x> ($ Id.VSub_DollarName '$_kfile'))} {<Id.Lit_Equals '='>} {(DQ <x>)})
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:_kfile)
                      op: assign_op.Equal
                      rhs: 
                        {(DQ ($ Id.VSub_DollarName '$OBJ') <'/hkr.'> (${ Id.VSub_Name _type) <.pub>)}
                      spids: [345]
                    )
                  ]
                )
              ]
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (command.ShAssignment
                  pairs: [
                    (assign_pair
                      lhs: (sh_lhs_expr.Name name:_kpub)
                      op: assign_op.Equal
                      rhs: 
                        {
                          (command_sub
                            left_token: <Id.Left_Backtick '`'>
                            child: 
                              (command.Simple
                                words: [
                                  {<awk>}
                                  {(DQ <'/'> ($ Id.VSub_DollarName '$_type') <' /'>) 
                                    (SQ <' { print $2 }'>)
                                  }
                                ]
                                redirects: [
                                  (redir
                                    op: <Id.Redir_Less '<'>
                                    loc: (redir_loc.Fd fd:0)
                                    arg: {($ Id.VSub_DollarName '$_kfile')}
                                  )
                                ]
                                do_fork: T
                              )
                          )
                        }
                      spids: [356]
                    )
                  ]
                )
                (C {<fatal>} {(DQ <'awk failed'>)})
              ]
            )
            (command.Simple
              words: [
                {<fgrep>}
                {(DQ ($ Id.VSub_DollarName '$_kpub'))}
                {($ Id.VSub_DollarName '$OBJ') <'/known_hosts'>}
              ]
              redirects: [(redir op:<Id.Redir_Great '>'> loc:(redir_loc.Fd fd:1) arg:{<'/dev/null'>})]
              do_fork: T
            )
          ]
        )
    )
    (C {<cp>} {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy.orig'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy'>}
    )
    (C {<verbose>} {(DQ <'learn hostkey with StrictHostKeyChecking=no'>)})
    (command.Simple
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {($ Id.VSub_DollarName '$OBJ') <'/known_hosts'>}
        )
      ]
      do_fork: F
    )
    (C {<dossh>} {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> <ssh-ed25519>} 
      {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <no>}
    )
    (C {<expect_nkeys>} {<1>} {(DQ <'unstrict connect keys'>)})
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [
        (C {<check_key_present>} {<ssh-ed25519>})
        (C {<fail>} {(DQ <'unstrict didn\'t learn key'>)})
      ]
    )
    (C {<verbose>} {(DQ <'learn additional hostkeys'>)})
    (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
      {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> ($ Id.VSub_DollarName '$all_algs')}
    )
    (C {<expect_nkeys>} {($ Id.VSub_DollarName '$nkeys')} {(DQ <'learn hostkeys'>)})
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [(C {<check_key_present>} {<ssh-rsa>}) (C {<fail>} {(DQ <'didn\'t learn keys'>)})]
    )
    (command.ForEach
      iter_name: k
      iter_words: [
        {
          (command_sub
            left_token: <Id.Left_Backtick '`'>
            child: (C {(${ Id.VSub_Name SSH)} {<-Q>} {<key-plain>})
          )
        }
      ]
      do_arg_iter: F
      body: 
        (command.DoGroup
          children: [
            (C {<verbose>} {(DQ <'learn additional hostkeys, type='> ($ Id.VSub_DollarName '$k'))})
            (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
              {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> ($ Id.VSub_DollarName '$k') <Id.Lit_Comma ','> 
                ($ Id.VSub_DollarName '$all_algs')
              }
            )
            (C {<expect_nkeys>} {($ Id.VSub_DollarName '$nkeys')} 
              {(DQ <'learn hostkeys '> ($ Id.VSub_DollarName '$k'))}
            )
            (command.AndOr
              ops: [Id.Op_DPipe]
              children: [
                (C {<check_key_present>} {($ Id.VSub_DollarName '$k')})
                (C {<fail>} {(DQ <'didn\'t learn '> ($ Id.VSub_DollarName '$k'))})
              ]
            )
          ]
        )
    )
    (C {<verbose>} {(DQ <'learn changed non-primary hostkey'>)})
    (C {<mv>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub.old'>}
    )
    (C {<rm>} {<-f>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa'>})
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [
        (C {(${ Id.VSub_Name SSHKEYGEN)} {<-qt>} {<ssh-rsa>} {<-f>} 
          {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa'>} {<-N>} {(SQ )}
        )
        (C {<fatal>} {(DQ <'ssh-keygen '> ($ Id.VSub_DollarName '$k'))})
      ]
    )
    (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
      {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> ($ Id.VSub_DollarName '$all_algs')}
    )
    (C {<expect_nkeys>} {($ Id.VSub_DollarName '$nkeys')} {(DQ <'learn hostkeys'>)})
    (command.AndOr
      ops: [Id.Op_DAmp]
      children: [
        (C {<check_key_present>} {<ssh-rsa>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub.old'>})
        (C {<fail>} {(DQ <'old key present'>)})
      ]
    )
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [(C {<check_key_present>} {<ssh-rsa>}) (C {<fail>} {(DQ <'didn\'t learn changed key'>)})]
    )
    (C {<verbose>} {(DQ <'learn new primary hostkey'>)})
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [
        (C {(${ Id.VSub_Name SSHKEYGEN)} {<-qt>} {<ssh-rsa>} {<-f>} 
          {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa-new'>} {<-N>} {(SQ )}
        )
        (C {<fatal>} {(DQ <'ssh-keygen '> ($ Id.VSub_DollarName '$k'))})
      ]
    )
    (command.Subshell
      child: 
        (command.CommandList
          children: [
            (command.Sentence
              child: (C {<cat>} {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy.orig'>})
              terminator: <Id.Op_Semi _>
            )
            (C {<echo>} {<HostKey>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa-new'>})
          ]
        )
      redirects: [
        (redir
          op: <Id.Redir_Great '>'>
          loc: (redir_loc.Fd fd:1)
          arg: {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy'>}
        )
      ]
    )
    (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
      {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> <ssh-rsa> <Id.Lit_Comma ','> 
        ($ Id.VSub_DollarName '$all_algs')
      }
    )
    (C {<expect_nkeys>} 
      {
        (command_sub
          left_token: <Id.Left_Backtick '`'>
          child: (C {<expr>} {($ Id.VSub_DollarName '$nkeys')} {<Id.Lit_Other '+'>} {<1>})
        )
      } {(DQ <'learn hostkeys'>)}
    )
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [(C {<check_key_present>} {<ssh-rsa>}) (C {<fail>} {(DQ <'current key missing'>)})]
    )
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [
        (C {<check_key_present>} {<ssh-rsa>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa-new.pub'>})
        (C {<fail>} {(DQ <'new key missing'>)})
      ]
    )
    (C {<verbose>} {(DQ <'rotate primary hostkey'>)})
    (C {<cp>} {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy.orig'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/sshd_proxy'>}
    )
    (C {<mv>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub.old'>}
    )
    (C {<mv>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa-new.pub'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub'>}
    )
    (C {<mv>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa-new'>} 
      {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa'>}
    )
    (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
      {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> <ssh-rsa> <Id.Lit_Comma ','> 
        ($ Id.VSub_DollarName '$all_algs')
      }
    )
    (C {<expect_nkeys>} {($ Id.VSub_DollarName '$nkeys')} {(DQ <'learn hostkeys'>)})
    (command.AndOr
      ops: [Id.Op_DAmp]
      children: [
        (C {<check_key_present>} {<ssh-rsa>} {($ Id.VSub_DollarName '$OBJ') <'/hkr.ssh-rsa.pub.old'>})
        (C {<fail>} {(DQ <'old key present'>)})
      ]
    )
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [(C {<check_key_present>} {<ssh-rsa>}) (C {<fail>} {(DQ <'didn\'t learn changed key'>)})]
    )
    (C {<verbose>} {(DQ <'check rotate primary hostkey'>)})
    (C {<dossh>} {<-oStrictHostKeyChecking> <Id.Lit_Equals '='> <yes>} 
      {<-oHostKeyAlgorithms> <Id.Lit_Equals '='> <ssh-rsa>}
    )
    (C {<expect_nkeys>} {<1>} {(DQ <'learn hostkeys'>)})
    (command.AndOr
      ops: [Id.Op_DPipe]
      children: [(C {<check_key_present>} {<ssh-rsa>}) (C {<fail>} {(DQ <'didn\'t learn changed key'>)})]
    )
  ]
)