#!/bin/bash set -e _help() { SELF=$( basename "$0" ) echo "Console Clipboard manager Usage: $SELF [command] [name] [filename] Commands: (r)ead (w)rite (d)elete (l)ist [default] Name: Any string for the clipboard name. default: 0 Filename: When reading from clipboard: File or folder to write the clipboard contents. If omitted: stdout When writing to clipboard:g/ File or folder to read from. If omitted: stdin Shorthand: echo my data | $SELF 1 # writes data with name: 1 $SELF 1 | cat - # prints the contents of file: 1 " exit } _load_config(){ STORAGE=~/.cache/cclip CONFIG=~/.config/cclip/config [[ -f "$CONFIG" ]] || { mkdir -p $( dirname "$CONFIG" ) echo STORAGE=$STORAGE > "$CONFIG" _msg "created config in "$CONFIG"" } [[ -f "$CONFIG" ]] && . "$CONFIG" # TODO, run line by line for security, get only lines with matching config item mkdir -p "$STORAGE" [[ -e "$STORAGE"/0 ]] || { echo Sample data | _write_stdin 0 } } _list() { cd "$STORAGE" [[ $(ls -A) ]] || { _msg "No clipboard entries" return } printf " %30s %8s %-19s %s\n" Type Size Date Name for n in *; do size=$( du -k -h -s --apparent-size "$n" | awk '{ print $1 }' ) type=$( file -b "$n" ) date=$( date -r "$n" -Iseconds ) printf " %30s %8s %-19s %s\n" \ "${type:0:30}" \ "$size" \ "${date::-6}" \ "$n" done } _write() { # no file mentioned, use stdin [[ -z "$FILE" ]] && stream_in=1 # stdin is open, use stdin [ -t 0 ] || stream_in=1 [ -t 0 ] && [[ -z "$FILE" ]] && { _msg File to read needed, or use stdin exit 1 } # sure to write something, delete target first rm -rf "$STORAGE/$NAME" [[ "$stream_in" -eq 1 ]] && { _write_stdin "$NAME" } || { _write_files "$NAME" "$FILE" } } _write_files() { # name, file cp -av "$2" "$STORAGE/$1" } _write_stdin() { # name cat - > "$STORAGE/$1" } _read() { [[ -e "$STORAGE/$NAME" ]] || { _msg "No such clipboard" return } [[ -z "$FILE" ]] && stream_out=1 [ -t 1 ] || stream_out=1 [[ "$stream_out" -eq 1 ]] && { [[ -d "$STORAGE/$NAME" ]] && { _msg "$NAME is a directory, needs target [file]" exit 1 } _read_stdout "$NAME" } || { _read_files "$NAME" "$FILE" } } _read_files() { # name, file cp -av "$STORAGE/$1" "$2" } _read_stdout() { # name cat "$STORAGE/$1" } _delete() { # name [[ -e "$STORAGE/$1" ]] || { _msg No such clipboard exit 1 } [[ "$FORCE" -ne 1 ]] && { read -p "Really delete $1 ? Break to cancel. " foo } rm -vrf "$STORAGE/$1" } _msg() { echo "$@" >&2 } _get_name() { [[ "$ARG1" = "$CMD" ]] && { NAME="$ARG2" } || { NAME="$ARG1" } [[ -z "$NAME" ]] && NAME=0 return 0 } _get_file() { [[ "$ARG1" = "$NAME" ]] && { FILE="$ARG2" } [[ "$ARG2" = "$NAME" ]] && { FILE="$ARG3" } return 0 } for (( i=1; i<=$#; i++ )); do [[ "${!i}" = "-h" ]] && _help [[ "${!i}" = "--help" ]] && _help done _load_config ARG1="$1" ARG2="$2" ARG3="$3" CMD=list [[ "$1" = "r" || "$1" = "read" ]] && { CMD=read; ARG1=$CMD; } [[ "$1" = "w" || "$1" = "write" ]] && { CMD=write; ARG1=$CMD; } [[ "$1" = "d" || "$1" = "delete" || "$1" = "del" ]] && { CMD=delete; ARG1=$CMD; } [[ "$1" = "l" || "$1" = "list" ]] && { CMD=list; ARG1=$CMD; } [[ "$1" = "h" || "$1" = "help" ]] && _help [[ -n "$1" ]] && [[ -e "$STORAGE"/"$1" ]] && CMD=read # if stdout redirected, default to read [ -t 1 ] || CMD=read # if stdin comes from stream, default to write [ -t 0 ] || CMD=write [[ "$CMD" = list ]] && { _list exit $? } _get_name _get_file [[ "$CMD" = read ]] && { _read exit $? } [[ "$CMD" = delete ]] && { _delete "$NAME" exit $? } [[ "$CMD" = write ]] && { _write exit $? } # TODO: # folders written as TAR # content encrypted with conf variable?