Last active
June 27, 2019 22:39
-
-
Save tubaman/099b3b01a6c78bdb2110d712cc2a171c to your computer and use it in GitHub Desktop.
Script to connect from one linux desktop to another using VNC over ssh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Connect from one linux desktop to another using SSH over VNC | |
# | |
# The script works best if you have ssh public key authentication setup with | |
# an agent so you don't have to type your ssh password 1000 times. | |
# | |
# Usage: vncssh remote_servername | |
# | |
# What does this do? | |
# 1. Calculate the right scale factor so the remote desktop resolution will | |
# fit on the local desktop's screen. | |
# 2. Start x11vnc on the remote desktop and LocalForward that VNC port back to | |
# the local desktop. | |
# 3. Use vncviewer on the local desktop to connect to x11vnc on the remote | |
# desktop via the ssh LocalForward. | |
# | |
# print line number on error | |
# https://gist.github.com/Integralist/74fffc52bb68e2bcd738 | |
error() { | |
local parent_lineno="$1" | |
local message="$2" | |
local code="${3:-1}" | |
if [[ -n "$message" ]] ; then | |
echo "Error on or near line ${parent_lineno}: ${message}; exiting with status ${code}" | |
else | |
echo "Error on or near line ${parent_lineno}; exiting with status ${code}" | |
fi | |
exit "${code}" | |
} | |
trap 'error ${LINENO}' ERR | |
REMOTEHOST=$1 | |
[ -n "$REMOTEHOST" ] | |
REMOTEDISPLAY=:0 | |
function find_local_available_desktop { | |
for port in $(seq 1 99); do | |
if ! netstat -antu | awk '{ print $4 }' | grep -q 59$(printf %02d $port); then | |
printf %02d $port | |
break | |
fi | |
done | |
} | |
function get_scale { | |
local localsize=$(xrandr | grep \* | awk '{ print $1 }') | |
#echo "localsize: $localsize" >&2 | |
local remotesize=$(ssh $REMOTEHOST "export DISPLAY=$REMOTEDISPLAY; xrandr" | grep \* | awk '{ print $1 }') | |
if [ -z "$remotesize" ]; then | |
remotesize=$(ssh $REMOTEHOST "export DISPLAY=$REMOTEDISPLAY; xrandr" | grep \+ | awk '{ print $1 }') | |
fi | |
if [ -z "$remotesize" ]; then | |
remotesize=$(ssh $REMOTEHOST "export DISPLAY=$REMOTEDISPLAY; xrandr" | grep current | sed 's/\([0-9]*\) x \([0-9]*\),\{0,1\}/\1x\2/g' | awk '{ print $6 }') | |
fi | |
#echo "remotesize: $remotesize" >&2 | |
local localx=$(echo $localsize | sed 's/x.*//') | |
#echo "localx: $localx" >&2 | |
local localy=$(echo $localsize | sed 's/.*x//') | |
#echo "localy: $localy" >&2 | |
local adjusty=75 # adjust to account for panels and other decoractions | |
#echo "adjusty: $adjustx" >&2 | |
localy=$(($localy - $adjusty)) | |
#echo "localy: $localy" >&2 | |
local remotex=$(echo $remotesize | sed 's/x.*//') | |
#echo "remotex: $remotex" >&2 | |
local remotey=$(echo $remotesize | sed 's/.*x//') | |
#echo "remotey: $remotey" >&2 | |
local scalex=$(echo $localx $remotex | awk '{ printf "%.2f\n", $1/$2 }') | |
#echo "scalex: $scalex" >&2 | |
local scaley=$(echo $localy $remotey | awk '{ printf "%.2f\n", $1/$2 }') | |
#echo "scaley: $scaley" >&2 | |
local scale | |
if [ $(echo "$scalex <= $scaley" | bc -l) -eq 1 ]; then | |
scale=$scalex | |
else | |
scale=$scaley | |
fi | |
#echo "scale: $scale" >&2 | |
echo $scale | |
} | |
# TODO: fix race condition here. Instead of searching for an available | |
# port, We should just try the port starting at 5901 below and increment | |
# until it works. | |
LOCAL_DESKTOP=$(find_local_available_desktop) | |
LOCAL_PORT=59$LOCAL_DESKTOP | |
SCALE=$(get_scale) | |
echo "scale: $SCALE" >&2 | |
X11VNC_LOG=$(mktemp --tmpdir x11vnc.tmp.XXXXXXXXXX) | |
ssh -t -L $LOCAL_PORT:localhost:5900 $REMOTEHOST "x11vnc -localhost -display $REMOTEDISPLAY -timeout 60 -scale $SCALE -dp" > $X11VNC_LOG 2>&1 & | |
X11VNC_PID=$! | |
while true; do | |
DESKTOP=$(grep "The VNC desktop is" $X11VNC_LOG | awk '{ print $5 }') | |
if [ -n "$DESKTOP" ]; then | |
rm -f $X11VNC_LOG | |
break | |
fi | |
sleep 0.2 | |
done | |
#vinagre --vnc-scale localhost:$LOCAL_DESKTOP | |
vncviewer -quality 4 -encodings "copyrect tight hextile" localhost:$LOCAL_DESKTOP |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment