Pegue dois (veja o histórico de uma versão que faz scp do lado do servidor e é um pouco mais simples), isto deve ser feito. A essência disso é esta:
- transmita uma variável de ambiente do cliente para o servidor, informando ao servidor como ele pode detectar quando as informações da porta estão disponíveis e, em seguida, obtém e usa essas variáveis.
- uma vez que as informações de porta estão disponíveis, copie-as de cliente para servidor, permitindo que o servidor as obtenha (com ajuda da parte 1 acima) e use-as
Primeiro, configure no lado remoto, você precisa habilitar o envio de uma variável env na configuração sshd :
sudo yourfavouriteeditor /etc/ssh/sshd_config
Localize a linha com AcceptEnv
e adicione MY_PORT_FILE
a ela (ou adicione a linha abaixo da seção direita Host
se ainda não houver uma). Para mim, a linha se tornou isso:
AcceptEnv LANG LC_* MY_PORT_FILE
Lembre-se também de reiniciar sshd para que isso tenha efeito.
Além disso, para que os scripts abaixo funcionem, faça mkdir ~/portfiles
no lado remoto!
Em seguida, no lado local, um trecho de script que será
- crie um nome de arquivo temporário para o redirecionamento stderr
- deixe um trabalho em segundo plano para aguardar que o arquivo tenha conteúdo
- passa o nome do arquivo para o servidor como variável env, enquanto redireciona ssh stderr para o arquivo
- trabalho de plano de fundo continua a copiar o arquivo temporário stderr para o lado do servidor usando scp separado O trabalho de plano de fundo
- também copia um arquivo de sinalizador para o servidor para indicar que o arquivo stderr está pronto
O fragmento de script:
REMOTE=$USER@datserver
PORTFILE='mktemp /tmp/sshdataserverports-$(hostname)-XXXXX'
test -e $PORTFILE && rm -v $PORTFILE
# EMPTYFLAG servers both as empty flag file for remote side,
# and safeguard for background job termination on this side
EMPTYFLAG=$PORTFILE-empty
cp /dev/null $EMPTYFLAG
# this variable has the file name sent over ssh connection
export MY_PORT_FILE=$(basename $PORTFILE)
# background job loop to wait for the temp file to have data
( while [ -f $EMPTYFLAG -a \! -s $PORTFILE ] ; do
sleep 1 # check once per sec
done
sleep 1 # make sure temp file gets the port data
# first copy temp file, ...
scp $PORTFILE $REMOTE:portfiles/$MY_PORT_FILE
# ...then copy flag file telling temp file contents are up to date
scp $EMPTYFLAG $REMOTE:portfiles/$MY_PORT_FILE.flag
) &
# actual ssh terminal connection
ssh -X -o "SendEnv MY_PORT_FILE" -R0:localhost:631 -R0:localhost:4713 $REMOTE 2> $PORTFILE
# remove files after connection is over
rm -v $PORTFILE $EMPTYFLAG
Em seguida, um snippet para o lado remoto, adequado para .bashrc :
# only do this if subdir has been created and env variable set
if [ -d ~/portfiles -a "$MY_PORT_FILE" ] ; then
PORTFILE=~/portfiles/$(basename "$MY_PORT_FILE")
FLAGFILE=$PORTFILE.flag
# wait for FLAGFILE to get copied,
# after which PORTFILE should be complete
while [ \! -f "$FLAGFILE" ] ; do
echo "Waiting for $FLAGFILE..."
sleep 1
done
# use quite exact regexps and head to make this robust
export CUPS_SERVER=localhost:$(grep '^Allocated port [0-9]\+ .* localhost:631[[:space:]]*$' "$PORTFILE" | head -1 | cut -d" " -f3)
export PULSE_SERVER=localhost:$(grep '^Allocated port [0-9]\+ .* localhost:4713[[:space:]]*$' "$PORTFILE" | head -1 | cut -d" " -f3)
echo "Set CUPS_SERVER and PULSE_SERVER"
# copied files served their purpose, and can be removed right away
rm -v -- "$PORTFILE" "$FLAGFILE"
fi
Observação : o código acima, obviamente, não foi totalmente testado e pode conter todos os tipos de erros, copiar e colar erros, etc. Qualquer pessoa que o use também entende, use em seu risco próprio! Eu testei usando apenas conexão localhost, e funcionou para mim, no meu env de teste. YMMV.