Если вам действительно нужно сначала установить туннель, а потом запустить vncviewer а затем только потом добраться до удаленной консоли, это основной сценарий:
#!/bin/sh
tmpd="$(mktemp -d)" || exit 1         # temporary directory creation
srvr=10.0.0.1                         # remote server
sckt="$tmpd"/"$$-${srvr}".socket      # control socket for SSH connection sharing
clean() { rm -rf "$tmpd"; }           # cleaning function, removes the temporary directory
                                      # establishing SSH master connection
ssh -o ControlMaster=yes \
    -o ControlPath="$sckt" \
    -o ExitOnForwardFailure=yes \
    -Nf -L 555:localhost:555 "$srvr" || { clean; exit 2; }
                                      # the tunnel is now established
vncviewer >/dev/null 2>&1 &           # silent custom command in the background
ssh -o ControlPath="$sckt" "$srvr"    # reusing the master connection
                                      # (exit the remote shell to continue)
wait $!                               # waiting for vncviewer to terminate
ssh -o ControlPath="$sckt" \
    -O exit "$srvr"                   # terminating the master connection
clean || exit 4                       # removing the temporary directory
Протестировано на клиенте Kubuntu, подключающемся к серверу Debian. Я не уверен, насколько он крепок. Считайте это доказательством концепции. Смотрите man 1 ssh и man 5 ssh_config для деталей.