Commit 3bf36389 authored by Hubert Lubaczewski's avatar Hubert Lubaczewski
Browse files

initial repo creation

parents
Pipeline #50160685 failed with stages
in 1 minute and 2 seconds
2019-03-04:
- Repo creation, with two tools that I wrote earlier.
Copyright (c) 2019, Hubert 'depesz' Lubaczewski <depesz@depesz.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
depeszs shell utils
===================
Set of shell utils I wrote to help my work in unix shell.
## Requirements
To use these tools you generally need to use Bash shell and standard GNU
tools. If there are any specific requirements for specific tool, they will get
listed in its own section.
## News
You can find news about this project on [my blog](https://www.depesz.com/tag/shell_utils/).
## General utils
### group_by
Groups values from input based on common value in some column.
[Initial blogpost](https://www.depesz.com/2019/02/19/grouping-values-in-shell/)
## TMUX related utils
These scripts are for [TMUX](http://tmux.github.io/) - if you're not familiar
with it - it's terminal multiplexer, kinda like old
[Screen](https://www.gnu.org/software/screen/) but newer and more powerful.
All of them are supposed to be run inside TMUX session.
### tmux_send_to_many
Automates sending "keyboard" input into multiple panes at once.
[Initial blogpost](https://www.depesz.com/2019/02/04/automation-for-doing-stuff-in-multiple-windows-in-tmux/)
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
# End of Unofficial Bash Strict Mode
# defaults
input_separator=$'\t'
output_separator=','
master_separator=$'\t'
group_by_column=''
detail_column=''
# defaults
# Helper functions
die() {
printf -- "$@" >&2
printf '\n' >&2
exit 1
}
show_help_and_die() {
error_message="${1:-}"
help_message="Syntax:
... | $0 [-s INPUT_SEPARATOR] [-o OUTPUT_SEPARATOR] [-m MASTER_SEPARATOR] -g GROUP_COLUMN -d DETAILS_COLUMN
Options:
-s : What is the separator between input columns. Defaults to \\t.
-o : What should be used as separator between group name and detail values in output. Defaults to ','.
-m : What should be used in output before group name and details. Defaults to \\t.
-g : Which column (numbers start from 1) should be used to define group
-d : Which column (numbers start from 1) contain values to group"
if [[ -n "${error_message}" ]]
then
printf "Error:\n %s\n\n" "${error_message}" >&2
echo "${help_message}" >&2
exit 1
fi
echo "${help_message}"
exit 0
}
# Helper functions
# MAIN PROGRAM
## Parse and validate command line arguments
while getopts 's:g:d:o:m:h?' opt "$@"
do
case "${opt}" in
s)
input_separator="${OPTARG}"
;;
g)
group_by_column="${OPTARG}"
;;
d)
detail_column="${OPTARG}"
;;
o)
output_separator="${OPTARG}"
;;
m)
master_separator="${OPTARG}"
;;
h|?)
show_help_and_die
;;
esac
done
[[ -n "${group_by_column}" ]] || die "You didn't provide group by column!"
[[ "${group_by_column}" =~ ^[1-9][0-9]*$ ]] || die "Group by column has to be positive integer, and not: [%s]!" "${group_by_column}"
[[ -n "${detail_column}" ]] || die "You didn't provide details column!"
[[ "${detail_column}" =~ ^[1-9][0-9]*$ ]] || die "Details column has to be positive integer, and not: [%s]!" "${detail_column}"
declare -a values
exec awk -v"os=${output_separator}" -v"hs=${master_separator}" -F"${input_separator}" "
BEGIN { count=0 }
{
g=\$${group_by_column};
v=\$${detail_column};
if ( g in details ) {
details[g] = details[g] os v;
} else {
order[count]=g;
count++;
details[g]=v;
}
}
END {
for (i=0; i < count; i++) {
group=order[i];
printf \"%s%s%s\\n\", group, hs, details[group]
}
}
"
# vim: set ft=sh:
#!/usr/bin/env bash
# Unofficial Bash Strict Mode
# http://redsymbol.net/articles/unofficial-bash-strict-mode/
set -euo pipefail
IFS=$'\n\t'
# End of Unofficial Bash Strict Mode
# defaults
mode="s"
list="0"
verbose=0
wait_time=0
# defaults
# Helper functions
verbose() {
(( verbose == 0 )) && return
printf -- "$@"
printf '\n'
}
die() {
printf -- "$@" >&2
printf '\n' >&2
exit 1
}
show_help_and_die() {
error_message="${1:-}"
help_message="Syntax:
$0 [-a] [-l] [-v] [-w SECONDS] PANE_MATCHER LIST OF STRINGS
Options:
-a : Enables matching across all sessions, not only current.
-l : List all matching panes and exit, don't send any keys.
-w : Wait given number of seconds before moving to next pane
-v : Print verbose information while working.
Arguments:
PANE_MATCHER : Regular expression (compatible with egrep), that will be
used to select panes that should be processed. Without
-a, panes are listed only from current session, and have
format:
WINDOW_NAME.PANE_INDEX
With -a, panes are listed from all sessions, and have
format:
SESSION_NAME:WINDOW_NAME.PANE_INDEX
LIST OF STRINGS : What should be sent to all selected panes."
if [[ -n "${error_message}" ]]
then
printf "Error:\n %s\n\n" "${error_message}" >&2
echo "${help_message}" >&2
exit 1
fi
echo "${help_message}"
exit 0
}
# Helper functions
# MAIN PROGRAM
## Make sure we're under tmux
[[ -n "${TMUX_PANE:-}" ]] || die "You have to run $0 under Tmux!"
current_tmux_session="$( tmux display-message -p -t "${TMUX_PANE}" "#S" )"
## Make sure we're under tmux
## Parse and validate command line arguments
while getopts 'alvw:h?' opt "$@"
do
case "${opt}" in
a)
mode="a"
;;
v)
verbose=1
;;
l)
list=1
;;
w)
wait_time="${OPTARG}"
;;
h|?)
show_help_and_die
;;
esac
done
shift $((OPTIND - 1))
matcher="${1:-}"
[[ -n "${matcher}" ]] || show_help_and_die "You didn't provide PANE_MATCHER?!"
shift
(( list < 1 )) && (( $# < 1 )) && show_help_and_die "You didn't provide LIST OF STRINGS?!"
list_of_strings=( "$@" )
## Parse and validate command line arguments
verbose 'Current tmux session: %s' "${current_tmux_session}"
## Get list of panes
if [[ "${mode}" == "s" ]]
then
full_pane_list="$( tmux list-panes -s -F $'#D\t#W.#P' | sort -t$'\t' -V -k 2,2 )"
else
full_pane_list="$( tmux list-panes -a -F $'#D\t#S:#W.#P' | sort -t$'\t' -V -k 2,2 )"
fi
## Get list of panes
## Find matching panes
target_pane_ids=()
target_pane_names=()
while read -r pane_id pane_name
do
[[ "${pane_name}" =~ $matcher ]] || continue
target_pane_ids+=( "${pane_id}" )
target_pane_names+=( "${pane_name}" )
done <<< "${full_pane_list}"
## Find matching panes
(( 0 == "${#target_pane_ids[@]}" )) && die "There are no matching panes."
if (( "${list}" == 1 ))
then
echo "List of matching panes:"
echo "======================="
i=0
while (( i < ${#target_pane_ids[@]} ))
do
printf -- "- %s\n" "${target_pane_names[$i]}"
(( ++i ))
done
exit 1
fi
if [[ "${wait_time}" == "0" ]]
then
verbose "Sending to matching panes (with no sleep time):"
else
verbose "Sending to matching panes (with sleep for %s):" "${wait_time}"
fi
verbose "- %s\n" "${list_of_strings[@]}"
verbose "Delivering to:"
i=0
while (( i < ${#target_pane_ids[@]} ))
do
verbose '>> %s' "${target_pane_names[$i]}"
tmux send-keys -t "${target_pane_ids[$i]}" "${list_of_strings[@]}"
(( ++i ))
[[ "${wait_time}" == 0 ]] && continue
verbose '- Waiting %s' "${wait_time}"
sleep "${wait_time}"
done
exit 0
# vim: set ft=sh:
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment