1 Star 0 Fork 0

韦相铭 / rmate

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
rmate 10.31 KB
一键复制 编辑 原始数据 按行查看 历史
vonas 提交于 2020-09-25 19:29 . Use $TMPDIR instead of /tmp
#!/usr/bin/env bash
# rmate
# Copyright (C) 2011-present by Harald Lapp <harald@octris.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This script can be found at:
# https://github.com/aurora/rmate
#
#
# This script is a pure bash compatible shell script implementing remote
# textmate functionality
#
#
# Thanks very much to all users and contributors! All bug-reports,
# feature-requests, patches, etc. are greatly appreciated! :-)
#
# init
#
version="1.0.2"
version_date="2019-04-08"
version_string="rmate-sh $version ($version_date)"
# determine hostname
function hostname_command(){
if command -v hostname >/dev/null 2>&1; then
echo "hostname"
else {
HOSTNAME_DESCRIPTOR="/proc/sys/kernel/hostname"
if test -r "$HOSTNAME_DESCRIPTOR"; then
echo "cat $HOSTNAME_DESCRIPTOR"
else
echo "hostname"
fi
}
fi
}
hostname=$($(hostname_command))
# default configuration
host=localhost
port=52698
eval home=$(builtin printf "~%q" "${SUDO_USER:-$LOGNAME}")
function load_config {
local rc_file=$1
local row
local host_pattern="^host(:[[:space:]]+|=)([^ ]+)"
local port_pattern="^port(:[[:space:]]+|=)([0-9]+)"
if [ -f "$rc_file" ]; then
while read -r row; do
if [[ "$row" =~ $host_pattern ]]; then
host=${BASH_REMATCH[2]}
elif [[ "$row" =~ $port_pattern ]]; then
port=${BASH_REMATCH[2]}
fi
done < "$rc_file"
fi
}
for i in "/etc/${0##*/}" $home/."${0##*/}/${0##*/}.rc" $home/."${0##*/}.rc"; do
load_config $i
done
host="${RMATE_HOST:-$host}"
port="${RMATE_PORT:-$port}"
tmp_dir="${TMPDIR:-/tmp}"
# misc initialization
filepaths=()
displaynames=()
selections=()
filetypes=()
verbose=false
nowait=true
force=false
success=false
# process command-line parameters
#
function showusage {
echo "usage: $(basename $0) [arguments] [--] file-path edit specified file
or: $(basename $0) [arguments] - read text from stdin
-H, --host HOST Connect to HOST. Use 'auto' to detect the host from
SSH. Defaults to $host.
-p, --port PORT Port number to use for connection. Defaults to $port.
-w, --[no-]wait Wait for file to be closed by TextMate.
-l, --line LINE Place caret on line number after loading file.
+N Alias for --line, if N is a number (eg.: +5).
-m, --name NAME The display name shown in TextMate.
-t, --type TYPE Treat file as having specified type.
-n, --new Open in a new window (Sublime Text).
-f, --force Open even if file is not writable.
-v, --verbose Verbose logging messages.
-h, --help Display this usage information.
--version Show version and exit.
"
}
function log {
if [[ $verbose = true ]]; then
echo "$@" 1>&2
fi
}
function dirpath {
(cd "$(dirname "$1")" >/dev/null 2>/dev/null || { echo "unable to cd to $1 directory" 1>&2; exit; } ; pwd -P)
}
function resolvepath {
local filepath="$1"
local directory
while [ -L "$filepath" ]; do
directory="$(cd -P "$(dirname "$filepath")" && pwd)"
filepath="$(readlink "$filepath")"
if [[ "${filepath:0:1}" != "/" ]]; then
filepath="$directory/$filepath"
fi
done
echo "$filepath"
}
function canonicalize {
local filepath="$1"
local relativepath
local result
if [[ "${filepath:0:1}" = "-" ]]; then
filepath="./$filepath"
fi
local dir=$(dirpath "$filepath")
if [ -L "$filepath" ]; then
relativepath=$(cd "$dir" || { echo "unable to cd to $dir" 1>&2; exit; } ; resolvepath "$(basename "$filepath")")
result=$(dirpath "$relativepath")/$(basename "$relativepath")
else
result=$(basename "$filepath")
if [ "$dir" = '/' ]; then
result="$dir$result"
else
result="$dir/$result"
fi
fi
echo "$result"
}
while [[ "$1" != "" ]]; do
case $1 in
-)
filepaths+=("-")
;;
--)
shift
break
;;
-H|--host)
host=$2
shift
;;
-p|--port)
port=$2
shift
;;
-w|--wait)
nowait=false
;;
--no-wait)
nowait=true
;;
-l|--line)
selections+=($2)
shift
;;
-m|--name)
displaynames+=($2)
shift
;;
-t|--type)
filetypes+=($2)
shift
;;
-n|--new)
new=true
;;
-f|--force)
force=true
;;
-v|--verbose)
verbose=true
;;
--version)
echo "$version_string"
exit 0
;;
-h|-\?|--help)
showusage
exit 0
;;
+[0-9][0-9]*)
selections+=(${1:1})
;;
*)
if [[ "${1:0:1}" = "-" ]]; then
showusage
exit 1
else
filepaths+=("$1")
fi
;;
esac
shift
done
if [[ "$host" = "auto" && "$SSH_CONNECTION" != "" ]]; then
host=${SSH_CONNECTION%% *}
fi
filepaths=("${filepaths[@]}" "$@")
if [ "${filepaths[*]}" = "" ]; then
if [[ $nowait = false ]]; then
filepaths=('-')
else
case "$-" in
*i*)
showusage
exit 1
;;
*)
filepaths=('-')
;;
esac
fi
fi
#------------------------------------------------------------
# main
#------------------------------------------------------------
function open_file {
local index="$1"
local filepath="${filepaths[$index]}"
local selection="${selections[$index]}"
local filetype="${filetypes[$index]}"
local displayname="${displaynames[$index]}"
local realpath
local data
if [ "$filepath" != "-" ]; then
realpath=$(canonicalize "$filepath")
log "$realpath"
if [ -d "$filepath" ]; then
echo "$filepath is a directory and rmate is unable to handle directories."
return 1
fi
if [ -f "$realpath" ] && [ ! -w "$realpath" ]; then
if [[ $force = false ]]; then
echo "File $filepath is not writable! Use -f to open anyway."
return 1
elif [[ $verbose = true ]]; then
log "File $filepath is not writable! Opening anyway."
fi
fi
if [ "$displayname" = "" ]; then
displayname="$hostname:$filepath"
fi
else
displayname="$hostname:untitled"
fi
echo "open" 1>&3
echo "display-name: $displayname" 1>&3
echo "real-path: $realpath" 1>&3
echo "data-on-save: yes" 1>&3
echo "re-activate: yes" 1>&3
echo "token: $filepath" 1>&3
if [[ $new = true ]]; then
echo "new: yes" 1>&3
fi
if [ "$selection" != "" ]; then
echo "selection: $selection" 1>&3
fi
if [ "$filetype" != "" ]; then
echo "file-type: $filetype" 1>&3
fi
if [ "$filepath" != "-" ] && [ -f "$filepath" ]; then
filesize=$(($(wc -c <"$realpath")))
echo "data: $filesize" 1>&3
cat "$realpath" 1>&3
elif [ "$filepath" = "-" ]; then
if [ -t 0 ]; then
echo "Reading from stdin, press ^D to stop"
else
log "Reading from stdin"
fi
# preserve trailing newlines
data=$(cat; echo x)
data=${data%x}
filesize=$(($(echo -ne "$data" | wc -c)))
echo "data: $filesize" 1>&3
echo -n "$data" 1>&3
else
echo "data: 0" 1>&3
fi
echo 1>&3
}
function handle_connection {
local cmd
local name
local value
local token
local tmp
local content
while read -r 0<&3; do
REPLY="${REPLY#"${REPLY%%[![:space:]]*}"}"
REPLY="${REPLY%"${REPLY##*[![:space:]]}"}"
cmd=$REPLY
token=""
tmp=""
while read -r 0<&3; do
REPLY="${REPLY#"${REPLY%%[![:space:]]*}"}"
REPLY="${REPLY%"${REPLY##*[![:space:]]}"}"
if [ "$REPLY" = "" ]; then
break
fi
name="${REPLY%%:*}"
value="${REPLY##*:}"
value="${value#"${value%%[![:space:]]*}"}" # fix textmate syntax highlighting: "
case $name in
"token")
token=$value
;;
"data")
if [ "$tmp" = "" ]; then
tmp="$tmp_dir/rmate.$RANDOM.$$"
touch "$tmp"
fi
dd bs=1 count=$value <&3 >>"$tmp" 2>/dev/null
;;
*)
;;
esac
done
if [[ "$cmd" = "close" ]]; then
log "Closing $token"
if [[ "$token" == "-" ]]; then
echo -n "$content"
fi
elif [[ "$cmd" = "save" ]]; then
log "Saving $token"
if [ "$token" != "-" ]; then
cat "$tmp" > "$token"
else
content=$(cat "$tmp")
fi
rm "$tmp"
fi
done
log "Done"
}
# connect to textmate and send command
#
exec 3<> "/dev/tcp/$host/$port"
if [ $? -gt 0 ]; then
echo "Unable to connect to TextMate on $host:$port"
exit 1
fi
read -r server_info 0<&3
log $server_info
for i in "${!filepaths[@]}"; do
open_file "$i"
[[ $? = 0 ]] && new=false && success=true
done
[[ $success = false ]] && exit 1
echo "." 1>&3
if [[ $nowait = true ]]; then
exec </dev/null >/dev/null 2>/dev/null
( (handle_connection &) &)
else
handle_connection
fi
1
https://gitee.com/bestming/rmate.git
git@gitee.com:bestming/rmate.git
bestming
rmate
rmate
master

搜索帮助