#########################################################################
set -e
-set -o pipefail
+
+# set -o pipefail
######################################################################
function help () {
cat <<EOF
-xremote.sh <script>
+xremote.sh [-h remote_host] <script> [script arguments]
This script takes a script as argument and executes it remotely in a
temporary directory on a ssh-accessible server.
- It parses the script first to find embedded arguments which defines
+ It parses the script first to find embedded arguments which define
the hostname on which to run, the files to send, the files to get
back when the execution is over, and commands to execute before
running the executable remotely.
@XREMOTE_GET: *.dat
@XREMOTE_PRE: ln -s /home/fleuret/data/pytorch ./data
- If no argument is provided to @XREMOTE_HOST, the environment
- variable $XREMOTE_HOST is used instead
+ If the -h option is provided @XREMOTE_HOST is ignored.
+
+ If no argument is provided to @XREMOTE_HOST, and the -h option is
+ not specified, the environment variable \$XREMOTE_HOST is used
+ instead
Contact <francois@fleuret.org> for comments.
######################################################################
-[[ -x "$1" ]] || (help && exit 1)
+while [[ "$1" =~ ^- ]]
+do
+ case "$1"
+ in
+ -h)
+ shift
+ ARG_HOST="$1"
+ echo "xremote: remote forced to ${ARG_HOST}"
+ ;;
+ *)
+ echo "Unknown option $1"
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+######################################################################
+
+[[ -a "$1" ]] || (help && exit 1)
main="$(basename "$1")"
cd "$(dirname "$1")"
+shift
+
trap cleanup_remote_tmp EXIT
######################################################################
PRE)
check_remote_is_defined
+ echo "xremote: ${value}"
ssh < /dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && ${value}"
;;
SEND)
check_remote_is_defined
- tar c ${value} | ssh "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && tar mx"
+ echo "xremote: -- sending files --------------------------------------------"
+ tar ch ${value} | ssh "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && tar mxv"
;;
HOST)
[[ "${REMOTE_DIR}" ]] && (exit "Remote host already defined!" >&2 && exit 1)
- REMOTE_HOST="${value}"
+ REMOTE_HOST="${ARG_HOST}" # Host given in argument has priority
+ [[ "${REMOTE_HOST}" ]] || REMOTE_HOST="${value}"
[[ "${REMOTE_HOST}" ]] || REMOTE_HOST="${XREMOTE_HOST}"
[[ "${REMOTE_HOST}" ]] || (echo "xremote: No remote host specified." >&2 && exit 1)
REMOTE_DIR="$(ssh </dev/null "${REMOTE_HOST}" mktemp -d /tmp/xremote.from_"$(hostname)_$(date +%Y%m%d-%H%M%S)".XXXXXX)"
+ echo "xremote: target is ${REMOTE_HOST}"
;;
esac
fi
tar c "${main}" | ssh "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && tar mx"
-echo "xremote: on ${REMOTE_HOST}"
+echo "xremote: -- running the executable -----------------------------------"
if [[ "${REMOTE_EXEC}" ]]
then
REMOTE_COMMAND="./${main}"
fi
-echo "xremote: -- stdout ---------------------------------------------------"
-ssh </dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && ${REMOTE_COMMAND}"
+######################################################################
+
+# I find this slightly ugly ...
+for s in "$@"
+do
+ quoted_args="${quoted_args} \"${s}\""
+done
+
+ssh </dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && ${REMOTE_COMMAND} ${quoted_args}"
######################################################################
# Disable globbing to keep wildcards for the remote side
-echo "xremote: -- retrieve results -----------------------------------------"
+echo "xremote: -- retrieving files -----------------------------------------"
set -f
label=$(echo "${line}" | sed -e 's/^.*@XREMOTE_\([^:]*\):.*$/\1/')
value=$(echo "${line}" | sed -e 's/^.*@XREMOTE_[^:]*: *\(.*\)$/\1/')
case "${label}" in
+ POST)
+ check_remote_is_defined
+ echo "xremote: ${value}"
+ ssh < /dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && ${value}"
+ ;;
+
GET)
check_remote_is_defined
ssh </dev/null "${REMOTE_HOST}" "cd \"${REMOTE_DIR}\" && tar 2>/dev/null c ${value}" | tar mxv