Bash: Use replaceVars instead.
This commit is contained in:
parent
4bcedc1a2e
commit
8d48872d3c
|
@ -1,13 +1,38 @@
|
||||||
{ util, pkgs, ... }@args:
|
{
|
||||||
|
util,
|
||||||
|
pkgs,
|
||||||
|
secret,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
let
|
let
|
||||||
modules = util.catText (util.ls ./module) args;
|
accent = "${config.module.style.color.accentR};${config.module.style.color.accentG};${config.module.style.color.accentB}";
|
||||||
modulesFile = pkgs.writeText "BashModules" modules;
|
negative = "${config.module.style.color.negativeR};${config.module.style.color.negativeG};${config.module.style.color.negativeB}";
|
||||||
|
neutral = "${config.module.style.color.neutralR};${config.module.style.color.neutralG};${config.module.style.color.neutralB}";
|
||||||
|
positive = "${config.module.style.color.positiveR};${config.module.style.color.positiveG};${config.module.style.color.positiveB}";
|
||||||
|
|
||||||
|
tgbot = secret.tg.bt;
|
||||||
|
tgdata = secret.tg.dt "false";
|
||||||
|
tgdatasilent = secret.tg.dt "true";
|
||||||
|
|
||||||
|
modulesRaw = pkgs.writeText "bash-user-modules-raw" (util.catContent (util.ls ./module));
|
||||||
|
modulesFile = pkgs.replaceVars modulesRaw {
|
||||||
|
inherit
|
||||||
|
accent
|
||||||
|
negative
|
||||||
|
neutral
|
||||||
|
positive
|
||||||
|
tgbot
|
||||||
|
tgdata
|
||||||
|
tgdatasilent
|
||||||
|
;
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit modules modulesFile;
|
inherit modulesFile;
|
||||||
|
|
||||||
bashrc =
|
bashrc =
|
||||||
modules
|
(builtins.readFile modulesFile)
|
||||||
+ ''
|
+ ''
|
||||||
# Find all functions.
|
# Find all functions.
|
||||||
function find_function() {
|
function find_function() {
|
||||||
|
|
|
@ -1,423 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
export _archive_pattern="_[0-9]{12}-[[:alnum:]]{40}"
|
|
||||||
export _archive_pattern_compressed="_[0-9]{12}-[[:alnum:]]{40}\.t(ar|gz|xz)$"
|
|
||||||
export _archive_pattern_fast="_[0-9]{12}-[[:alnum:]]{40}\.tar$"
|
|
||||||
|
|
||||||
# Archive using multiple threads. Uses 75% of free RAM.
|
|
||||||
# All directories by default.
|
|
||||||
# Supports .archiveignore exclude file.
|
|
||||||
# Usage: archive [DIRS]
|
|
||||||
function archive() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_dir))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Skip if already an archive.
|
|
||||||
_is_archive "''${target}" && {
|
|
||||||
_iterate_skip "Already an archive."
|
|
||||||
return 0
|
|
||||||
};
|
|
||||||
|
|
||||||
# Cut full paths.
|
|
||||||
[[ "''${target##*/}" = "" ]] || target="''${target##*/}"
|
|
||||||
|
|
||||||
local date=$(_archive_date)
|
|
||||||
|
|
||||||
# Parse name.
|
|
||||||
local name=$(parse_pascal ''${target})
|
|
||||||
|
|
||||||
# Exclude support.
|
|
||||||
local exclude=""
|
|
||||||
[[ -f ".archiveignore" ]] && exclude="--exclude-from=.archiveignore"
|
|
||||||
[[ -f "''${target}/.archiveignore" ]] && exclude="--exclude-from=''${target}/.archiveignore"
|
|
||||||
|
|
||||||
# Create archive.
|
|
||||||
local hash=$(tar ''${exclude} -c ''${target} | pv -s $(/usr/bin/env du -sb ''${target} | awk '{print $1}') | xz -9e --threads=0 --memlimit=$(_archive_memlimit) | tee ''${name}.txz | sha1sum | cut -d\ -f1)
|
|
||||||
|
|
||||||
# Append hash to target name.
|
|
||||||
local new_name="''${name}_''${date}-''${hash}.txz"
|
|
||||||
mv -- ''${name}.txz ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Creates a simple archive.
|
|
||||||
# If it is a file, it just reformats file name to match archive name.
|
|
||||||
# For dirs, it first creates a tar archive.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: archive_fast [DIRS]
|
|
||||||
function archive_fast() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=("''${@}")
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Skip if already an archive.
|
|
||||||
_is_archive "''${target}" && {
|
|
||||||
_iterate_skip "Already an archive."
|
|
||||||
return 0
|
|
||||||
};
|
|
||||||
|
|
||||||
# Cut full paths.
|
|
||||||
[[ "''${target##*/}" = "" ]] || target="''${target##*/}"
|
|
||||||
|
|
||||||
# Start timestamp.
|
|
||||||
local date=$(_archive_date)
|
|
||||||
|
|
||||||
# Exclude support.
|
|
||||||
local exclude
|
|
||||||
[[ -f ".archiveignore" ]] && exclude="--exclude-from=.archiveignore"
|
|
||||||
[[ -f "''${target}/.archiveignore" ]] && exclude="--exclude-from=''${target}/.archiveignore"
|
|
||||||
|
|
||||||
local name
|
|
||||||
local extension
|
|
||||||
|
|
||||||
if [[ -d "''${target}" ]]; then
|
|
||||||
name=$(parse_pascal "''${target}")
|
|
||||||
|
|
||||||
# Create archive.
|
|
||||||
local hash=$(tar ''${exclude} -c "''${target}" | pv -s $(/usr/bin/env du -sb "''${target}" | awk '{print $1}') | tee "''${name}".tar | sha1sum | cut -d\ -f1)
|
|
||||||
|
|
||||||
# Append hash to target name.
|
|
||||||
local new_name="''${name}_''${date}-''${hash}.tar"
|
|
||||||
mv -- "''${name}".tar ''${new_name} && echo ''${new_name}
|
|
||||||
else
|
|
||||||
name=$(parse_pascal "''${target%.*}")
|
|
||||||
extension=".''${target##*.}"
|
|
||||||
|
|
||||||
# Check if extension matches name, then drop it.
|
|
||||||
[[ "''${extension}" = ".''${target%.*}" ]] && extension=""
|
|
||||||
|
|
||||||
local hash=$(pv "''${target}" | sha1sum | cut -d\ -f1)
|
|
||||||
local new_name="''${name}_''${date}-''${hash}''${extension}"
|
|
||||||
mv -- "''${target}" "''${new_name}" && echo ''${new_name}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check archives integrity.
|
|
||||||
# Checks all archives by default.
|
|
||||||
# Usage: archive_check [FILES]
|
|
||||||
function archive_check() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_archive))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
_archive_check "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete old versions of an archive.
|
|
||||||
# All archives with 1 version by default.
|
|
||||||
# Usage: archive_prune [NAME] [VERSIONS]
|
|
||||||
function archive_prune() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${1})
|
|
||||||
local versions=''${2}
|
|
||||||
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_archive_names))
|
|
||||||
[[ "''${versions}" = "" ]] && versions=1
|
|
||||||
|
|
||||||
if [[ ''${#} -gt 2 ]]; then
|
|
||||||
help archive_prune
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local prune=($(ls | grep -E "^''${target}''${_archive_pattern}" | sort -r | sed -e "1,''${versions}d"))
|
|
||||||
|
|
||||||
for archive in ''${prune[@]}; do
|
|
||||||
rm -- "''${archive}" && echo "''${archive}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete specified or all archive files.
|
|
||||||
# Usage: archive_rm [FILES]
|
|
||||||
function archive_rm() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_archive))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
rm -- "''${target}" && echo "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Recompress previously created archive_fast with better compression.
|
|
||||||
# Usage: archive_compress [FILES]
|
|
||||||
function archive_compress() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=$(_ls_archive_fast)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local data=($(_archive_parse "''${target}"))
|
|
||||||
local tmp="''${data[0]}.txz"
|
|
||||||
|
|
||||||
# Check that old format.
|
|
||||||
if [[ "''${data[3]}" != "tar" ]]; then
|
|
||||||
_iterate_skip "Not in .tar format!"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check integrity.
|
|
||||||
_archive_check "''${target}" || return 1
|
|
||||||
|
|
||||||
# Recompress.
|
|
||||||
local hash=$(pv "''${target}" | xz -9e --threads=0 --memlimit=$(_archive_memlimit) | tee "''${tmp}" | sha1sum | cut -d\ -f1)
|
|
||||||
|
|
||||||
# Rename.
|
|
||||||
local new_name="''${data[0]}_''${data[1]}-''${hash}.txz"
|
|
||||||
mv -- ''${tmp} ''${new_name} && rm ''${target} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename archives.
|
|
||||||
# If no name specified, it simplifies archive's name.
|
|
||||||
# If no archives specified, apply to all archives.
|
|
||||||
# Usage: archive_name [ARCHIVE] [NAME]
|
|
||||||
function archive_name() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets="''${1}"
|
|
||||||
local name="''${2}"
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_archive))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Simplify name by default.
|
|
||||||
if [[ "''${name}" = "" || ''${count} -gt 1 ]]; then
|
|
||||||
name="''${target%_*}"
|
|
||||||
name="$(parse_pascal ''${name})"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove old name.
|
|
||||||
local data="''${target##*_}"
|
|
||||||
local new_name="''${name}_''${data}"
|
|
||||||
|
|
||||||
# Check for the same name.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Check for existing target.
|
|
||||||
if [[ -f "''${new_name}" ]]; then
|
|
||||||
_error "''${new_name}: Already exists!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Rename.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Extract previously created archive with checksum validation.
|
|
||||||
# Supports unarchiving exact paths from the remote machines (rsync syntax).
|
|
||||||
# Usage: unarchive [HOST:FILES]
|
|
||||||
function unarchive() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=$(_ls_archive_compressed)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Validate.
|
|
||||||
# _archive_check "''${target}" || return 1
|
|
||||||
if ! _is_compressed_archive "''${target}"; then
|
|
||||||
_iterate_skip "Not a compressed archive."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remote archives.
|
|
||||||
local remote
|
|
||||||
local file="''${target}"
|
|
||||||
|
|
||||||
if [[ "''${target//\\:/}" == *:* ]]; then
|
|
||||||
local host="''${target%%:*}"
|
|
||||||
file="''${target#*:}"
|
|
||||||
remote=(trysudo ssh ''${host})
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract.
|
|
||||||
case "''${file##*.}" in
|
|
||||||
"txz")
|
|
||||||
''${remote[@]} pv -f ''${file} | xz -d | tar -xf -
|
|
||||||
;;
|
|
||||||
"tar")
|
|
||||||
''${remote[@]} pv -f ''${file} | tar -xf -
|
|
||||||
;;
|
|
||||||
"tgz")
|
|
||||||
''${remote[@]} pv -f ''${file} | gzip -d | tar -xf -
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Change archive's filesystem time to match creation date.
|
|
||||||
# Usage: archive_touch [FILES]
|
|
||||||
function archive_touch() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=$(_ls_archive)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local data=($(_archive_parse "''${target}"))
|
|
||||||
local date=''${data[1]}
|
|
||||||
touch -t ''${date} -- ''${target}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse archive file name to get: name, date, hash and format.
|
|
||||||
# Usage: _archive_parse <FILENAME>
|
|
||||||
function _archive_parse() {
|
|
||||||
local input="''${1}"
|
|
||||||
local name="''${input%_*}"
|
|
||||||
local format="''${input##*.}"
|
|
||||||
local data="''${input##*_}"; data="''${data%.*}"
|
|
||||||
local date="''${data%%-*}"
|
|
||||||
local hash="''${data##*-}"
|
|
||||||
|
|
||||||
# No extension if no dots.
|
|
||||||
[[ "''${input}" = *\.* ]] || format=""
|
|
||||||
|
|
||||||
echo "''${name}"
|
|
||||||
echo "''${date}"
|
|
||||||
echo "''${hash}"
|
|
||||||
echo "''${format}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete for archive_name function.
|
|
||||||
# First arg is the archives list, second one is selected archive's current name.
|
|
||||||
function _comp_archive_name() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
COMPREPLY=()
|
|
||||||
|
|
||||||
local cur="''${COMP_WORDS[COMP_CWORD]}"
|
|
||||||
local prev="''${COMP_WORDS[COMP_CWORD-1]}"
|
|
||||||
local command="''${COMP_WORDS[0]}"
|
|
||||||
|
|
||||||
if [[ "''${prev}" = "''${command}" ]]; then
|
|
||||||
COMPREPLY=( $(compgen -W "$(ls | grep -E ''${_archive_pattern})" -- ''${cur}) )
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
local data=($(_archive_parse ''${prev}))
|
|
||||||
local name="''${data[0]}"
|
|
||||||
COMPREPLY=( $(compgen -W "''${name}" -- ''${cur}) )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with archives in current dir.
|
|
||||||
function _comp_archive_grep() {
|
|
||||||
_autocomplete_grep ''${_archive_pattern}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with fast archives in current dir.
|
|
||||||
function _comp_archive_grep_fast() {
|
|
||||||
_autocomplete_grep ''${_archive_pattern_fast}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get date for a new archive.
|
|
||||||
function _archive_date() {
|
|
||||||
date +%Y%m%d%H%M
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get names of all archives.
|
|
||||||
function _archive_names() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local archives=($(_ls_archive))
|
|
||||||
local names=()
|
|
||||||
|
|
||||||
for archive in ''${archives[@]}; do
|
|
||||||
local data=($(_archive_parse ''${archive}))
|
|
||||||
names+=(''${data[0]})
|
|
||||||
done
|
|
||||||
|
|
||||||
# Remove copies.
|
|
||||||
names=($(printf '%s\n' "''${names[@]}" | sort -u))
|
|
||||||
|
|
||||||
printf '%s\n' "''${names[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with names of all archives.
|
|
||||||
function _comp_archive_names() {
|
|
||||||
_autocomplete $(_archive_names)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if file is an archive.
|
|
||||||
function _is_archive() {
|
|
||||||
local target="''${*}"
|
|
||||||
local out=$(echo "''${target##*/}" | grep -E ''${_archive_pattern})
|
|
||||||
|
|
||||||
[[ "''${out}" != "" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if file is a compressed archive.
|
|
||||||
function _is_compressed_archive() {
|
|
||||||
local out=$(echo "''${*}" | grep -E ''${_archive_pattern_compressed})
|
|
||||||
|
|
||||||
[[ "''${out}" != "" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
# List all archives.
|
|
||||||
function _ls_archive() {
|
|
||||||
ls | grep -E ''${_archive_pattern}
|
|
||||||
}
|
|
||||||
|
|
||||||
# List fast archives.
|
|
||||||
function _ls_archive_fast() {
|
|
||||||
ls | grep -E ''${_archive_pattern_fast}
|
|
||||||
}
|
|
||||||
|
|
||||||
# List fast archives.
|
|
||||||
function _ls_archive_compressed() {
|
|
||||||
ls | grep -E ''${_archive_pattern_compressed}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Filter input for archives only.
|
|
||||||
function _filter_archive() {
|
|
||||||
grep -E ''${_archive_pattern}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _archive_memlimit() {
|
|
||||||
local mem_free=$(_mem_free)
|
|
||||||
local mem_limit=$((mem_free*3/4))
|
|
||||||
|
|
||||||
echo "''${mem_limit}MiB"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _archive_check() {
|
|
||||||
# Extract hash from name.
|
|
||||||
local data=($(_archive_parse ''${target}))
|
|
||||||
local saved=''${data[2]}
|
|
||||||
|
|
||||||
# Calculate actual hash.
|
|
||||||
local actual=$(pv ''${target} | sha1sum | cut -d\ -f1)
|
|
||||||
|
|
||||||
# Compare hashes.
|
|
||||||
[[ "''${actual}" = "''${saved}" ]] || _error "Archive check failed."
|
|
||||||
}
|
|
||||||
|
|
||||||
# complete -o filenames -F _comp_archive_grep archive_check unarchive archive_rm archive_touch
|
|
||||||
# complete -o filenames -F _comp_archive_grep_fast archive_xz
|
|
||||||
complete -o filenames -F _comp_archive_name archive_name
|
|
||||||
complete -o filenames -F _comp_archive_names archive_prune
|
|
||||||
'';
|
|
||||||
}
|
|
419
home/program/bash/module/Archive.sh
Normal file
419
home/program/bash/module/Archive.sh
Normal file
|
@ -0,0 +1,419 @@
|
||||||
|
export _archive_pattern="_[0-9]{12}-[[:alnum:]]{40}"
|
||||||
|
export _archive_pattern_compressed="_[0-9]{12}-[[:alnum:]]{40}\.t(ar|gz|xz)$"
|
||||||
|
export _archive_pattern_fast="_[0-9]{12}-[[:alnum:]]{40}\.tar$"
|
||||||
|
|
||||||
|
# Archive using multiple threads. Uses 75% of free RAM.
|
||||||
|
# All directories by default.
|
||||||
|
# Supports .archiveignore exclude file.
|
||||||
|
# Usage: archive [DIRS]
|
||||||
|
function archive() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_dir))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Skip if already an archive.
|
||||||
|
_is_archive "${target}" && {
|
||||||
|
_iterate_skip "Already an archive."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cut full paths.
|
||||||
|
[[ ${target##*/} == "" ]] || target="${target##*/}"
|
||||||
|
|
||||||
|
local date=$(_archive_date)
|
||||||
|
|
||||||
|
# Parse name.
|
||||||
|
local name=$(parse_pascal ${target})
|
||||||
|
|
||||||
|
# Exclude support.
|
||||||
|
local exclude=""
|
||||||
|
[[ -f ".archiveignore" ]] && exclude="--exclude-from=.archiveignore"
|
||||||
|
[[ -f "${target}/.archiveignore" ]] && exclude="--exclude-from=${target}/.archiveignore"
|
||||||
|
|
||||||
|
# Create archive.
|
||||||
|
local hash=$(tar ${exclude} -c ${target} | pv -s $(/usr/bin/env du -sb ${target} | awk '{print $1}') | xz -9e --threads=0 --memlimit=$(_archive_memlimit) | tee ${name}.txz | sha1sum | cut -d\ -f1)
|
||||||
|
|
||||||
|
# Append hash to target name.
|
||||||
|
local new_name="${name}_${date}-${hash}.txz"
|
||||||
|
mv -- ${name}.txz ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Creates a simple archive.
|
||||||
|
# If it is a file, it just reformats file name to match archive name.
|
||||||
|
# For dirs, it first creates a tar archive.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: archive_fast [DIRS]
|
||||||
|
function archive_fast() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=("${@}")
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Skip if already an archive.
|
||||||
|
_is_archive "${target}" && {
|
||||||
|
_iterate_skip "Already an archive."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cut full paths.
|
||||||
|
[[ ${target##*/} == "" ]] || target="${target##*/}"
|
||||||
|
|
||||||
|
# Start timestamp.
|
||||||
|
local date=$(_archive_date)
|
||||||
|
|
||||||
|
# Exclude support.
|
||||||
|
local exclude
|
||||||
|
[[ -f ".archiveignore" ]] && exclude="--exclude-from=.archiveignore"
|
||||||
|
[[ -f "${target}/.archiveignore" ]] && exclude="--exclude-from=${target}/.archiveignore"
|
||||||
|
|
||||||
|
local name
|
||||||
|
local extension
|
||||||
|
|
||||||
|
if [[ -d ${target} ]]; then
|
||||||
|
name=$(parse_pascal "${target}")
|
||||||
|
|
||||||
|
# Create archive.
|
||||||
|
local hash=$(tar ${exclude} -c "${target}" | pv -s $(/usr/bin/env du -sb "${target}" | awk '{print $1}') | tee "${name}".tar | sha1sum | cut -d\ -f1)
|
||||||
|
|
||||||
|
# Append hash to target name.
|
||||||
|
local new_name="${name}_${date}-${hash}.tar"
|
||||||
|
mv -- "${name}".tar ${new_name} && echo ${new_name}
|
||||||
|
else
|
||||||
|
name=$(parse_pascal "${target%.*}")
|
||||||
|
extension=".${target##*.}"
|
||||||
|
|
||||||
|
# Check if extension matches name, then drop it.
|
||||||
|
[[ ${extension} == ".${target%.*}" ]] && extension=""
|
||||||
|
|
||||||
|
local hash=$(pv "${target}" | sha1sum | cut -d\ -f1)
|
||||||
|
local new_name="${name}_${date}-${hash}${extension}"
|
||||||
|
mv -- "${target}" "${new_name}" && echo ${new_name}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check archives integrity.
|
||||||
|
# Checks all archives by default.
|
||||||
|
# Usage: archive_check [FILES]
|
||||||
|
function archive_check() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_archive))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
_archive_check "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete old versions of an archive.
|
||||||
|
# All archives with 1 version by default.
|
||||||
|
# Usage: archive_prune [NAME] [VERSIONS]
|
||||||
|
function archive_prune() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${1})
|
||||||
|
local versions=${2}
|
||||||
|
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_archive_names))
|
||||||
|
[[ ${versions} == "" ]] && versions=1
|
||||||
|
|
||||||
|
if [[ ${#} -gt 2 ]]; then
|
||||||
|
help archive_prune
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local prune=($(ls | grep -E "^${target}${_archive_pattern}" | sort -r | sed -e "1,${versions}d"))
|
||||||
|
|
||||||
|
for archive in ${prune[@]}; do
|
||||||
|
rm -- "${archive}" && echo "${archive}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete specified or all archive files.
|
||||||
|
# Usage: archive_rm [FILES]
|
||||||
|
function archive_rm() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_archive))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
rm -- "${target}" && echo "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Recompress previously created archive_fast with better compression.
|
||||||
|
# Usage: archive_compress [FILES]
|
||||||
|
function archive_compress() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=$(_ls_archive_fast)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local data=($(_archive_parse "${target}"))
|
||||||
|
local tmp="${data[0]}.txz"
|
||||||
|
|
||||||
|
# Check that old format.
|
||||||
|
if [[ ${data[3]} != "tar" ]]; then
|
||||||
|
_iterate_skip "Not in .tar format!"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check integrity.
|
||||||
|
_archive_check "${target}" || return 1
|
||||||
|
|
||||||
|
# Recompress.
|
||||||
|
local hash=$(pv "${target}" | xz -9e --threads=0 --memlimit=$(_archive_memlimit) | tee "${tmp}" | sha1sum | cut -d\ -f1)
|
||||||
|
|
||||||
|
# Rename.
|
||||||
|
local new_name="${data[0]}_${data[1]}-${hash}.txz"
|
||||||
|
mv -- ${tmp} ${new_name} && rm ${target} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename archives.
|
||||||
|
# If no name specified, it simplifies archive's name.
|
||||||
|
# If no archives specified, apply to all archives.
|
||||||
|
# Usage: archive_name [ARCHIVE] [NAME]
|
||||||
|
function archive_name() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets="${1}"
|
||||||
|
local name="${2}"
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_archive))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Simplify name by default.
|
||||||
|
if [[ ${name} == "" || ${count} -gt 1 ]]; then
|
||||||
|
name="${target%_*}"
|
||||||
|
name="$(parse_pascal ${name})"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remove old name.
|
||||||
|
local data="${target##*_}"
|
||||||
|
local new_name="${name}_${data}"
|
||||||
|
|
||||||
|
# Check for the same name.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Check for existing target.
|
||||||
|
if [[ -f ${new_name} ]]; then
|
||||||
|
_error "${new_name}: Already exists!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Rename.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Extract previously created archive with checksum validation.
|
||||||
|
# Supports unarchiving exact paths from the remote machines (rsync syntax).
|
||||||
|
# Usage: unarchive [HOST:FILES]
|
||||||
|
function unarchive() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=$(_ls_archive_compressed)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Validate.
|
||||||
|
# _archive_check "${target}" || return 1
|
||||||
|
if ! _is_compressed_archive "${target}"; then
|
||||||
|
_iterate_skip "Not a compressed archive."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Remote archives.
|
||||||
|
local remote
|
||||||
|
local file="${target}"
|
||||||
|
|
||||||
|
if [[ ${target//\\:/} == *:* ]]; then
|
||||||
|
local host="${target%%:*}"
|
||||||
|
file="${target#*:}"
|
||||||
|
remote=(trysudo ssh ${host})
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Extract.
|
||||||
|
case "${file##*.}" in
|
||||||
|
"txz")
|
||||||
|
${remote[@]} pv -f ${file} | xz -d | tar -xf -
|
||||||
|
;;
|
||||||
|
"tar")
|
||||||
|
${remote[@]} pv -f ${file} | tar -xf -
|
||||||
|
;;
|
||||||
|
"tgz")
|
||||||
|
${remote[@]} pv -f ${file} | gzip -d | tar -xf -
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Change archive's filesystem time to match creation date.
|
||||||
|
# Usage: archive_touch [FILES]
|
||||||
|
function archive_touch() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=$(_ls_archive)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local data=($(_archive_parse "${target}"))
|
||||||
|
local date=${data[1]}
|
||||||
|
touch -t ${date} -- ${target}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse archive file name to get: name, date, hash and format.
|
||||||
|
# Usage: _archive_parse <FILENAME>
|
||||||
|
function _archive_parse() {
|
||||||
|
local input="${1}"
|
||||||
|
local name="${input%_*}"
|
||||||
|
local format="${input##*.}"
|
||||||
|
local data="${input##*_}"
|
||||||
|
data="${data%.*}"
|
||||||
|
local date="${data%%-*}"
|
||||||
|
local hash="${data##*-}"
|
||||||
|
|
||||||
|
# No extension if no dots.
|
||||||
|
[[ ${input} == *\.* ]] || format=""
|
||||||
|
|
||||||
|
echo "${name}"
|
||||||
|
echo "${date}"
|
||||||
|
echo "${hash}"
|
||||||
|
echo "${format}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete for archive_name function.
|
||||||
|
# First arg is the archives list, second one is selected archive's current name.
|
||||||
|
function _comp_archive_name() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
|
local cur="${COMP_WORDS[COMP_CWORD]}"
|
||||||
|
local prev="${COMP_WORDS[COMP_CWORD - 1]}"
|
||||||
|
local command="${COMP_WORDS[0]}"
|
||||||
|
|
||||||
|
if [[ ${prev} == "${command}" ]]; then
|
||||||
|
COMPREPLY=($(compgen -W "$(ls | grep -E ${_archive_pattern})" -- ${cur}))
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
local data=($(_archive_parse ${prev}))
|
||||||
|
local name="${data[0]}"
|
||||||
|
COMPREPLY=($(compgen -W "${name}" -- ${cur}))
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with archives in current dir.
|
||||||
|
function _comp_archive_grep() {
|
||||||
|
_autocomplete_grep ${_archive_pattern}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with fast archives in current dir.
|
||||||
|
function _comp_archive_grep_fast() {
|
||||||
|
_autocomplete_grep ${_archive_pattern_fast}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get date for a new archive.
|
||||||
|
function _archive_date() {
|
||||||
|
date +%Y%m%d%H%M
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get names of all archives.
|
||||||
|
function _archive_names() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local archives=($(_ls_archive))
|
||||||
|
local names=()
|
||||||
|
|
||||||
|
for archive in ${archives[@]}; do
|
||||||
|
local data=($(_archive_parse ${archive}))
|
||||||
|
names+=(${data[0]})
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove copies.
|
||||||
|
names=($(printf '%s\n' "${names[@]}" | sort -u))
|
||||||
|
|
||||||
|
printf '%s\n' "${names[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with names of all archives.
|
||||||
|
function _comp_archive_names() {
|
||||||
|
_autocomplete $(_archive_names)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if file is an archive.
|
||||||
|
function _is_archive() {
|
||||||
|
local target="${*}"
|
||||||
|
local out=$(echo "${target##*/}" | grep -E ${_archive_pattern})
|
||||||
|
|
||||||
|
[[ ${out} != "" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if file is a compressed archive.
|
||||||
|
function _is_compressed_archive() {
|
||||||
|
local out=$(echo "${*}" | grep -E ${_archive_pattern_compressed})
|
||||||
|
|
||||||
|
[[ ${out} != "" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# List all archives.
|
||||||
|
function _ls_archive() {
|
||||||
|
ls | grep -E ${_archive_pattern}
|
||||||
|
}
|
||||||
|
|
||||||
|
# List fast archives.
|
||||||
|
function _ls_archive_fast() {
|
||||||
|
ls | grep -E ${_archive_pattern_fast}
|
||||||
|
}
|
||||||
|
|
||||||
|
# List fast archives.
|
||||||
|
function _ls_archive_compressed() {
|
||||||
|
ls | grep -E ${_archive_pattern_compressed}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Filter input for archives only.
|
||||||
|
function _filter_archive() {
|
||||||
|
grep -E ${_archive_pattern}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _archive_memlimit() {
|
||||||
|
local mem_free=$(_mem_free)
|
||||||
|
local mem_limit=$((mem_free * 3 / 4))
|
||||||
|
|
||||||
|
echo "${mem_limit}MiB"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _archive_check() {
|
||||||
|
# Extract hash from name.
|
||||||
|
local data=($(_archive_parse ${target}))
|
||||||
|
local saved=${data[2]}
|
||||||
|
|
||||||
|
# Calculate actual hash.
|
||||||
|
local actual=$(pv ${target} | sha1sum | cut -d\ -f1)
|
||||||
|
|
||||||
|
# Compare hashes.
|
||||||
|
[[ ${actual} == "${saved}" ]] || _error "Archive check failed."
|
||||||
|
}
|
||||||
|
|
||||||
|
# complete -o filenames -F _comp_archive_grep archive_check unarchive archive_rm archive_touch
|
||||||
|
# complete -o filenames -F _comp_archive_grep_fast archive_xz
|
||||||
|
complete -o filenames -F _comp_archive_name archive_name
|
||||||
|
complete -o filenames -F _comp_archive_names archive_prune
|
|
@ -1,28 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Ask general AI.
|
|
||||||
# Usage: ask <QUERY>
|
|
||||||
function ask() {
|
|
||||||
curl http://localhost:11434/api/generate -d "{
|
|
||||||
\"model\":\"''${OLLAMA_MODEL}\",
|
|
||||||
\"raw\":true,
|
|
||||||
\"prompt\":\"''${*}\"
|
|
||||||
}" 2> /dev/null | parallel -j1 -- "printf '%s\n' {} | jq -r .response | sed -e 's/^$/\+\+\+/' | tr -d '\n' | sed -e 's/\+\+\+/\n/'"
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Specify ask model.
|
|
||||||
function ask_model() {
|
|
||||||
export OLLAMA_MODEL="''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _complete_ask_model() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local models=($(ollama list | sed -e "1d" | cut -f1))
|
|
||||||
_autocomplete ''${models[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _complete_ask_model ask_model
|
|
||||||
'';
|
|
||||||
}
|
|
23
home/program/bash/module/Ask.sh
Normal file
23
home/program/bash/module/Ask.sh
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# Ask general AI.
|
||||||
|
# Usage: ask <QUERY>
|
||||||
|
function ask() {
|
||||||
|
curl http://localhost:11434/api/generate -d "{
|
||||||
|
\"model\":\"${OLLAMA_MODEL}\",
|
||||||
|
\"raw\":true,
|
||||||
|
\"prompt\":\"${*}\"
|
||||||
|
}" 2>/dev/null | parallel -j1 -- "printf '%s\n' {} | jq -r .response | sed -e 's/^$/\+\+\+/' | tr -d '\n' | sed -e 's/\+\+\+/\n/'"
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Specify ask model.
|
||||||
|
function ask_model() {
|
||||||
|
export OLLAMA_MODEL="${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _complete_ask_model() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local models=($(ollama list | sed -e "1d" | cut -f1))
|
||||||
|
_autocomplete ${models[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _complete_ask_model ask_model
|
|
@ -1,44 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Bash autocomplete.
|
|
||||||
# There are also options like -o nospace. see man for more info.
|
|
||||||
# Usage: _foo() { _autocomplete "{foo,bar}" } ; complete -F _foo foo
|
|
||||||
function _autocomplete() {
|
|
||||||
local iter use cur
|
|
||||||
cur=''${COMP_WORDS[COMP_CWORD]}
|
|
||||||
use="''${@//\\ /___}"
|
|
||||||
for iter in $use; do
|
|
||||||
if [[ $iter =~ ^$cur ]]; then
|
|
||||||
COMPREPLY+=( $(printf "%q" "''${iter//___/ }") )
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete by grepping file names.
|
|
||||||
function _autocomplete_grep() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
COMPREPLY=()
|
|
||||||
|
|
||||||
local pattern="''${1}"
|
|
||||||
local candidates=$("$(ls | grep -E ''${pattern})")
|
|
||||||
_autocomplete ''${candidates}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete nested program.
|
|
||||||
function _autocomplete_nested() {
|
|
||||||
# local IFS=$'\n'
|
|
||||||
local cur prev words cword split i
|
|
||||||
_init_completion -s || return
|
|
||||||
|
|
||||||
for ((i = 1; i <= cword; i++)); do
|
|
||||||
if [[ ''${words[i]} != -* ]]; then
|
|
||||||
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
|
|
||||||
local root_command=''${words[i]}
|
|
||||||
_command_offset ''${i}
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
39
home/program/bash/module/Autocomplete.sh
Normal file
39
home/program/bash/module/Autocomplete.sh
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Bash autocomplete.
|
||||||
|
# There are also options like -o nospace. see man for more info.
|
||||||
|
# Usage: _foo() { _autocomplete "{foo,bar}" } ; complete -F _foo foo
|
||||||
|
function _autocomplete() {
|
||||||
|
local iter use cur
|
||||||
|
cur=${COMP_WORDS[COMP_CWORD]}
|
||||||
|
use="${@//\\ /___}"
|
||||||
|
for iter in $use; do
|
||||||
|
if [[ $iter =~ ^$cur ]]; then
|
||||||
|
COMPREPLY+=($(printf "%q" "${iter//___/ }"))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete by grepping file names.
|
||||||
|
function _autocomplete_grep() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
COMPREPLY=()
|
||||||
|
|
||||||
|
local pattern="${1}"
|
||||||
|
local candidates=$("$(ls | grep -E ${pattern})")
|
||||||
|
_autocomplete ${candidates}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete nested program.
|
||||||
|
function _autocomplete_nested() {
|
||||||
|
# local IFS=$'\n'
|
||||||
|
local cur prev words cword split i
|
||||||
|
_init_completion -s || return
|
||||||
|
|
||||||
|
for ((i = 1; i <= cword; i++)); do
|
||||||
|
if [[ ${words[i]} != -* ]]; then
|
||||||
|
local PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin
|
||||||
|
local root_command=${words[i]}
|
||||||
|
_command_offset ${i}
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Print current battery charge level in percents.
|
|
||||||
function battery_level() {
|
|
||||||
head -c -1 /sys/class/power_supply/BAT*/capacity
|
|
||||||
echo '%'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get battery's info.
|
|
||||||
function battery_info() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local battery=("$(upower --enumerate | grep battery_BAT)")
|
|
||||||
upower -i "''${battery[0]}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
12
home/program/bash/module/Battery.sh
Normal file
12
home/program/bash/module/Battery.sh
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# Print current battery charge level in percents.
|
||||||
|
function battery_level() {
|
||||||
|
head -c -1 /sys/class/power_supply/BAT*/capacity
|
||||||
|
echo '%'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get battery's info.
|
||||||
|
function battery_info() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local battery=("$(upower --enumerate | grep battery_BAT)")
|
||||||
|
upower -i "${battery[0]}"
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Extract all formats with binwalk.
|
|
||||||
# Use -M for recursive extract.
|
|
||||||
# Usage: binwalke <FILES>
|
|
||||||
function binwalke() {
|
|
||||||
binwalk --dd='.*' "$@"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
6
home/program/bash/module/Binwalk.sh
Normal file
6
home/program/bash/module/Binwalk.sh
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Extract all formats with binwalk.
|
||||||
|
# Use -M for recursive extract.
|
||||||
|
# Usage: binwalke <FILES>
|
||||||
|
function binwalke() {
|
||||||
|
binwalk --dd='.*' "$@"
|
||||||
|
}
|
|
@ -1,90 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Switch bottle.
|
|
||||||
# Usage: bt <NAME>
|
|
||||||
function bt() {
|
|
||||||
export SHELL_NAME="''${*}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Create new bottle.
|
|
||||||
# Usage: btc [ENV] [EXTRA]
|
|
||||||
function btc() {
|
|
||||||
local env="''${1}"
|
|
||||||
[[ "''${env}" = "" ]] && env="gaming"
|
|
||||||
bottles-cli new --bottle-name "''${SHELL_NAME}" --environment "''${env}" "''${@:2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run a file inside a bottle.
|
|
||||||
# Usage: btre <EXE> [EXTRA]
|
|
||||||
function btre() {
|
|
||||||
bottles-cli run -b "''${SHELL_NAME}" -e "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run a program inside a bottle.
|
|
||||||
# Usage: btr <NAME> [EXTRA]
|
|
||||||
function btr() {
|
|
||||||
bottles-cli run -b "''${SHELL_NAME}" -p "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List bottles.
|
|
||||||
function btl() {
|
|
||||||
bottles-cli list bottles 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# List programs in a bottle.
|
|
||||||
function btlp() {
|
|
||||||
bottles-cli programs -b "''${SHELL_NAME}" 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add a program to bottle.
|
|
||||||
# Usage: bta <NAME> <EXE> [EXTRA]
|
|
||||||
function bta() {
|
|
||||||
local name="''${1}"
|
|
||||||
local exe=$(realpath "''${2}")
|
|
||||||
if [[ "''${exe}" = "" ]]; then
|
|
||||||
help bta
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
bottles-cli add -b "''${SHELL_NAME}" -n "''${name}" -p "''${exe}" "''${@:3}" 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set bottle env var.
|
|
||||||
# Usage: bte <NAME=VALUE>
|
|
||||||
function bte() {
|
|
||||||
local env="''${1}"
|
|
||||||
if [[ "''${env}" = "" ]]; then
|
|
||||||
help bte
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
bottles-cli edit -b "''${SHELL_NAME}" --env-var "''${@}" 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Play bottle.
|
|
||||||
# Usage: btp <BOTTLE>
|
|
||||||
function btp() {
|
|
||||||
local bottle="''${1##*/}"
|
|
||||||
if [[ "''${bottle}" = "" ]]; then
|
|
||||||
help btp
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local program=$(bottles-cli programs -b "''${bottle}" 2> /dev/null | sed -n -e "s/^- //; 2p")
|
|
||||||
bottles-cli run -b "''${bottle}" -p "''${program}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _comp_bottles_list() {
|
|
||||||
_autocomplete $(bottles-cli list bottles 2> /dev/null | sed -e "1d; s/^- //")
|
|
||||||
}
|
|
||||||
|
|
||||||
function _comp_programs_list() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
_autocomplete $(bottles-cli programs -b "''${SHELL_NAME}" 2> /dev/null | sed -e "1d; s/^- //")
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _comp_bottles_list bt btp
|
|
||||||
complete -F _comp_programs_list btr
|
|
||||||
'';
|
|
||||||
}
|
|
85
home/program/bash/module/Bottle.sh
Normal file
85
home/program/bash/module/Bottle.sh
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
# Switch bottle.
|
||||||
|
# Usage: bt <NAME>
|
||||||
|
function bt() {
|
||||||
|
export SHELL_NAME="${*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create new bottle.
|
||||||
|
# Usage: btc [ENV] [EXTRA]
|
||||||
|
function btc() {
|
||||||
|
local env="${1}"
|
||||||
|
[[ ${env} == "" ]] && env="gaming"
|
||||||
|
bottles-cli new --bottle-name "${SHELL_NAME}" --environment "${env}" "${@:2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a file inside a bottle.
|
||||||
|
# Usage: btre <EXE> [EXTRA]
|
||||||
|
function btre() {
|
||||||
|
bottles-cli run -b "${SHELL_NAME}" -e "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a program inside a bottle.
|
||||||
|
# Usage: btr <NAME> [EXTRA]
|
||||||
|
function btr() {
|
||||||
|
bottles-cli run -b "${SHELL_NAME}" -p "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List bottles.
|
||||||
|
function btl() {
|
||||||
|
bottles-cli list bottles 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# List programs in a bottle.
|
||||||
|
function btlp() {
|
||||||
|
bottles-cli programs -b "${SHELL_NAME}" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add a program to bottle.
|
||||||
|
# Usage: bta <NAME> <EXE> [EXTRA]
|
||||||
|
function bta() {
|
||||||
|
local name="${1}"
|
||||||
|
local exe=$(realpath "${2}")
|
||||||
|
if [[ ${exe} == "" ]]; then
|
||||||
|
help bta
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
bottles-cli add -b "${SHELL_NAME}" -n "${name}" -p "${exe}" "${@:3}" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set bottle env var.
|
||||||
|
# Usage: bte <NAME=VALUE>
|
||||||
|
function bte() {
|
||||||
|
local env="${1}"
|
||||||
|
if [[ ${env} == "" ]]; then
|
||||||
|
help bte
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
bottles-cli edit -b "${SHELL_NAME}" --env-var "${@}" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Play bottle.
|
||||||
|
# Usage: btp <BOTTLE>
|
||||||
|
function btp() {
|
||||||
|
local bottle="${1##*/}"
|
||||||
|
if [[ ${bottle} == "" ]]; then
|
||||||
|
help btp
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local program=$(bottles-cli programs -b "${bottle}" 2>/dev/null | sed -n -e "s/^- //; 2p")
|
||||||
|
bottles-cli run -b "${bottle}" -p "${program}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _comp_bottles_list() {
|
||||||
|
_autocomplete $(bottles-cli list bottles 2>/dev/null | sed -e "1d; s/^- //")
|
||||||
|
}
|
||||||
|
|
||||||
|
function _comp_programs_list() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
_autocomplete $(bottles-cli programs -b "${SHELL_NAME}" 2>/dev/null | sed -e "1d; s/^- //")
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _comp_bottles_list bt btp
|
||||||
|
complete -F _comp_programs_list btr
|
|
@ -1,23 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Set display brightness to a minimum.
|
|
||||||
function brmin() {
|
|
||||||
light -S 0.01
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set display brightness to a maximum.
|
|
||||||
function brmax() {
|
|
||||||
light -S 100
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set display brightness in percent, 50% default.
|
|
||||||
# Usage: brset [LEVEL]
|
|
||||||
function brset() {
|
|
||||||
local level=''${1}
|
|
||||||
[[ "''${level}" = "" ]] && level=50
|
|
||||||
|
|
||||||
light -S ''${level}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
18
home/program/bash/module/Brightness.sh
Normal file
18
home/program/bash/module/Brightness.sh
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Set display brightness to a minimum.
|
||||||
|
function brmin() {
|
||||||
|
light -S 0.01
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set display brightness to a maximum.
|
||||||
|
function brmax() {
|
||||||
|
light -S 100
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set display brightness in percent, 50% default.
|
||||||
|
# Usage: brset [LEVEL]
|
||||||
|
function brset() {
|
||||||
|
local level=${1}
|
||||||
|
[[ ${level} == "" ]] && level=50
|
||||||
|
|
||||||
|
light -S ${level}
|
||||||
|
}
|
|
@ -1,74 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# CD (back to) directory.
|
|
||||||
# Goes to the exact-match dir first. If no exact match found, it finds first directory that contains the input (case-insensitive).
|
|
||||||
# Usage: cdd <DIR>
|
|
||||||
function cdd() {
|
|
||||||
local target="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${target}" = "" ]]; then
|
|
||||||
help cdd
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local array=($(_cdd_directories))
|
|
||||||
local result
|
|
||||||
|
|
||||||
# Check for exact match ELSE look for containing.
|
|
||||||
if _contains ''${target} ''${array[@]}; then
|
|
||||||
local current="''${PWD%/*}"
|
|
||||||
result="''${current%\/$target\/*}/''${target}"
|
|
||||||
else
|
|
||||||
# Make search case-insensitive.
|
|
||||||
shopt -s nocasematch
|
|
||||||
|
|
||||||
# Find dir name that contains input.
|
|
||||||
local found=1
|
|
||||||
for (( idx=''${#array[@]}-1 ; idx>=0 ; idx-- )); do
|
|
||||||
dir="''${array[idx]}"
|
|
||||||
[[ "''${dir}" =~ "''${target}" ]] && found=0
|
|
||||||
[[ ''${found} = 0 ]] && result="/''${dir}''${result}"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Clean-up???
|
|
||||||
shopt -u nocasematch
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Go there!
|
|
||||||
if [[ "''${result}" != "" ]]; then
|
|
||||||
echo "''${result}"
|
|
||||||
cd "''${result}"
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# CLI cd. Opens CLI file manager.
|
|
||||||
function ccd() {
|
|
||||||
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
|
|
||||||
yazi "$@" --cwd-file="$tmp"
|
|
||||||
if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
|
|
||||||
cd -- "$cwd"
|
|
||||||
fi
|
|
||||||
rm -f -- "$tmp"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get list of all parent dirs.
|
|
||||||
function _cdd_directories() {
|
|
||||||
local array
|
|
||||||
IFS='/' read -r -a array <<< "''${PWD}"
|
|
||||||
array=("''${array[@]:1}")
|
|
||||||
unset array[-1]
|
|
||||||
printf "%s\n" "''${array[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _comp_cdd() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local dirs=($(_cdd_directories))
|
|
||||||
_autocomplete ''${dirs[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -o nosort -o filenames -F _comp_cdd cdd
|
|
||||||
'';
|
|
||||||
}
|
|
69
home/program/bash/module/Cd.sh
Normal file
69
home/program/bash/module/Cd.sh
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
# CD (back to) directory.
|
||||||
|
# Goes to the exact-match dir first. If no exact match found, it finds first directory that contains the input (case-insensitive).
|
||||||
|
# Usage: cdd <DIR>
|
||||||
|
function cdd() {
|
||||||
|
local target="${1}"
|
||||||
|
|
||||||
|
if [[ ${target} == "" ]]; then
|
||||||
|
help cdd
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local array=($(_cdd_directories))
|
||||||
|
local result
|
||||||
|
|
||||||
|
# Check for exact match ELSE look for containing.
|
||||||
|
if _contains ${target} ${array[@]}; then
|
||||||
|
local current="${PWD%/*}"
|
||||||
|
result="${current%\/$target\/*}/${target}"
|
||||||
|
else
|
||||||
|
# Make search case-insensitive.
|
||||||
|
shopt -s nocasematch
|
||||||
|
|
||||||
|
# Find dir name that contains input.
|
||||||
|
local found=1
|
||||||
|
for ((idx = ${#array[@]} - 1; idx >= 0; idx--)); do
|
||||||
|
dir="${array[idx]}"
|
||||||
|
[[ ${dir} =~ ${target} ]] && found=0
|
||||||
|
[[ ${found} == 0 ]] && result="/${dir}${result}"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Clean-up???
|
||||||
|
shopt -u nocasematch
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Go there!
|
||||||
|
if [[ ${result} != "" ]]; then
|
||||||
|
echo "${result}"
|
||||||
|
cd "${result}"
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# CLI cd. Opens CLI file manager.
|
||||||
|
function ccd() {
|
||||||
|
local tmp="$(mktemp -t "yazi-cwd.XXXXXX")"
|
||||||
|
yazi "$@" --cwd-file="$tmp"
|
||||||
|
if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
|
||||||
|
cd -- "$cwd"
|
||||||
|
fi
|
||||||
|
rm -f -- "$tmp"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get list of all parent dirs.
|
||||||
|
function _cdd_directories() {
|
||||||
|
local array
|
||||||
|
IFS='/' read -r -a array <<<"${PWD}"
|
||||||
|
array=("${array[@]:1}")
|
||||||
|
unset array[-1]
|
||||||
|
printf "%s\n" "${array[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _comp_cdd() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local dirs=($(_cdd_directories))
|
||||||
|
_autocomplete ${dirs[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -o nosort -o filenames -F _comp_cdd cdd
|
|
@ -1,29 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Collection of available CLI colors.
|
|
||||||
# They may differ depending on the terminal used.
|
|
||||||
# Colors with 'b' prefix are bold colors.
|
|
||||||
|
|
||||||
export color_default="\033[0m"
|
|
||||||
export color_blue="\033[0;34m"
|
|
||||||
export color_bblue="\033[1;34m"
|
|
||||||
export color_cyan="\033[0;36m"
|
|
||||||
export color_bcyan="\033[1;36m"
|
|
||||||
export color_green="\033[0;32m"
|
|
||||||
export color_bgreen="\033[1;32m"
|
|
||||||
export color_purple="\033[0;35m"
|
|
||||||
export color_bpurple="\033[1;35m"
|
|
||||||
export color_red="\033[0;31m"
|
|
||||||
export color_bred="\033[1;31m"
|
|
||||||
export color_white="\033[0;37m"
|
|
||||||
export color_bwhite="\033[1;37m"
|
|
||||||
export color_yellow="\033[0;33m"
|
|
||||||
export color_byellow="\033[1;33m"
|
|
||||||
|
|
||||||
# Print all available colors with their names colored in corresponding color.
|
|
||||||
function color_test() {
|
|
||||||
echo -e "''${color_default}color_default\n''${color_blue}color_blue\n''${color_bblue}color_bblue\n''${color_cyan}color_cyan\n''${color_bcyan}color_bcyan\n''${color_green}color_green\n''${color_bgreen}color_bgreen\n''${color_purple}color_purple\n''${color_bpurple}color_bpurple\n''${color_red}color_red\n''${color_bred}color_bred\n''${color_white}color_white\n''${color_bwhite}color_bwhite\n''${color_yellow}color_yellow\n''${color_byellow}color_byellow"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
24
home/program/bash/module/Color.sh
Normal file
24
home/program/bash/module/Color.sh
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# Collection of available CLI colors.
|
||||||
|
# They may differ depending on the terminal used.
|
||||||
|
# Colors with 'b' prefix are bold colors.
|
||||||
|
|
||||||
|
export color_default="\033[0m"
|
||||||
|
export color_blue="\033[0;34m"
|
||||||
|
export color_bblue="\033[1;34m"
|
||||||
|
export color_cyan="\033[0;36m"
|
||||||
|
export color_bcyan="\033[1;36m"
|
||||||
|
export color_green="\033[0;32m"
|
||||||
|
export color_bgreen="\033[1;32m"
|
||||||
|
export color_purple="\033[0;35m"
|
||||||
|
export color_bpurple="\033[1;35m"
|
||||||
|
export color_red="\033[0;31m"
|
||||||
|
export color_bred="\033[1;31m"
|
||||||
|
export color_white="\033[0;37m"
|
||||||
|
export color_bwhite="\033[1;37m"
|
||||||
|
export color_yellow="\033[0;33m"
|
||||||
|
export color_byellow="\033[1;33m"
|
||||||
|
|
||||||
|
# Print all available colors with their names colored in corresponding color.
|
||||||
|
function color_test() {
|
||||||
|
echo -e "${color_default}color_default\n${color_blue}color_blue\n${color_bblue}color_bblue\n${color_cyan}color_cyan\n${color_bcyan}color_bcyan\n${color_green}color_green\n${color_bgreen}color_bgreen\n${color_purple}color_purple\n${color_bpurple}color_bpurple\n${color_red}color_red\n${color_bred}color_bred\n${color_white}color_white\n${color_bwhite}color_bwhite\n${color_yellow}color_yellow\n${color_byellow}color_byellow"
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Copy stdin to system clipboard. *Example:* `echo hi \| copy`.
|
|
||||||
function copy() {
|
|
||||||
wl-copy
|
|
||||||
}
|
|
||||||
|
|
||||||
# Paste system clipboard to stdout. *Example:* `paste > file.txt`.
|
|
||||||
function paste() {
|
|
||||||
wl-paste
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
9
home/program/bash/module/Copypaste.sh
Normal file
9
home/program/bash/module/Copypaste.sh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Copy stdin to system clipboard. *Example:* `echo hi \| copy`.
|
||||||
|
function copy() {
|
||||||
|
wl-copy
|
||||||
|
}
|
||||||
|
|
||||||
|
# Paste system clipboard to stdout. *Example:* `paste > file.txt`.
|
||||||
|
function paste() {
|
||||||
|
wl-paste
|
||||||
|
}
|
|
@ -1,55 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Replaces default cp with rsync.
|
|
||||||
# Usage: rcp <FROM> <TO>
|
|
||||||
function rcp() {
|
|
||||||
rsync -ahP --chmod=u+w "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Replaces default cp with rsync.
|
|
||||||
# Only compare file size.
|
|
||||||
# Usage: rcp_fast <FROM> <TO>
|
|
||||||
function rcp_fast() {
|
|
||||||
rsync -ahP --chmod=u+w --size-only "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Replaces default cp with rsync.
|
|
||||||
# Compare file hashes.
|
|
||||||
# Usage: rcp_hash <FROM> <TO>
|
|
||||||
function rcp_hash() {
|
|
||||||
rsync -ahP --chmod=u+w --checksum "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy and also merge all changes (delete dst files that do not exist in src).
|
|
||||||
# Usage: rcp_merge <FROM> <TO>
|
|
||||||
function rcp_merge() {
|
|
||||||
rsync -ahP --chmod=u+w --delete "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy and also merge all changes FAST (delete dst files that do not exist in src, only compare size).
|
|
||||||
# Usage: rcp_merge_fast <FROM> <TO>
|
|
||||||
function rcp_merge_fast() {
|
|
||||||
rsync -ahP --chmod=u+w --delete --size-only "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy and also merge all changes BY CHECKSUM (delete dst files that do not exist in src, compare hashes).
|
|
||||||
# Usage: rcp_merge_hash <FROM> <TO>
|
|
||||||
function rcp_merge_hash() {
|
|
||||||
rsync -ahP --chmod=u+w --delete --checksum "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print output of cp_merge without writing anything.
|
|
||||||
# Usage: rcp_test <FROM> <TO>
|
|
||||||
function rcp_test() {
|
|
||||||
rsync -ahP --chmod=u+w --delete -n "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy by creating hardlinks.
|
|
||||||
# Works for directories, too.
|
|
||||||
# Usage: cp_link <FROM> <TO>
|
|
||||||
function cp_link() {
|
|
||||||
/usr/bin/env cp -lr "''${@}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
50
home/program/bash/module/Cp.sh
Normal file
50
home/program/bash/module/Cp.sh
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
# Replaces default cp with rsync.
|
||||||
|
# Usage: rcp <FROM> <TO>
|
||||||
|
function rcp() {
|
||||||
|
rsync -ahP --chmod=u+w "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replaces default cp with rsync.
|
||||||
|
# Only compare file size.
|
||||||
|
# Usage: rcp_fast <FROM> <TO>
|
||||||
|
function rcp_fast() {
|
||||||
|
rsync -ahP --chmod=u+w --size-only "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replaces default cp with rsync.
|
||||||
|
# Compare file hashes.
|
||||||
|
# Usage: rcp_hash <FROM> <TO>
|
||||||
|
function rcp_hash() {
|
||||||
|
rsync -ahP --chmod=u+w --checksum "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy and also merge all changes (delete dst files that do not exist in src).
|
||||||
|
# Usage: rcp_merge <FROM> <TO>
|
||||||
|
function rcp_merge() {
|
||||||
|
rsync -ahP --chmod=u+w --delete "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy and also merge all changes FAST (delete dst files that do not exist in src, only compare size).
|
||||||
|
# Usage: rcp_merge_fast <FROM> <TO>
|
||||||
|
function rcp_merge_fast() {
|
||||||
|
rsync -ahP --chmod=u+w --delete --size-only "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy and also merge all changes BY CHECKSUM (delete dst files that do not exist in src, compare hashes).
|
||||||
|
# Usage: rcp_merge_hash <FROM> <TO>
|
||||||
|
function rcp_merge_hash() {
|
||||||
|
rsync -ahP --chmod=u+w --delete --checksum "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print output of cp_merge without writing anything.
|
||||||
|
# Usage: rcp_test <FROM> <TO>
|
||||||
|
function rcp_test() {
|
||||||
|
rsync -ahP --chmod=u+w --delete -n "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy by creating hardlinks.
|
||||||
|
# Works for directories, too.
|
||||||
|
# Usage: cp_link <FROM> <TO>
|
||||||
|
function cp_link() {
|
||||||
|
/usr/bin/env cp -lr "${@}"
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Download a file from the web.
|
|
||||||
# Usaee: dl <FILE> [FILES...]
|
|
||||||
function dl() {
|
|
||||||
wcurl --curl-options='--http2 --continue-at -' -- ''${@}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
5
home/program/bash/module/Curl.sh
Normal file
5
home/program/bash/module/Curl.sh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Download a file from the web.
|
||||||
|
# Usaee: dl <FILE> [FILES...]
|
||||||
|
function dl() {
|
||||||
|
wcurl --curl-options='--http2 --continue-at -' -- ${@}
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Print today date in yyyyMMdd format.
|
|
||||||
function today() {
|
|
||||||
date +%Y%m%d
|
|
||||||
}
|
|
||||||
|
|
||||||
# Current day of week number.
|
|
||||||
function dow() {
|
|
||||||
date +%u
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
9
home/program/bash/module/Date.sh
Normal file
9
home/program/bash/module/Date.sh
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Print today date in yyyyMMdd format.
|
||||||
|
function today() {
|
||||||
|
date +%Y%m%d
|
||||||
|
}
|
||||||
|
|
||||||
|
# Current day of week number.
|
||||||
|
function dow() {
|
||||||
|
date +%u
|
||||||
|
}
|
|
@ -1,73 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Show only physical drives info.
|
|
||||||
function pdf() {
|
|
||||||
df --si | sed -e '1p' -e '/^\/dev\//!d'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show total size in SI.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: tdu [DIRS]
|
|
||||||
function tdu() {
|
|
||||||
du -sh --si "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Unlock encrypted disk file.
|
|
||||||
# Usage: funlock <FILE>
|
|
||||||
function funlock() {
|
|
||||||
local file="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${file}" = "" ]]; then
|
|
||||||
help funlock
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local name=$(parse_alnum "''${file##*/}")
|
|
||||||
|
|
||||||
local loop=$(udisksctl loop-setup --no-user-interaction --file "''${file}")
|
|
||||||
loop="''${loop##* }"; loop="''${loop%.}"
|
|
||||||
|
|
||||||
local decrypted=$(udisksctl unlock --block-device "''${loop}")
|
|
||||||
decrypted="''${decrypted##* }"; decrypted="''${decrypted%.}"
|
|
||||||
|
|
||||||
local mount=$(udisksctl mount --no-user-interaction --block-device "''${decrypted}")
|
|
||||||
mount="''${mount#* at }"
|
|
||||||
|
|
||||||
ya pub dds-cd --str "''${mount}" 2> /dev/null
|
|
||||||
cd "''${mount}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Mount file.
|
|
||||||
# Usage: fmount <FILE>
|
|
||||||
function fmount() {
|
|
||||||
local file="''${1}"
|
|
||||||
if [[ "''${file}" = "" ]]; then
|
|
||||||
help fmount
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local loop=$(udisksctl loop-setup --no-user-interaction --file "''${file}")
|
|
||||||
loop="''${loop##* }"; loop="''${loop%.}"
|
|
||||||
|
|
||||||
local mount=$(udisksctl mount --no-user-interaction --block-device "''${loop}")
|
|
||||||
mount="''${mount#* at }"
|
|
||||||
|
|
||||||
ya pub dds-cd --str "''${mount}" 2> /dev/null
|
|
||||||
cd "''${mount}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Unmount file.
|
|
||||||
# Usage: fumount <LOOPDEVICE>
|
|
||||||
function fumount() {
|
|
||||||
local loop="''${1}"
|
|
||||||
if [[ "''${loop}" = "" ]]; then
|
|
||||||
help fumount
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
udisksctl unmount --no-user-interaction --block-device "''${loop}"
|
|
||||||
udisksctl loop-delete --no-user-interaction --block-device "''${loop}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
71
home/program/bash/module/Disk.sh
Normal file
71
home/program/bash/module/Disk.sh
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
# Show only physical drives info.
|
||||||
|
function pdf() {
|
||||||
|
df --si | sed -e '1p' -e '/^\/dev\//!d'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show total size in SI.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: tdu [DIRS]
|
||||||
|
function tdu() {
|
||||||
|
du -sh --si "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unlock encrypted disk file.
|
||||||
|
# Usage: funlock <FILE>
|
||||||
|
function funlock() {
|
||||||
|
local file="${1}"
|
||||||
|
|
||||||
|
if [[ ${file} == "" ]]; then
|
||||||
|
help funlock
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local name=$(parse_alnum "${file##*/}")
|
||||||
|
|
||||||
|
local loop=$(udisksctl loop-setup --no-user-interaction --file "${file}")
|
||||||
|
loop="${loop##* }"
|
||||||
|
loop="${loop%.}"
|
||||||
|
|
||||||
|
local decrypted=$(udisksctl unlock --block-device "${loop}")
|
||||||
|
decrypted="${decrypted##* }"
|
||||||
|
decrypted="${decrypted%.}"
|
||||||
|
|
||||||
|
local mount=$(udisksctl mount --no-user-interaction --block-device "${decrypted}")
|
||||||
|
mount="${mount#* at }"
|
||||||
|
|
||||||
|
ya pub dds-cd --str "${mount}" 2>/dev/null
|
||||||
|
cd "${mount}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mount file.
|
||||||
|
# Usage: fmount <FILE>
|
||||||
|
function fmount() {
|
||||||
|
local file="${1}"
|
||||||
|
if [[ ${file} == "" ]]; then
|
||||||
|
help fmount
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local loop=$(udisksctl loop-setup --no-user-interaction --file "${file}")
|
||||||
|
loop="${loop##* }"
|
||||||
|
loop="${loop%.}"
|
||||||
|
|
||||||
|
local mount=$(udisksctl mount --no-user-interaction --block-device "${loop}")
|
||||||
|
mount="${mount#* at }"
|
||||||
|
|
||||||
|
ya pub dds-cd --str "${mount}" 2>/dev/null
|
||||||
|
cd "${mount}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unmount file.
|
||||||
|
# Usage: fumount <LOOPDEVICE>
|
||||||
|
function fumount() {
|
||||||
|
local loop="${1}"
|
||||||
|
if [[ ${loop} == "" ]]; then
|
||||||
|
help fumount
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
udisksctl unmount --no-user-interaction --block-device "${loop}"
|
||||||
|
udisksctl loop-delete --no-user-interaction --block-device "${loop}"
|
||||||
|
}
|
|
@ -1,100 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Show container's volumes.
|
|
||||||
# Usage: docker_volumes <CONTAINER>
|
|
||||||
function docker_volumes() {
|
|
||||||
docker inspect -f '{{ .Mounts }}' "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if any container exited.
|
|
||||||
function docker_health() {
|
|
||||||
docker ps -a | grep Exited
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find out container's IP address.
|
|
||||||
# Usage: docker_ip <CONTAINER>
|
|
||||||
function docker_ip() {
|
|
||||||
docker inspect -f '\'''{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'\' "''${1}" | sed "s/^.//" | sed "s/.$//"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update all docker images.
|
|
||||||
function docker_update() {
|
|
||||||
docker images --format "{{.Repository}}:{{.Tag}}" | xargs -L1 docker pull
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose shortcut.
|
|
||||||
function dc() {
|
|
||||||
docker compose "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose up.
|
|
||||||
# Usage: dcu [SERVICES]
|
|
||||||
function dcu() {
|
|
||||||
docker compose up -d "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose down.
|
|
||||||
# Usage: dcd [SERVICES]
|
|
||||||
function dcd() {
|
|
||||||
docker compose down "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose pull.
|
|
||||||
# Usage: dcp [SERVICES]
|
|
||||||
function dcp() {
|
|
||||||
docker compose pull "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose logs.
|
|
||||||
# Usage: dcl [SERVICES]
|
|
||||||
function dcl() {
|
|
||||||
docker compose logs -f "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose restart.
|
|
||||||
# Usage: dcr [SERVICES]
|
|
||||||
function dcr() {
|
|
||||||
docker compose restart "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose stop.
|
|
||||||
# Usage: dcs [SERVICES]
|
|
||||||
function dcs() {
|
|
||||||
docker compose stop "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose down & up specified services.
|
|
||||||
# Usage: dcdu [SERVICES]
|
|
||||||
function dcdu() {
|
|
||||||
dcd "''${@}"
|
|
||||||
dcu "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose pull & up specified services.
|
|
||||||
# Usage: dcpu [SERVICES]
|
|
||||||
function dcpu() {
|
|
||||||
dcp "''${@}"
|
|
||||||
dcu "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Docker compose up & attach to logs for specified services.
|
|
||||||
# Usage: dcul [SERVICES]
|
|
||||||
function dcul() {
|
|
||||||
dcu "''${@}" && dcl "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with available services.
|
|
||||||
function _dc_services() {
|
|
||||||
_autocomplete "$(docker compose config --services 2> /dev/null)"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with available container names.
|
|
||||||
function _dc_containers() {
|
|
||||||
_autocomplete "$(docker ps --format "\""{{.Names}}"\"")"
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _dc_services dcu dcd dcp dcl dcul dcdu dcr dcs dcpu
|
|
||||||
complete -F _dc_containers docker_volumes docker_ip
|
|
||||||
'';
|
|
||||||
}
|
|
95
home/program/bash/module/Docker.sh
Normal file
95
home/program/bash/module/Docker.sh
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# Show container's volumes.
|
||||||
|
# Usage: docker_volumes <CONTAINER>
|
||||||
|
function docker_volumes() {
|
||||||
|
docker inspect -f '{{ .Mounts }}' "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if any container exited.
|
||||||
|
function docker_health() {
|
||||||
|
docker ps -a | grep Exited
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find out container's IP address.
|
||||||
|
# Usage: docker_ip <CONTAINER>
|
||||||
|
function docker_ip() {
|
||||||
|
docker inspect -f '\'{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'\' "${1}" | sed "s/^.//" | sed "s/.$//"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update all docker images.
|
||||||
|
function docker_update() {
|
||||||
|
docker images --format "{{.Repository}}:{{.Tag}}" | xargs -L1 docker pull
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose shortcut.
|
||||||
|
function dc() {
|
||||||
|
docker compose "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose up.
|
||||||
|
# Usage: dcu [SERVICES]
|
||||||
|
function dcu() {
|
||||||
|
docker compose up -d "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose down.
|
||||||
|
# Usage: dcd [SERVICES]
|
||||||
|
function dcd() {
|
||||||
|
docker compose down "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose pull.
|
||||||
|
# Usage: dcp [SERVICES]
|
||||||
|
function dcp() {
|
||||||
|
docker compose pull "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose logs.
|
||||||
|
# Usage: dcl [SERVICES]
|
||||||
|
function dcl() {
|
||||||
|
docker compose logs -f "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose restart.
|
||||||
|
# Usage: dcr [SERVICES]
|
||||||
|
function dcr() {
|
||||||
|
docker compose restart "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose stop.
|
||||||
|
# Usage: dcs [SERVICES]
|
||||||
|
function dcs() {
|
||||||
|
docker compose stop "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose down & up specified services.
|
||||||
|
# Usage: dcdu [SERVICES]
|
||||||
|
function dcdu() {
|
||||||
|
dcd "${@}"
|
||||||
|
dcu "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose pull & up specified services.
|
||||||
|
# Usage: dcpu [SERVICES]
|
||||||
|
function dcpu() {
|
||||||
|
dcp "${@}"
|
||||||
|
dcu "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Docker compose up & attach to logs for specified services.
|
||||||
|
# Usage: dcul [SERVICES]
|
||||||
|
function dcul() {
|
||||||
|
dcu "${@}" && dcl "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with available services.
|
||||||
|
function _dc_services() {
|
||||||
|
_autocomplete "$(docker compose config --services 2>/dev/null)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with available container names.
|
||||||
|
function _dc_containers() {
|
||||||
|
_autocomplete "$(docker ps --format '"'{{.Names}}"\"")"
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _dc_services dcu dcd dcp dcl dcul dcdu dcr dcs dcpu
|
||||||
|
complete -F _dc_containers docker_volumes docker_ip
|
|
@ -1,44 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Burn specified iso file to DVD.
|
|
||||||
# Usage: dvd_burn_iso <FILE.iso>
|
|
||||||
function dvd_burn_iso() {
|
|
||||||
local iso="''${1}"
|
|
||||||
if [[ "''${iso}" = "" ]]; then
|
|
||||||
help dvd_burn_iso
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
growisofs -dvd-compat -speed=8 -use-the-force-luke=tty -Z /dev/sr0="''${iso}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Burn specified iso file to CD.
|
|
||||||
# Usage: cd_burn_iso <FILE.iso>
|
|
||||||
function cd_burn_iso() {
|
|
||||||
local iso="''${1}"
|
|
||||||
if [[ "''${iso}" = "" ]]; then
|
|
||||||
help cd_burn_iso
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
wodim speed=8 -tao dev=/dev/sr0 "''${iso}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Burn specified audio files to CD.
|
|
||||||
# Usage: cd_burn_audio <FILES.wav>
|
|
||||||
function cd_burn_audio() {
|
|
||||||
if [[ "''${*}" = "" ]]; then
|
|
||||||
help cd_burn_audio
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
cdrecord -v dev=/dev/sr0 speed=8 -audio -pad "''${*}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Spawn Nix shell with required tools.
|
|
||||||
function dvd_shell() {
|
|
||||||
SHELL_NAME="dvd" tmpshell dvdplusrwtools cdrkit
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
39
home/program/bash/module/Dvd.sh
Normal file
39
home/program/bash/module/Dvd.sh
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Burn specified iso file to DVD.
|
||||||
|
# Usage: dvd_burn_iso <FILE.iso>
|
||||||
|
function dvd_burn_iso() {
|
||||||
|
local iso="${1}"
|
||||||
|
if [[ ${iso} == "" ]]; then
|
||||||
|
help dvd_burn_iso
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
growisofs -dvd-compat -speed=8 -use-the-force-luke=tty -Z /dev/sr0="${iso}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Burn specified iso file to CD.
|
||||||
|
# Usage: cd_burn_iso <FILE.iso>
|
||||||
|
function cd_burn_iso() {
|
||||||
|
local iso="${1}"
|
||||||
|
if [[ ${iso} == "" ]]; then
|
||||||
|
help cd_burn_iso
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
wodim speed=8 -tao dev=/dev/sr0 "${iso}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Burn specified audio files to CD.
|
||||||
|
# Usage: cd_burn_audio <FILES.wav>
|
||||||
|
function cd_burn_audio() {
|
||||||
|
if [[ ${*} == "" ]]; then
|
||||||
|
help cd_burn_audio
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cdrecord -v dev=/dev/sr0 speed=8 -audio -pad "${*}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Spawn Nix shell with required tools.
|
||||||
|
function dvd_shell() {
|
||||||
|
SHELL_NAME="dvd" tmpshell dvdplusrwtools cdrkit
|
||||||
|
}
|
|
@ -1,113 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Mux audio into containers. File names in sound and current dirrectories must match.
|
|
||||||
# Usage: ffmpeg_mux_audio <SOUND> <OUTPUT DIR>
|
|
||||||
function ffmpeg_mux_audio() {
|
|
||||||
if [[ "''${1}" = "" ]]; then
|
|
||||||
help ffmpeg_mux_audio
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
for file in *; do ffmpeg -i "$file" -i "$1"/"$file" -c copy -map 0:v:0 -map 1:a:0 -shortest "$2"/"$file"; done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Mux cover into music file.
|
|
||||||
# Usage: ffmpeg_mux_cover <FORMAT> <COVER>
|
|
||||||
function ffmpeg_mux_cover() {
|
|
||||||
if [[ "''${1}" = "" ]]; then
|
|
||||||
help ffmpeg_mux_cover
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local format="''${1}"
|
|
||||||
local cover="''${2}"
|
|
||||||
|
|
||||||
mkdir out
|
|
||||||
|
|
||||||
case "''${format}" in
|
|
||||||
# "mka"|"mkv")
|
|
||||||
# for file in *.''${format}; do
|
|
||||||
# ffmpeg -i "''${file}" -attach "''${cover}" -map 0 -c copy -metadata:s:t mimetype="image/''${cover##*.}" -metadata:s:t:0 filename="cover.''${cover##*.}" "./out/''${file}" || return 1
|
|
||||||
# done
|
|
||||||
# ;;
|
|
||||||
*)
|
|
||||||
for file in *.''${format}; do
|
|
||||||
# ffmpeg -i "''${file}" -i "''${cover}" -map 0 -map 0:-v? -map 1 -codec copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -disposition:v attached_pic ./out/"''${file}" || return 1
|
|
||||||
ffmpeg -i "''${file}" -i "''${cover}" -map 0 -map 1 -codec copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -disposition:v attached_pic ./out/"''${file}" || return 1
|
|
||||||
done
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
mv out/* .
|
|
||||||
rm -d out/ && rm "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Generate music metadata from directory structure.
|
|
||||||
# Top dir is the Artist name like this: `The_Beatles`.
|
|
||||||
# Next are albums like this: `2010_My_love`.
|
|
||||||
# Inside are songs like this: `01_sample.flac`.
|
|
||||||
# Usage: ffmpeg_music_meta <FORMAT>
|
|
||||||
function ffmpeg_music_meta() {
|
|
||||||
if [[ "''${1}" = "" ]]; then
|
|
||||||
help ffmpeg_music_meta
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local format="''${1}"
|
|
||||||
|
|
||||||
ls *.''${format} &> /dev/null || return 1
|
|
||||||
|
|
||||||
local artist="''${PWD%/*}"; artist="''${artist##*/}"; artist="''${artist//_/ }"
|
|
||||||
local album="''${PWD##*/}"; album="''${album#*_}"; album="''${album//_/ }"
|
|
||||||
local year="''${PWD##*/}"; year="''${year%%_*}"
|
|
||||||
# local total=$(ls *.''${format} | wc -l)
|
|
||||||
|
|
||||||
mkdir out
|
|
||||||
|
|
||||||
for file in *.''${format}; do
|
|
||||||
local track="''${file%%_*}"; track=$((10#''${track})); [[ "''${track}" = "" ]] && track=0
|
|
||||||
local title="''${file#*_}"; title="''${title%.*}"; title="''${title//_/ }"
|
|
||||||
|
|
||||||
# echo "''${artist}; ''${album}; ''${year}; ''${track}; ''${title}"
|
|
||||||
# TODO: make it format-specific.
|
|
||||||
ffmpeg -i "''${file}" -map 0 -c copy -metadata "artists=" -metadata "artist=''${artist}" -metadata "album_artist=''${artist}" -metadata "album=''${album}" -metadata "date=''${year}" -metadata "year=''${year}" -metadata "date_released=''${year}" -metadata "track=''${track}" -metadata "part_number=''${track}" -metadata "title=''${title}" ./out/"''${file}" || return 1
|
|
||||||
done
|
|
||||||
|
|
||||||
mv out/* .
|
|
||||||
rm -d out/
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rotate the video clock-wise.
|
|
||||||
# Usage: ffmpeg_rotate <ANGLE> <TARGET>
|
|
||||||
function ffmpeg_rotate() {
|
|
||||||
if [[ "''${2}" = "" ]]; then
|
|
||||||
help ffmpeg_rotate
|
|
||||||
fi
|
|
||||||
|
|
||||||
local angle="''${1}"
|
|
||||||
local target="''${2}"
|
|
||||||
|
|
||||||
ffmpeg -display_rotation ''${angle} -i ''${target} -c copy _''${target} && mv _''${target} ''${target} || rm _''${target}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get video FPS.
|
|
||||||
function _ffprobe_fps() {
|
|
||||||
local fps=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "''${1}")
|
|
||||||
[[ "''${fps}" = "" ]] && fps=30 || fps=$((fps))
|
|
||||||
echo "''${fps}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get recommended keyframe interval for a file.
|
|
||||||
function _ffprobe_keyint() {
|
|
||||||
local fps=$(_ffprobe_fps "''${1}")
|
|
||||||
echo $((fps*5))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get audio bitrage. 128 by default.
|
|
||||||
function _ffprobe_ba() {
|
|
||||||
local ba=$(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "''${1}")
|
|
||||||
[[ "''${ba}" != "N/A" ]] && echo $((ba/1024)) || echo 128
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
117
home/program/bash/module/Ffmpeg.sh
Normal file
117
home/program/bash/module/Ffmpeg.sh
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# Mux audio into containers. File names in sound and current dirrectories must match.
|
||||||
|
# Usage: ffmpeg_mux_audio <SOUND> <OUTPUT DIR>
|
||||||
|
function ffmpeg_mux_audio() {
|
||||||
|
if [[ ${1} == "" ]]; then
|
||||||
|
help ffmpeg_mux_audio
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
for file in *; do ffmpeg -i "$file" -i "$1"/"$file" -c copy -map 0:v:0 -map 1:a:0 -shortest "$2"/"$file"; done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Mux cover into music file.
|
||||||
|
# Usage: ffmpeg_mux_cover <FORMAT> <COVER>
|
||||||
|
function ffmpeg_mux_cover() {
|
||||||
|
if [[ ${1} == "" ]]; then
|
||||||
|
help ffmpeg_mux_cover
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local format="${1}"
|
||||||
|
local cover="${2}"
|
||||||
|
|
||||||
|
mkdir out
|
||||||
|
|
||||||
|
case "${format}" in
|
||||||
|
# "mka"|"mkv")
|
||||||
|
# for file in *.${format}; do
|
||||||
|
# ffmpeg -i "${file}" -attach "${cover}" -map 0 -c copy -metadata:s:t mimetype="image/${cover##*.}" -metadata:s:t:0 filename="cover.${cover##*.}" "./out/${file}" || return 1
|
||||||
|
# done
|
||||||
|
# ;;
|
||||||
|
*)
|
||||||
|
for file in *.${format}; do
|
||||||
|
# ffmpeg -i "${file}" -i "${cover}" -map 0 -map 0:-v? -map 1 -codec copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -disposition:v attached_pic ./out/"${file}" || return 1
|
||||||
|
ffmpeg -i "${file}" -i "${cover}" -map 0 -map 1 -codec copy -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" -disposition:v attached_pic ./out/"${file}" || return 1
|
||||||
|
done
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
mv out/* .
|
||||||
|
rm -d out/ && rm "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate music metadata from directory structure.
|
||||||
|
# Top dir is the Artist name like this: `The_Beatles`.
|
||||||
|
# Next are albums like this: `2010_My_love`.
|
||||||
|
# Inside are songs like this: `01_sample.flac`.
|
||||||
|
# Usage: ffmpeg_music_meta <FORMAT>
|
||||||
|
function ffmpeg_music_meta() {
|
||||||
|
if [[ ${1} == "" ]]; then
|
||||||
|
help ffmpeg_music_meta
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local format="${1}"
|
||||||
|
|
||||||
|
ls *.${format} &>/dev/null || return 1
|
||||||
|
|
||||||
|
local artist="${PWD%/*}"
|
||||||
|
artist="${artist##*/}"
|
||||||
|
artist="${artist//_/ }"
|
||||||
|
local album="${PWD##*/}"
|
||||||
|
album="${album#*_}"
|
||||||
|
album="${album//_/ }"
|
||||||
|
local year="${PWD##*/}"
|
||||||
|
year="${year%%_*}"
|
||||||
|
# local total=$(ls *.${format} | wc -l)
|
||||||
|
|
||||||
|
mkdir out
|
||||||
|
|
||||||
|
for file in *.${format}; do
|
||||||
|
local track="${file%%_*}"
|
||||||
|
track=$((10#${track}))
|
||||||
|
[[ ${track} == "" ]] && track=0
|
||||||
|
local title="${file#*_}"
|
||||||
|
title="${title%.*}"
|
||||||
|
title="${title//_/ }"
|
||||||
|
|
||||||
|
# echo "${artist}; ${album}; ${year}; ${track}; ${title}"
|
||||||
|
# TODO: make it format-specific.
|
||||||
|
ffmpeg -i "${file}" -map 0 -c copy -metadata "artists=" -metadata "artist=${artist}" -metadata "album_artist=${artist}" -metadata "album=${album}" -metadata "date=${year}" -metadata "year=${year}" -metadata "date_released=${year}" -metadata "track=${track}" -metadata "part_number=${track}" -metadata "title=${title}" ./out/"${file}" || return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
mv out/* .
|
||||||
|
rm -d out/
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rotate the video clock-wise.
|
||||||
|
# Usage: ffmpeg_rotate <ANGLE> <TARGET>
|
||||||
|
function ffmpeg_rotate() {
|
||||||
|
if [[ ${2} == "" ]]; then
|
||||||
|
help ffmpeg_rotate
|
||||||
|
fi
|
||||||
|
|
||||||
|
local angle="${1}"
|
||||||
|
local target="${2}"
|
||||||
|
|
||||||
|
ffmpeg -display_rotation ${angle} -i ${target} -c copy _${target} && mv _${target} ${target} || rm _${target}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get video FPS.
|
||||||
|
function _ffprobe_fps() {
|
||||||
|
local fps=$(ffprobe -v 0 -of csv=p=0 -select_streams v:0 -show_entries stream=r_frame_rate "${1}")
|
||||||
|
[[ ${fps} == "" ]] && fps=30 || fps=$((fps))
|
||||||
|
echo "${fps}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get recommended keyframe interval for a file.
|
||||||
|
function _ffprobe_keyint() {
|
||||||
|
local fps=$(_ffprobe_fps "${1}")
|
||||||
|
echo $((fps * 5))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get audio bitrage. 128 by default.
|
||||||
|
function _ffprobe_ba() {
|
||||||
|
local ba=$(ffprobe -v error -select_streams a:0 -show_entries stream=bit_rate -of default=noprint_wrappers=1:nokey=1 "${1}")
|
||||||
|
[[ ${ba} != "N/A" ]] && echo $((ba / 1024)) || echo 128
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Open file/dir in GUI.
|
|
||||||
# Usage: o <FILE>
|
|
||||||
function o() {
|
|
||||||
xdg-open "''${@}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
5
home/program/bash/module/File.sh
Normal file
5
home/program/bash/module/File.sh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Open file/dir in GUI.
|
||||||
|
# Usage: o <FILE>
|
||||||
|
function o() {
|
||||||
|
xdg-open "${@}"
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Find all file extensions.
|
|
||||||
function find_ext() {
|
|
||||||
local types=($(find -type f | sed -e "s/.*\///" -e "s/^\.//" -e "/\./!d" -e "s/.*\.//"))
|
|
||||||
echo "''${types[@]}" | tr ' ' '\n' | sort -u
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
5
home/program/bash/module/Find.sh
Normal file
5
home/program/bash/module/Find.sh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Find all file extensions.
|
||||||
|
function find_ext() {
|
||||||
|
local types=($(find -type f | sed -e "s/.*\///" -e "s/^\.//" -e "/\./!d" -e "s/.*\.//"))
|
||||||
|
echo "${types[@]}" | tr ' ' '\n' | sort -u
|
||||||
|
}
|
|
@ -1,25 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Fix when ethernet mistakenly detects 100 Mb instead of 1000 Mb.
|
|
||||||
# SPEED is one of 10/100/1000 etc.
|
|
||||||
# Usage: fix_ethernet_speed <DEVICE> <SPEED>
|
|
||||||
function fix_ethernet_speed() {
|
|
||||||
local device="''${1}"
|
|
||||||
local speed="''${2}"
|
|
||||||
|
|
||||||
if [[ "''${device}" = "" || "''${speed}" = "" ]]; then
|
|
||||||
help fix_ethernet_speed
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
ethtool -s "''${device}" speed "''${speed}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Delete lost Gradle lock files.
|
|
||||||
function fix_gradle_lock() {
|
|
||||||
cd "''${HOME}/.gradle" && find -type f | grep \\.lock$ | xargs -- rm
|
|
||||||
cd -
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
20
home/program/bash/module/Fix.sh
Normal file
20
home/program/bash/module/Fix.sh
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# Fix when ethernet mistakenly detects 100 Mb instead of 1000 Mb.
|
||||||
|
# SPEED is one of 10/100/1000 etc.
|
||||||
|
# Usage: fix_ethernet_speed <DEVICE> <SPEED>
|
||||||
|
function fix_ethernet_speed() {
|
||||||
|
local device="${1}"
|
||||||
|
local speed="${2}"
|
||||||
|
|
||||||
|
if [[ ${device} == "" || ${speed} == "" ]]; then
|
||||||
|
help fix_ethernet_speed
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
ethtool -s "${device}" speed "${speed}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Delete lost Gradle lock files.
|
||||||
|
function fix_gradle_lock() {
|
||||||
|
cd "${HOME}/.gradle" && find -type f | grep \\.lock$ | xargs -- rm
|
||||||
|
cd -
|
||||||
|
}
|
|
@ -1,338 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Git push.
|
|
||||||
function gps() {
|
|
||||||
git push "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git push all (branches). Useful for pushing all stuff to a new remote.
|
|
||||||
function gpsa() {
|
|
||||||
local remotes=($(git remote))
|
|
||||||
for remote in ''${remotes[@]}; do
|
|
||||||
echo -n "''${remote}: "
|
|
||||||
git push "''${remote}" --tags "refs/remotes/origin/*:refs/heads/*"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git force push.
|
|
||||||
function gpsf() {
|
|
||||||
git push --force "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git pull.
|
|
||||||
function gpl() {
|
|
||||||
git pull "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git log.
|
|
||||||
function gl() {
|
|
||||||
git log --show-signature "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git status.
|
|
||||||
function gs() {
|
|
||||||
git status "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git stash.
|
|
||||||
function gst() {
|
|
||||||
git stash "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Cd to git's root dir.
|
|
||||||
function gcd() {
|
|
||||||
local path=$(git rev-parse --show-toplevel)
|
|
||||||
[[ "''${path}" = "" ]] && return 1
|
|
||||||
cd "''${path}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git diff.
|
|
||||||
function gd() {
|
|
||||||
git diff --patience "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git diff added.
|
|
||||||
function gda() {
|
|
||||||
git diff --cached --patience "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git commit.
|
|
||||||
function gc() {
|
|
||||||
git commit -m "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git clone with tree filter.
|
|
||||||
function gct() {
|
|
||||||
git clone --filter tree:0 ''${@}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git clone full repo.
|
|
||||||
function gcf() {
|
|
||||||
git clone ''${@}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git clone latest commit only.
|
|
||||||
function gcl() {
|
|
||||||
git clone --depth=1 --single-branch ''${@}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git signed commit.
|
|
||||||
function gcs() {
|
|
||||||
git commit -S -m "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git checkout.
|
|
||||||
function gch() {
|
|
||||||
git checkout "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git checkout branch.
|
|
||||||
# Usage: gchb <BRANCH>
|
|
||||||
function gchb() {
|
|
||||||
git checkout -b "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git branch.
|
|
||||||
function gb() {
|
|
||||||
git branch --all "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git branch delete.
|
|
||||||
# Usage: gbd <BRANCH>
|
|
||||||
function gbd() {
|
|
||||||
git branch -D "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git branch delete all except current.
|
|
||||||
function gbda() {
|
|
||||||
git branch | grep -v ^* | xargs git branch -D
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git fetch all.
|
|
||||||
function gf() {
|
|
||||||
git fetch --all -v -p
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git tag.
|
|
||||||
function gt() {
|
|
||||||
git tag "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git ignore files.
|
|
||||||
function gi() {
|
|
||||||
git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git patch from staged diff.
|
|
||||||
# Usage: gpd
|
|
||||||
function gpd() {
|
|
||||||
git diff --staged --patch --binary --minimal
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git patch from commit.
|
|
||||||
# Usage: gpc [REF] [COUNT]
|
|
||||||
function gpc() {
|
|
||||||
local ref="''${1}"
|
|
||||||
local count="''${2}"
|
|
||||||
[[ "''${ref}" = "" ]] && ref="HEAD"
|
|
||||||
[[ "''${count}" = "" ]] && count=1
|
|
||||||
git format-patch --stdout --minimal --patch --binary -''${count} "''${ref}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Git patch apply.
|
|
||||||
# Usage: gpa <FILE>
|
|
||||||
function gpa() {
|
|
||||||
git apply --index "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Unstage changes.
|
|
||||||
# Usage: grs [FILES]
|
|
||||||
function grs() {
|
|
||||||
local target=''${@}
|
|
||||||
[[ "''${target}" = "" ]] && target="."
|
|
||||||
git restore --staged "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run git garbage collection.
|
|
||||||
function ggc() {
|
|
||||||
git gc --aggressive --no-cruft --prune=now
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check git file integrity.
|
|
||||||
function gfsck() {
|
|
||||||
git fsck
|
|
||||||
}
|
|
||||||
|
|
||||||
# Preview diff while adding. Adds current dir by default.
|
|
||||||
# Usage: ga [FILES]
|
|
||||||
function ga() {
|
|
||||||
local target=''${@}
|
|
||||||
[[ "''${target}" = "" ]] && target="."
|
|
||||||
|
|
||||||
git diff ''${target}
|
|
||||||
git add ''${target}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rebase by X commits or from root. When COUNT is 0 - rebase from root. Default is 2.
|
|
||||||
# Usage: gr [COMMIT COUNT]
|
|
||||||
function gr() {
|
|
||||||
local base="''${1}"
|
|
||||||
|
|
||||||
# Rebase last 2 commits by default.
|
|
||||||
if [[ "''${base}" = "" ]]; then
|
|
||||||
base="2"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If 0, rebase from root. else from specified base.
|
|
||||||
if [[ "''${base}" = "0" ]]; then
|
|
||||||
git rebase -i --root
|
|
||||||
else
|
|
||||||
git rebase -i HEAD~''${base}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Specify git user as Dmitry Voronin with provided email.
|
|
||||||
# Usage: gu [EMAIL]
|
|
||||||
function gu() {
|
|
||||||
local name="Dmitry Voronin"
|
|
||||||
local email="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${name}" = "" || "''${email}" = "" ]]; then
|
|
||||||
echo "usage: gu [EMAIL]"
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
git config user.name "''${name}"
|
|
||||||
git config user.email "''${email}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get my git repo.
|
|
||||||
# Usage: gg <REPO>
|
|
||||||
function gg() {
|
|
||||||
local repo="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${repo}" = "" ]]; then
|
|
||||||
help gg
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
git clone ssh://git@git.voronind.com:22144/voronind/"''${repo}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# See diff for a specific commit. Last commit by default.
|
|
||||||
# Usage: gdc [COMMITHASH]
|
|
||||||
function gdc() {
|
|
||||||
local hash="''${1}"
|
|
||||||
[[ "''${hash}" = "" ]] && hash="HEAD"
|
|
||||||
git diff "''${hash}^!"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get version number based on commit count.
|
|
||||||
function gv() {
|
|
||||||
git rev-list HEAD --count
|
|
||||||
}
|
|
||||||
|
|
||||||
# Open the remote web url in default browser.
|
|
||||||
# Usage: gw [REMOTE]
|
|
||||||
function gw() {
|
|
||||||
local remote="''${1}"
|
|
||||||
[[ "''${remote}" = "" ]] && remote="$(git remote | head -n1)"
|
|
||||||
|
|
||||||
local url="$(git remote get-url ''${remote})"
|
|
||||||
open "''${url}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Search for string in whole git history.
|
|
||||||
# Usage: gsearch <STRING>
|
|
||||||
function gsearch() {
|
|
||||||
local target="''${*}"
|
|
||||||
|
|
||||||
if [[ "''${target}" = "" ]]; then
|
|
||||||
help gsearch
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
git log -p -G "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sign the old commits. 0 to resign from root.
|
|
||||||
# Usage: gsign [COMMIT_COUNT]
|
|
||||||
function gsign() {
|
|
||||||
local base="''${1}"
|
|
||||||
|
|
||||||
# Resign last commit by default.
|
|
||||||
if [[ "''${base}" = "" ]]; then
|
|
||||||
base="1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If 0, rebase from root. else from specified base.
|
|
||||||
if [[ "''${base}" = "0" ]]; then
|
|
||||||
git rebase --exec 'git commit --amend --no-edit -n -S' -i --root
|
|
||||||
else
|
|
||||||
git rebase --exec 'git commit --amend --no-edit -n -S' -i HEAD~''${base}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show current branch.
|
|
||||||
function _git_current_branch() {
|
|
||||||
git branch --show-current 2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Show origin's url.
|
|
||||||
function _git_origin_url() {
|
|
||||||
git remote get-url origin
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get this dotfiles url.
|
|
||||||
function _git_dotfiles_url() {
|
|
||||||
echo 'https://git.voronind.com/voronind/linux.git'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if current git repo is this dotfiles.
|
|
||||||
function _git_is_dotfiles() {
|
|
||||||
# [[ "$(_git_origin_url)" = "$(_git_dotfiles_url)" ]]
|
|
||||||
local dir="''${PWD}"
|
|
||||||
|
|
||||||
while [[ "''${dir}" != "" ]]; do
|
|
||||||
if [[ -d "''${dir}/.git" ]]; then
|
|
||||||
if [[ "''${dir}" = "''${HOME}" ]] || [[ "''${dir}" = "$(realpath ''${HOME})" ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
dir="''${dir%/*}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete.
|
|
||||||
_completion_loader git &> /dev/null
|
|
||||||
__git_complete gps _git_push &> /dev/null
|
|
||||||
__git_complete gpsf _git_push &> /dev/null
|
|
||||||
__git_complete gpl _git_pull &> /dev/null
|
|
||||||
__git_complete gl _git_log &> /dev/null
|
|
||||||
__git_complete gs _git_status &> /dev/null
|
|
||||||
__git_complete gst _git_stash &> /dev/null
|
|
||||||
__git_complete gd _git_diff &> /dev/null
|
|
||||||
__git_complete gdc _git_diff &> /dev/null
|
|
||||||
__git_complete gc _git_commit &> /dev/null
|
|
||||||
__git_complete gch _git_checkout &> /dev/null
|
|
||||||
__git_complete gchb _git_checkout &> /dev/null
|
|
||||||
__git_complete gb _git_branch &> /dev/null
|
|
||||||
__git_complete gbd _git_branch &> /dev/null
|
|
||||||
__git_complete gf _git_fetch &> /dev/null
|
|
||||||
__git_complete gt _git_tag &> /dev/null
|
|
||||||
__git_complete gp _git_apply &> /dev/null
|
|
||||||
__git_complete ga _git_add &> /dev/null
|
|
||||||
__git_complete gw _git_pull &> /dev/null
|
|
||||||
|
|
||||||
# Autocomplete with my git emails.
|
|
||||||
function _gu() {
|
|
||||||
_autocomplete hi@voronind.com dd.voronin@fsight.ru
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _gu gu
|
|
||||||
'';
|
|
||||||
}
|
|
333
home/program/bash/module/Git.sh
Normal file
333
home/program/bash/module/Git.sh
Normal file
|
@ -0,0 +1,333 @@
|
||||||
|
# Git push.
|
||||||
|
function gps() {
|
||||||
|
git push "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git push all (branches). Useful for pushing all stuff to a new remote.
|
||||||
|
function gpsa() {
|
||||||
|
local remotes=($(git remote))
|
||||||
|
for remote in ${remotes[@]}; do
|
||||||
|
echo -n "${remote}: "
|
||||||
|
git push "${remote}" --tags "refs/remotes/origin/*:refs/heads/*"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git force push.
|
||||||
|
function gpsf() {
|
||||||
|
git push --force "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git pull.
|
||||||
|
function gpl() {
|
||||||
|
git pull "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git log.
|
||||||
|
function gl() {
|
||||||
|
git log --show-signature "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git status.
|
||||||
|
function gs() {
|
||||||
|
git status "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git stash.
|
||||||
|
function gst() {
|
||||||
|
git stash "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Cd to git's root dir.
|
||||||
|
function gcd() {
|
||||||
|
local path=$(git rev-parse --show-toplevel)
|
||||||
|
[[ ${path} == "" ]] && return 1
|
||||||
|
cd "${path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git diff.
|
||||||
|
function gd() {
|
||||||
|
git diff --patience "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git diff added.
|
||||||
|
function gda() {
|
||||||
|
git diff --cached --patience "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git commit.
|
||||||
|
function gc() {
|
||||||
|
git commit -m "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git clone with tree filter.
|
||||||
|
function gct() {
|
||||||
|
git clone --filter tree:0 ${@}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git clone full repo.
|
||||||
|
function gcf() {
|
||||||
|
git clone ${@}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git clone latest commit only.
|
||||||
|
function gcl() {
|
||||||
|
git clone --depth=1 --single-branch ${@}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git signed commit.
|
||||||
|
function gcs() {
|
||||||
|
git commit -S -m "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git checkout.
|
||||||
|
function gch() {
|
||||||
|
git checkout "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git checkout branch.
|
||||||
|
# Usage: gchb <BRANCH>
|
||||||
|
function gchb() {
|
||||||
|
git checkout -b "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git branch.
|
||||||
|
function gb() {
|
||||||
|
git branch --all "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git branch delete.
|
||||||
|
# Usage: gbd <BRANCH>
|
||||||
|
function gbd() {
|
||||||
|
git branch -D "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git branch delete all except current.
|
||||||
|
function gbda() {
|
||||||
|
git branch | grep -v ^* | xargs git branch -D
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git fetch all.
|
||||||
|
function gf() {
|
||||||
|
git fetch --all -v -p
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git tag.
|
||||||
|
function gt() {
|
||||||
|
git tag "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git ignore files.
|
||||||
|
function gi() {
|
||||||
|
git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git patch from staged diff.
|
||||||
|
# Usage: gpd
|
||||||
|
function gpd() {
|
||||||
|
git diff --staged --patch --binary --minimal
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git patch from commit.
|
||||||
|
# Usage: gpc [REF] [COUNT]
|
||||||
|
function gpc() {
|
||||||
|
local ref="${1}"
|
||||||
|
local count="${2}"
|
||||||
|
[[ ${ref} == "" ]] && ref="HEAD"
|
||||||
|
[[ ${count} == "" ]] && count=1
|
||||||
|
git format-patch --stdout --minimal --patch --binary -${count} "${ref}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Git patch apply.
|
||||||
|
# Usage: gpa <FILE>
|
||||||
|
function gpa() {
|
||||||
|
git apply --index "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Unstage changes.
|
||||||
|
# Usage: grs [FILES]
|
||||||
|
function grs() {
|
||||||
|
local target=${@}
|
||||||
|
[[ ${target} == "" ]] && target="."
|
||||||
|
git restore --staged "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run git garbage collection.
|
||||||
|
function ggc() {
|
||||||
|
git gc --aggressive --no-cruft --prune=now
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check git file integrity.
|
||||||
|
function gfsck() {
|
||||||
|
git fsck
|
||||||
|
}
|
||||||
|
|
||||||
|
# Preview diff while adding. Adds current dir by default.
|
||||||
|
# Usage: ga [FILES]
|
||||||
|
function ga() {
|
||||||
|
local target=${@}
|
||||||
|
[[ ${target} == "" ]] && target="."
|
||||||
|
|
||||||
|
git diff ${target}
|
||||||
|
git add ${target}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rebase by X commits or from root. When COUNT is 0 - rebase from root. Default is 2.
|
||||||
|
# Usage: gr [COMMIT COUNT]
|
||||||
|
function gr() {
|
||||||
|
local base="${1}"
|
||||||
|
|
||||||
|
# Rebase last 2 commits by default.
|
||||||
|
if [[ ${base} == "" ]]; then
|
||||||
|
base="2"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If 0, rebase from root. else from specified base.
|
||||||
|
if [[ ${base} == "0" ]]; then
|
||||||
|
git rebase -i --root
|
||||||
|
else
|
||||||
|
git rebase -i HEAD~${base}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Specify git user as Dmitry Voronin with provided email.
|
||||||
|
# Usage: gu [EMAIL]
|
||||||
|
function gu() {
|
||||||
|
local name="Dmitry Voronin"
|
||||||
|
local email="${1}"
|
||||||
|
|
||||||
|
if [[ ${name} == "" || ${email} == "" ]]; then
|
||||||
|
echo "usage: gu [EMAIL]"
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
git config user.name "${name}"
|
||||||
|
git config user.email "${email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get my git repo.
|
||||||
|
# Usage: gg <REPO>
|
||||||
|
function gg() {
|
||||||
|
local repo="${1}"
|
||||||
|
|
||||||
|
if [[ ${repo} == "" ]]; then
|
||||||
|
help gg
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
git clone ssh://git@git.voronind.com:22144/voronind/"${repo}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# See diff for a specific commit. Last commit by default.
|
||||||
|
# Usage: gdc [COMMITHASH]
|
||||||
|
function gdc() {
|
||||||
|
local hash="${1}"
|
||||||
|
[[ ${hash} == "" ]] && hash="HEAD"
|
||||||
|
git diff "${hash}^!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get version number based on commit count.
|
||||||
|
function gv() {
|
||||||
|
git rev-list HEAD --count
|
||||||
|
}
|
||||||
|
|
||||||
|
# Open the remote web url in default browser.
|
||||||
|
# Usage: gw [REMOTE]
|
||||||
|
function gw() {
|
||||||
|
local remote="${1}"
|
||||||
|
[[ ${remote} == "" ]] && remote="$(git remote | head -n1)"
|
||||||
|
|
||||||
|
local url="$(git remote get-url ${remote})"
|
||||||
|
open "${url}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Search for string in whole git history.
|
||||||
|
# Usage: gsearch <STRING>
|
||||||
|
function gsearch() {
|
||||||
|
local target="${*}"
|
||||||
|
|
||||||
|
if [[ ${target} == "" ]]; then
|
||||||
|
help gsearch
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
git log -p -G "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sign the old commits. 0 to resign from root.
|
||||||
|
# Usage: gsign [COMMIT_COUNT]
|
||||||
|
function gsign() {
|
||||||
|
local base="${1}"
|
||||||
|
|
||||||
|
# Resign last commit by default.
|
||||||
|
if [[ ${base} == "" ]]; then
|
||||||
|
base="1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If 0, rebase from root. else from specified base.
|
||||||
|
if [[ ${base} == "0" ]]; then
|
||||||
|
git rebase --exec 'git commit --amend --no-edit -n -S' -i --root
|
||||||
|
else
|
||||||
|
git rebase --exec 'git commit --amend --no-edit -n -S' -i HEAD~${base}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show current branch.
|
||||||
|
function _git_current_branch() {
|
||||||
|
git branch --show-current 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Show origin's url.
|
||||||
|
function _git_origin_url() {
|
||||||
|
git remote get-url origin
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get this dotfiles url.
|
||||||
|
function _git_dotfiles_url() {
|
||||||
|
echo 'https://git.voronind.com/voronind/linux.git'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if current git repo is this dotfiles.
|
||||||
|
function _git_is_dotfiles() {
|
||||||
|
# [[ "$(_git_origin_url)" = "$(_git_dotfiles_url)" ]]
|
||||||
|
local dir="${PWD}"
|
||||||
|
|
||||||
|
while [[ ${dir} != "" ]]; do
|
||||||
|
if [[ -d "${dir}/.git" ]]; then
|
||||||
|
if [[ ${dir} == "${HOME}" ]] || [[ ${dir} == "$(realpath ${HOME})" ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
dir="${dir%/*}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete.
|
||||||
|
_completion_loader git &>/dev/null
|
||||||
|
__git_complete gps _git_push &>/dev/null
|
||||||
|
__git_complete gpsf _git_push &>/dev/null
|
||||||
|
__git_complete gpl _git_pull &>/dev/null
|
||||||
|
__git_complete gl _git_log &>/dev/null
|
||||||
|
__git_complete gs _git_status &>/dev/null
|
||||||
|
__git_complete gst _git_stash &>/dev/null
|
||||||
|
__git_complete gd _git_diff &>/dev/null
|
||||||
|
__git_complete gdc _git_diff &>/dev/null
|
||||||
|
__git_complete gc _git_commit &>/dev/null
|
||||||
|
__git_complete gch _git_checkout &>/dev/null
|
||||||
|
__git_complete gchb _git_checkout &>/dev/null
|
||||||
|
__git_complete gb _git_branch &>/dev/null
|
||||||
|
__git_complete gbd _git_branch &>/dev/null
|
||||||
|
__git_complete gf _git_fetch &>/dev/null
|
||||||
|
__git_complete gt _git_tag &>/dev/null
|
||||||
|
__git_complete gp _git_apply &>/dev/null
|
||||||
|
__git_complete ga _git_add &>/dev/null
|
||||||
|
__git_complete gw _git_pull &>/dev/null
|
||||||
|
|
||||||
|
# Autocomplete with my git emails.
|
||||||
|
function _gu() {
|
||||||
|
_autocomplete hi@voronind.com dd.voronin@fsight.ru
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _gu gu
|
|
@ -1,96 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Check smartcard pin.
|
|
||||||
function scunlock() {
|
|
||||||
pkill keyboxd &> /dev/null
|
|
||||||
# pkill gpg-agent &> /dev/null
|
|
||||||
echo verify | gpg --card-edit --no-tty --command-fd=0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Encrypt files to myself.
|
|
||||||
# Usage: encrypt <FILES>
|
|
||||||
function encrypt() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
|
|
||||||
if [[ "''${targets}" = "" ]]; then
|
|
||||||
help encrypt
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
gpg --encrypt --armor --recipient hi@voronind.com --output "''${target}.gpg" "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Decrypt files to myself.
|
|
||||||
# Usage: decrypt [FILES]
|
|
||||||
function decrypt() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*.gpg)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
gpg --decrypt --output "''${target%.gpg}" "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sign a file.
|
|
||||||
# Usage: sign <FILES>
|
|
||||||
function sign() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
|
|
||||||
if [[ "''${targets}" = "" ]]; then
|
|
||||||
help sign
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
gpg --detach-sig --armor --output "''${target}.sig" "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Verify a signature. All .sig files by default.
|
|
||||||
# Usage: verify [FILES]
|
|
||||||
function verify() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*.sig)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
gpg --verify "''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find user keys using keyservers.
|
|
||||||
# Usage: gpg_find <EMAIL>
|
|
||||||
function gpg_find() {
|
|
||||||
local email="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${email}" = "" ]]; then
|
|
||||||
help gpg_find
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
gpg --locate-keys "''${email}" \
|
|
||||||
|| gpg --locate-keys --auto-key-locate hkps://keys.openpgp.org "''${email}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Update keys.
|
|
||||||
function gpg_refresh() {
|
|
||||||
gpg --refresh-keys
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
91
home/program/bash/module/Gpg.sh
Normal file
91
home/program/bash/module/Gpg.sh
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
# Check smartcard pin.
|
||||||
|
function scunlock() {
|
||||||
|
pkill keyboxd &>/dev/null
|
||||||
|
# pkill gpg-agent &> /dev/null
|
||||||
|
echo verify | gpg --card-edit --no-tty --command-fd=0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Encrypt files to myself.
|
||||||
|
# Usage: encrypt <FILES>
|
||||||
|
function encrypt() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
|
||||||
|
if [[ ${targets} == "" ]]; then
|
||||||
|
help encrypt
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
gpg --encrypt --armor --recipient hi@voronind.com --output "${target}.gpg" "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Decrypt files to myself.
|
||||||
|
# Usage: decrypt [FILES]
|
||||||
|
function decrypt() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
|
||||||
|
[[ ${targets} == "" ]] && targets=(*.gpg)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
gpg --decrypt --output "${target%.gpg}" "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sign a file.
|
||||||
|
# Usage: sign <FILES>
|
||||||
|
function sign() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
|
||||||
|
if [[ ${targets} == "" ]]; then
|
||||||
|
help sign
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
gpg --detach-sig --armor --output "${target}.sig" "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify a signature. All .sig files by default.
|
||||||
|
# Usage: verify [FILES]
|
||||||
|
function verify() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
|
||||||
|
[[ ${targets} == "" ]] && targets=(*.sig)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
gpg --verify "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find user keys using keyservers.
|
||||||
|
# Usage: gpg_find <EMAIL>
|
||||||
|
function gpg_find() {
|
||||||
|
local email="${1}"
|
||||||
|
|
||||||
|
if [[ ${email} == "" ]]; then
|
||||||
|
help gpg_find
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
gpg --locate-keys "${email}" ||
|
||||||
|
gpg --locate-keys --auto-key-locate hkps://keys.openpgp.org "${email}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Update keys.
|
||||||
|
function gpg_refresh() {
|
||||||
|
gpg --refresh-keys
|
||||||
|
}
|
|
@ -1,74 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Group files by extension.
|
|
||||||
# Usage: group_ext [FILES]
|
|
||||||
function group_ext() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local ext=''${target##*.}
|
|
||||||
[[ -d "''${target}" ]] && { _iterate_skip "Is a directory."; return 0; }
|
|
||||||
[[ "''${ext}" = "''${target}" ]] && { _iterate_skip "No extension."; return 0; }
|
|
||||||
|
|
||||||
mkdir ''${ext} 2> /dev/null
|
|
||||||
|
|
||||||
mv -- ''${target} ./''${ext}/''${target}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Group files and dirs by year.
|
|
||||||
# Usage: group_year [FILES]
|
|
||||||
function group_year() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(ls))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local year=$(stat --format=%y ''${target})
|
|
||||||
year=''${year%%-*}
|
|
||||||
|
|
||||||
mkdir ''${year} 2> /dev/null
|
|
||||||
|
|
||||||
mv -- ''${target} ./''${year}/''${target}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Copy files from current year to the named dir.
|
|
||||||
# Usage: group_year_copy <YEAR> [FILES]
|
|
||||||
function group_year_copy() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local selected_year="''${1}"
|
|
||||||
local targets=(''${@:2})
|
|
||||||
|
|
||||||
if [[ "''${selected_year}" = "" ]]; then
|
|
||||||
help group_year_copy
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All files by default.
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(ls))
|
|
||||||
|
|
||||||
mkdir ''${selected_year} 2> /dev/null
|
|
||||||
|
|
||||||
process() {
|
|
||||||
local year=$(stat --format=%y ''${target})
|
|
||||||
year=''${year%%-*}
|
|
||||||
|
|
||||||
if [[ "''${year}" = "''${selected_year}" ]]; then
|
|
||||||
rcp -- ''${target} ./''${selected_year}/
|
|
||||||
else
|
|
||||||
_iterate_skip "Skip: ''${year}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
75
home/program/bash/module/Group.sh
Normal file
75
home/program/bash/module/Group.sh
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
# Group files by extension.
|
||||||
|
# Usage: group_ext [FILES]
|
||||||
|
function group_ext() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local ext=${target##*.}
|
||||||
|
[[ -d ${target} ]] && {
|
||||||
|
_iterate_skip "Is a directory."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
[[ ${ext} == "${target}" ]] && {
|
||||||
|
_iterate_skip "No extension."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir ${ext} 2>/dev/null
|
||||||
|
|
||||||
|
mv -- ${target} ./${ext}/${target}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Group files and dirs by year.
|
||||||
|
# Usage: group_year [FILES]
|
||||||
|
function group_year() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(ls))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local year=$(stat --format=%y ${target})
|
||||||
|
year=${year%%-*}
|
||||||
|
|
||||||
|
mkdir ${year} 2>/dev/null
|
||||||
|
|
||||||
|
mv -- ${target} ./${year}/${target}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Copy files from current year to the named dir.
|
||||||
|
# Usage: group_year_copy <YEAR> [FILES]
|
||||||
|
function group_year_copy() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local selected_year="${1}"
|
||||||
|
local targets=(${@:2})
|
||||||
|
|
||||||
|
if [[ ${selected_year} == "" ]]; then
|
||||||
|
help group_year_copy
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# All files by default.
|
||||||
|
[[ ${targets} == "" ]] && targets=($(ls))
|
||||||
|
|
||||||
|
mkdir ${selected_year} 2>/dev/null
|
||||||
|
|
||||||
|
process() {
|
||||||
|
local year=$(stat --format=%y ${target})
|
||||||
|
year=${year%%-*}
|
||||||
|
|
||||||
|
if [[ ${year} == "${selected_year}" ]]; then
|
||||||
|
rcp -- ${target} ./${selected_year}/
|
||||||
|
else
|
||||||
|
_iterate_skip "Skip: ${year}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Get help about dotfiles bash function.
|
|
||||||
# Usage: help <FUNCTION>
|
|
||||||
function help() {
|
|
||||||
local fun="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${fun}" = "" ]] || [[ "$(find_function | grep ''${fun})" = "" ]]; then
|
|
||||||
help help
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat ~/.bashrc | sed -n -e "/^function ''${fun}()/q;p" | tac | sed -n -e "/^[^#]/q;p" | tac | sed -e "s/^# \+//" -e "\$i \ " | sed "1{/^$/d}" | sed "1{/^ *$/d}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Short for help.
|
|
||||||
# Usage: h <FUNCTION>
|
|
||||||
function h() {
|
|
||||||
help "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with available functions.
|
|
||||||
function _help_functions() {
|
|
||||||
_autocomplete $(find_function)
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _help_functions help h
|
|
||||||
'';
|
|
||||||
}
|
|
25
home/program/bash/module/Help.sh
Normal file
25
home/program/bash/module/Help.sh
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# Get help about dotfiles bash function.
|
||||||
|
# Usage: help <FUNCTION>
|
||||||
|
function help() {
|
||||||
|
local fun="${1}"
|
||||||
|
|
||||||
|
if [[ ${fun} == "" ]] || [[ "$(find_function | grep ${fun})" == "" ]]; then
|
||||||
|
help help
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat ~/.bashrc | sed -n -e "/^function ${fun}()/q;p" | tac | sed -n -e "/^[^#]/q;p" | tac | sed -e "s/^# \+//" -e "\$i \ " | sed "1{/^$/d}" | sed "1{/^ *$/d}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Short for help.
|
||||||
|
# Usage: h <FUNCTION>
|
||||||
|
function h() {
|
||||||
|
help "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with available functions.
|
||||||
|
function _help_functions() {
|
||||||
|
_autocomplete $(find_function)
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _help_functions help h
|
|
@ -1,71 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Unset possible system-defined aliases.
|
|
||||||
unalias l ll lll llll la lla &> /dev/null
|
|
||||||
unset l ll lll llll la lla &> /dev/null
|
|
||||||
|
|
||||||
# List files in dirs.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: l [DIRS]
|
|
||||||
function l() {
|
|
||||||
# ls -lhv --si --group-directories-first --color=auto -- "$@"
|
|
||||||
ccd "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List last modified files first.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: ll [DIRS]
|
|
||||||
function ll() {
|
|
||||||
ls -lhv --si --group-directories-first --color=auto -- "$@"
|
|
||||||
# ls -lhvtr --si --color=auto -- "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List files in tree structure.
|
|
||||||
# Current dir by default.
|
|
||||||
# Depth can be omitted by passing `-` (dash).
|
|
||||||
# Usage: lll [DEPTH] [DIRS]
|
|
||||||
function lll() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local depth="''${1}"
|
|
||||||
local target=("''${@:2}")
|
|
||||||
|
|
||||||
[[ "''${target}" = "" ]] && target="."
|
|
||||||
[[ "''${depth}" = "" ]] && depth=666
|
|
||||||
[[ "''${depth}" = "-" ]] && depth=666
|
|
||||||
|
|
||||||
tree -a -L "''${depth}" -- "''${target[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List files recursively.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: llll [DIRS]
|
|
||||||
function llll() {
|
|
||||||
ls -RlAhv --si --group-directories-first --color=auto -- "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List all files in dirs, incl. hidden files.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: la [DIRS]
|
|
||||||
function la() {
|
|
||||||
ls -lAh --si --group-directories-first --color=auto -- "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List all files in dirs, incl. hidden files, sorted by mtime.
|
|
||||||
# Current dir by default.
|
|
||||||
# Usage: lla [DIRS]
|
|
||||||
function lla() {
|
|
||||||
ls -lAhtr --si --color=auto -- "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# List only files.
|
|
||||||
function _ls_file() {
|
|
||||||
ls --classify | grep -v \/$
|
|
||||||
}
|
|
||||||
|
|
||||||
# List only dirs.
|
|
||||||
function _ls_dir() {
|
|
||||||
ls --classify | grep \/$ | sed -e "s/\/$//"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
66
home/program/bash/module/Ls.sh
Normal file
66
home/program/bash/module/Ls.sh
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
# Unset possible system-defined aliases.
|
||||||
|
unalias l ll lll llll la lla &>/dev/null
|
||||||
|
unset l ll lll llll la lla &>/dev/null
|
||||||
|
|
||||||
|
# List files in dirs.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: l [DIRS]
|
||||||
|
function l() {
|
||||||
|
# ls -lhv --si --group-directories-first --color=auto -- "$@"
|
||||||
|
ccd "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List last modified files first.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: ll [DIRS]
|
||||||
|
function ll() {
|
||||||
|
ls -lhv --si --group-directories-first --color=auto -- "$@"
|
||||||
|
# ls -lhvtr --si --color=auto -- "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List files in tree structure.
|
||||||
|
# Current dir by default.
|
||||||
|
# Depth can be omitted by passing `-` (dash).
|
||||||
|
# Usage: lll [DEPTH] [DIRS]
|
||||||
|
function lll() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local depth="${1}"
|
||||||
|
local target=("${@:2}")
|
||||||
|
|
||||||
|
[[ ${target} == "" ]] && target="."
|
||||||
|
[[ ${depth} == "" ]] && depth=666
|
||||||
|
[[ ${depth} == "-" ]] && depth=666
|
||||||
|
|
||||||
|
tree -a -L "${depth}" -- "${target[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List files recursively.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: llll [DIRS]
|
||||||
|
function llll() {
|
||||||
|
ls -RlAhv --si --group-directories-first --color=auto -- "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List all files in dirs, incl. hidden files.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: la [DIRS]
|
||||||
|
function la() {
|
||||||
|
ls -lAh --si --group-directories-first --color=auto -- "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List all files in dirs, incl. hidden files, sorted by mtime.
|
||||||
|
# Current dir by default.
|
||||||
|
# Usage: lla [DIRS]
|
||||||
|
function lla() {
|
||||||
|
ls -lAhtr --si --color=auto -- "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# List only files.
|
||||||
|
function _ls_file() {
|
||||||
|
ls --classify | grep -v \/$
|
||||||
|
}
|
||||||
|
|
||||||
|
# List only dirs.
|
||||||
|
function _ls_dir() {
|
||||||
|
ls --classify | grep \/$ | sed -e "s/\/$//"
|
||||||
|
}
|
|
@ -1,400 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Rename dirs to `snake_case` and files to `PascalCase`. Careful with structured file names like archives!
|
|
||||||
# Usage: name [FILES]
|
|
||||||
function name() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(ls))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Skip archive.
|
|
||||||
if $(_is_archive "''${target}"); then
|
|
||||||
_iterate_skip "File is an archive, skip."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -d "''${target}" ]]; then
|
|
||||||
local new_name=$(parse_snake ''${target})
|
|
||||||
[[ -e "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
else
|
|
||||||
local ext=".''${target##*.}"
|
|
||||||
local name=''${target%.*}
|
|
||||||
[[ "''${ext}" = ".''${target}" ]] && ext=""
|
|
||||||
|
|
||||||
local new_name="$(parse_pascal ''${name})''${ext}"
|
|
||||||
[[ -e "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename files with provided parser, i.e. `parse_simple`.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_parse <PARSER> [FILES]
|
|
||||||
function name_parse() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local parser=''${1}
|
|
||||||
local targets=(''${@:2})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=([^.]*)
|
|
||||||
|
|
||||||
if [[ "''${parser}" = "" ]]; then
|
|
||||||
help name_parse
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Skip archive.
|
|
||||||
if $(_is_archive "''${target}"); then
|
|
||||||
_iterate_skip "File is an archive, skip."
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# parse new name.
|
|
||||||
local ext=""
|
|
||||||
local name="''${target}"
|
|
||||||
|
|
||||||
# ext only for files.
|
|
||||||
if [[ -f "''${target}" ]]; then
|
|
||||||
ext=".''${target##*.}"
|
|
||||||
name="''${target%.*}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Files w/o extension support.
|
|
||||||
[[ "''${ext#.}" = "''${name}" ]] && ext=""
|
|
||||||
|
|
||||||
# Get new name.
|
|
||||||
local new_name=$(''${parser} "''${name}")''${ext,,}
|
|
||||||
|
|
||||||
# check if same name.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# check if target name already exists.
|
|
||||||
if [[ -f "''${new_name}" ]]; then
|
|
||||||
_error "''${new_name}: Already exists!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# rename target.
|
|
||||||
mv -- "''${target}" "''${new_name}" && echo "''${new_name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename all files to their hashes while keeping extensions.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_hash [FILES]
|
|
||||||
function name_hash() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# extract extension.
|
|
||||||
local extension="''${target##*.}"
|
|
||||||
if [[ "''${extension}" = "''${target}" ]]; then
|
|
||||||
extension=""
|
|
||||||
else
|
|
||||||
extension=".''${extension}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# hash the new name.
|
|
||||||
local hash=$(pv "''${target}" | sha1sum | cut -d\ -f1)
|
|
||||||
new_name="''${hash,,}''${extension,,}"
|
|
||||||
|
|
||||||
# check if same name.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# rename target.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check hashes for previously renamed files.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_hash_check [FILES]
|
|
||||||
function name_hash_check() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=([^.]*)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# extract hashes.
|
|
||||||
local stored="''${target%%.*}"
|
|
||||||
local actual=$(pv "''${target}" | sha1sum | cut -d\ -f1)
|
|
||||||
|
|
||||||
# compare hashes.
|
|
||||||
if [[ "''${stored}" != "''${actual}" ]]; then
|
|
||||||
_error "Failed."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename files for Jellyfin shows, i.e. `Episode S01E01.mkv`
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_show [FILES]
|
|
||||||
function name_show() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local season="$(realpath .)"; season="''${season##*\ }"
|
|
||||||
local episode=0
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
# Error when no season number specified.
|
|
||||||
if [[ "''${season}" = "" ]]; then
|
|
||||||
_error "Could not determine season number."
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
((episode++))
|
|
||||||
|
|
||||||
# extract new name.
|
|
||||||
local new_name="Episode S''${season}E$(printf %02d ''${episode}).''${target##*.}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# rename target.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename files for Kavita manga format.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_manga <SEASON> [FILES]
|
|
||||||
function name_manga() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local manga=''${PWD##*/}
|
|
||||||
local season=''${1}
|
|
||||||
local episode=0
|
|
||||||
local targets=(''${@:2})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
# Error when no season number specified.
|
|
||||||
if [[ "''${season}" = "" ]]; then
|
|
||||||
help name_manga
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
((episode++))
|
|
||||||
|
|
||||||
# Extract new name.
|
|
||||||
local new_name="''${manga} Vol.''${season} Ch.''${episode}.''${target##*.}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename target.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename files for ffmpeg_music_meta format.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_music [FILES]
|
|
||||||
function name_music() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(ls))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Extract new name.
|
|
||||||
local ext=''${target##*.}
|
|
||||||
|
|
||||||
if [[ -d "''${target}" ]]; then
|
|
||||||
local new_name="$(parse_startcase $(parse_simple ''${target%.*}))"
|
|
||||||
else
|
|
||||||
local new_name="$(parse_startcase $(parse_simple ''${target%.*})).''${ext}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target%/}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename target.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Rename files with new extension.
|
|
||||||
# All files by default.
|
|
||||||
# Usage: name_ext <EXTENSION> [FILES]
|
|
||||||
function name_ext() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local extension=''${1}
|
|
||||||
local targets=(''${@:2})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
# Error when no new extension specified.
|
|
||||||
if [[ "''${extension}" = "" ]]; then
|
|
||||||
help name_ext
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Extract new name.
|
|
||||||
local new_name="''${target%.*}"."''${extension}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename target.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Change file name prefix.
|
|
||||||
# All matching files by default.
|
|
||||||
# Usage: name_prefix <OLD> <NEW> [FILES]
|
|
||||||
function name_prefix() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local old=''${1}
|
|
||||||
local new=''${2}
|
|
||||||
local targets=(''${@:3})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(''${old}*)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Create new name.
|
|
||||||
local new_name="''${new}''${target#$old}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Change file name postfix.
|
|
||||||
# All matching files by default.
|
|
||||||
# Usage: name_postfix <OLD> <NEW> [FILES]
|
|
||||||
function name_postfix() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local old=''${1}
|
|
||||||
local new=''${2}
|
|
||||||
local targets=(''${@:3})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*''${old})
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Create new name.
|
|
||||||
local new_name="''${target%$old}''${new}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Replace part of the name.
|
|
||||||
# All matching files by default.
|
|
||||||
# Usage: name_replace <OLD> <NEW> [FILES]
|
|
||||||
function name_replace() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local old=''${1}
|
|
||||||
local new=''${2}
|
|
||||||
local targets=(''${@:3})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*''${old}*)
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Create new name.
|
|
||||||
local new_name="''${target//$old/$new}"
|
|
||||||
|
|
||||||
# Skip on no change.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Rename.
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fix numbering for numbered files. I.e if there are 10 items and some of them start without zero, then append zero to it. 1..10 -> 01..10.
|
|
||||||
# Usage: name_fix_numbering [FILES]
|
|
||||||
function name_fix_numbering() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local highest=0
|
|
||||||
local power=0
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(ls | grep "^[0-9]"))
|
|
||||||
|
|
||||||
# Count leading zeroes.
|
|
||||||
for target in "''${targets[@]}"; do
|
|
||||||
# Check that starts with a digit.
|
|
||||||
[[ "''${target}" =~ ^[0-9] ]] || continue
|
|
||||||
|
|
||||||
local digits=($(parse_ints "''${target}"))
|
|
||||||
local digit="''${digits[0]}"
|
|
||||||
digit=$((10#''${digit}))
|
|
||||||
|
|
||||||
[[ "''${digit}" -gt "''${highest}" ]] && highest="''${digit}"
|
|
||||||
done
|
|
||||||
|
|
||||||
local i=''${highest}
|
|
||||||
while [[ i -gt 0 ]]; do
|
|
||||||
((power++))
|
|
||||||
i=$((''${i}/10))
|
|
||||||
done
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Check that starts with a digit.
|
|
||||||
if [[ ! "''${target}" =~ ^[0-9] ]]; then
|
|
||||||
_error "Does not start with a digit!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Prepare new name.
|
|
||||||
local digits=($(parse_ints "''${target}"))
|
|
||||||
local digit="''${digits[0]}"
|
|
||||||
digit=$((10#''${digit}))
|
|
||||||
local new_name=$(printf "%0''${power}d" "''${digit}")"''${target#''${digits[0]}}"
|
|
||||||
|
|
||||||
# Skip if the same name.
|
|
||||||
[[ "''${target}" = "''${new_name}" ]] && return 0
|
|
||||||
|
|
||||||
# Check that file does not exist.
|
|
||||||
if [[ -e "''${new_name}" ]]; then
|
|
||||||
_error "''${new_name}: File exists!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
mv -- ''${target} ''${new_name} && echo ''${new_name}
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _comp_name_parse() {
|
|
||||||
_autocomplete $(find_function | grep ^parse)
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -o filenames -F _comp_name_parse name_parse
|
|
||||||
'';
|
|
||||||
}
|
|
396
home/program/bash/module/Name.sh
Normal file
396
home/program/bash/module/Name.sh
Normal file
|
@ -0,0 +1,396 @@
|
||||||
|
# Rename dirs to `snake_case` and files to `PascalCase`. Careful with structured file names like archives!
|
||||||
|
# Usage: name [FILES]
|
||||||
|
function name() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(ls))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Skip archive.
|
||||||
|
if $(_is_archive "${target}"); then
|
||||||
|
_iterate_skip "File is an archive, skip."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d ${target} ]]; then
|
||||||
|
local new_name=$(parse_snake ${target})
|
||||||
|
[[ -e ${new_name} ]] && return 0
|
||||||
|
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
else
|
||||||
|
local ext=".${target##*.}"
|
||||||
|
local name=${target%.*}
|
||||||
|
[[ ${ext} == ".${target}" ]] && ext=""
|
||||||
|
|
||||||
|
local new_name="$(parse_pascal ${name})${ext}"
|
||||||
|
[[ -e ${new_name} ]] && return 0
|
||||||
|
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename files with provided parser, i.e. `parse_simple`.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_parse <PARSER> [FILES]
|
||||||
|
function name_parse() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local parser=${1}
|
||||||
|
local targets=(${@:2})
|
||||||
|
[[ ${targets} == "" ]] && targets=("[^.]*")
|
||||||
|
|
||||||
|
if [[ ${parser} == "" ]]; then
|
||||||
|
help name_parse
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Skip archive.
|
||||||
|
if $(_is_archive "${target}"); then
|
||||||
|
_iterate_skip "File is an archive, skip."
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# parse new name.
|
||||||
|
local ext=""
|
||||||
|
local name="${target}"
|
||||||
|
|
||||||
|
# ext only for files.
|
||||||
|
if [[ -f ${target} ]]; then
|
||||||
|
ext=".${target##*.}"
|
||||||
|
name="${target%.*}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Files w/o extension support.
|
||||||
|
[[ ${ext#.} == "${name}" ]] && ext=""
|
||||||
|
|
||||||
|
# Get new name.
|
||||||
|
local new_name=$(${parser} "${name}")${ext,,}
|
||||||
|
|
||||||
|
# check if same name.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# check if target name already exists.
|
||||||
|
if [[ -f ${new_name} ]]; then
|
||||||
|
_error "${new_name}: Already exists!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# rename target.
|
||||||
|
mv -- "${target}" "${new_name}" && echo "${new_name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename all files to their hashes while keeping extensions.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_hash [FILES]
|
||||||
|
function name_hash() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# extract extension.
|
||||||
|
local extension="${target##*.}"
|
||||||
|
if [[ ${extension} == "${target}" ]]; then
|
||||||
|
extension=""
|
||||||
|
else
|
||||||
|
extension=".${extension}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# hash the new name.
|
||||||
|
local hash=$(pv "${target}" | sha1sum | cut -d\ -f1)
|
||||||
|
new_name="${hash,,}${extension,,}"
|
||||||
|
|
||||||
|
# check if same name.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# rename target.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check hashes for previously renamed files.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_hash_check [FILES]
|
||||||
|
function name_hash_check() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=("[^.]*")
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# extract hashes.
|
||||||
|
local stored="${target%%.*}"
|
||||||
|
local actual=$(pv "${target}" | sha1sum | cut -d\ -f1)
|
||||||
|
|
||||||
|
# compare hashes.
|
||||||
|
if [[ ${stored} != "${actual}" ]]; then
|
||||||
|
_error "Failed."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename files for Jellyfin shows, i.e. `Episode S01E01.mkv`
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_show [FILES]
|
||||||
|
function name_show() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local season="$(realpath .)"
|
||||||
|
season="${season##*\ }"
|
||||||
|
local episode=0
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
# Error when no season number specified.
|
||||||
|
if [[ ${season} == "" ]]; then
|
||||||
|
_error "Could not determine season number."
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
((episode++))
|
||||||
|
|
||||||
|
# extract new name.
|
||||||
|
local new_name="Episode S${season}E$(printf %02d ${episode}).${target##*.}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# rename target.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename files for Kavita manga format.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_manga <SEASON> [FILES]
|
||||||
|
function name_manga() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local manga=${PWD##*/}
|
||||||
|
local season=${1}
|
||||||
|
local episode=0
|
||||||
|
local targets=(${@:2})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
# Error when no season number specified.
|
||||||
|
if [[ ${season} == "" ]]; then
|
||||||
|
help name_manga
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
((episode++))
|
||||||
|
|
||||||
|
# Extract new name.
|
||||||
|
local new_name="${manga} Vol.${season} Ch.${episode}.${target##*.}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename target.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename files for ffmpeg_music_meta format.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_music [FILES]
|
||||||
|
function name_music() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(ls))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Extract new name.
|
||||||
|
local ext=${target##*.}
|
||||||
|
|
||||||
|
if [[ -d ${target} ]]; then
|
||||||
|
local new_name="$(parse_startcase $(parse_simple ${target%.*}))"
|
||||||
|
else
|
||||||
|
local new_name="$(parse_startcase $(parse_simple ${target%.*})).${ext}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target%/} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename target.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Rename files with new extension.
|
||||||
|
# All files by default.
|
||||||
|
# Usage: name_ext <EXTENSION> [FILES]
|
||||||
|
function name_ext() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local extension=${1}
|
||||||
|
local targets=(${@:2})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
# Error when no new extension specified.
|
||||||
|
if [[ ${extension} == "" ]]; then
|
||||||
|
help name_ext
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Extract new name.
|
||||||
|
local new_name="${target%.*}"."${extension}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename target.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Change file name prefix.
|
||||||
|
# All matching files by default.
|
||||||
|
# Usage: name_prefix <OLD> <NEW> [FILES]
|
||||||
|
function name_prefix() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local old=${1}
|
||||||
|
local new=${2}
|
||||||
|
local targets=(${@:3})
|
||||||
|
[[ ${targets} == "" ]] && targets=(${old}*)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Create new name.
|
||||||
|
local new_name="${new}${target#$old}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Change file name postfix.
|
||||||
|
# All matching files by default.
|
||||||
|
# Usage: name_postfix <OLD> <NEW> [FILES]
|
||||||
|
function name_postfix() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local old=${1}
|
||||||
|
local new=${2}
|
||||||
|
local targets=(${@:3})
|
||||||
|
[[ ${targets} == "" ]] && targets=(*${old})
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Create new name.
|
||||||
|
local new_name="${target%$old}${new}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replace part of the name.
|
||||||
|
# All matching files by default.
|
||||||
|
# Usage: name_replace <OLD> <NEW> [FILES]
|
||||||
|
function name_replace() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local old=${1}
|
||||||
|
local new=${2}
|
||||||
|
local targets=(${@:3})
|
||||||
|
[[ ${targets} == "" ]] && targets=(*${old}*)
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Create new name.
|
||||||
|
local new_name="${target//$old/$new}"
|
||||||
|
|
||||||
|
# Skip on no change.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Rename.
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Fix numbering for numbered files. I.e if there are 10 items and some of them start without zero, then append zero to it. 1..10 -> 01..10.
|
||||||
|
# Usage: name_fix_numbering [FILES]
|
||||||
|
function name_fix_numbering() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local highest=0
|
||||||
|
local power=0
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(ls | grep "^[0-9]"))
|
||||||
|
|
||||||
|
# Count leading zeroes.
|
||||||
|
for target in "${targets[@]}"; do
|
||||||
|
# Check that starts with a digit.
|
||||||
|
[[ ${target} =~ ^[0-9] ]] || continue
|
||||||
|
|
||||||
|
local digits=($(parse_ints "${target}"))
|
||||||
|
local digit="${digits[0]}"
|
||||||
|
digit=$((10#${digit}))
|
||||||
|
|
||||||
|
[[ ${digit} -gt ${highest} ]] && highest="${digit}"
|
||||||
|
done
|
||||||
|
|
||||||
|
local i=${highest}
|
||||||
|
while [[ i -gt 0 ]]; do
|
||||||
|
((power++))
|
||||||
|
i=$((i / 10))
|
||||||
|
done
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Check that starts with a digit.
|
||||||
|
if [[ ! ${target} =~ ^[0-9] ]]; then
|
||||||
|
_error "Does not start with a digit!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Prepare new name.
|
||||||
|
local digits=($(parse_ints "${target}"))
|
||||||
|
local digit="${digits[0]}"
|
||||||
|
digit=$((10#${digit}))
|
||||||
|
local new_name=$(printf "%0${power}d" "${digit}")"${target#${digits[0]}}"
|
||||||
|
|
||||||
|
# Skip if the same name.
|
||||||
|
[[ ${target} == "${new_name}" ]] && return 0
|
||||||
|
|
||||||
|
# Check that file does not exist.
|
||||||
|
if [[ -e ${new_name} ]]; then
|
||||||
|
_error "${new_name}: File exists!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mv -- ${target} ${new_name} && echo ${new_name}
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _comp_name_parse() {
|
||||||
|
_autocomplete $(find_function | grep ^parse)
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -o filenames -F _comp_name_parse name_parse
|
|
@ -1,90 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Spawn shell with specified nix environment.
|
|
||||||
# Uses flake.nix in current dir by default.
|
|
||||||
# Usage: shell [NAME]
|
|
||||||
function shell() {
|
|
||||||
local target="''${1}"
|
|
||||||
[[ "''${target}" = "" ]] && target="default"
|
|
||||||
|
|
||||||
SHELL_NAME="''${target}" nix develop ".#''${target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Spawn temporary nix-shell with specified packages.
|
|
||||||
# Usage: tmpshell <PACKAGES>
|
|
||||||
function tmpshell() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local input=("''${@}")
|
|
||||||
local pkgs=()
|
|
||||||
local tag="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${input}" = "" ]]; then
|
|
||||||
help tmpshell
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
for pkg in ''${input[@]}; do
|
|
||||||
pkgs+=("nixpkgs#''${pkg}")
|
|
||||||
done
|
|
||||||
|
|
||||||
SHELL_NAME="''${tag}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix shell --impure ''${pkgs[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
function nix_depends() {
|
|
||||||
nix why-depends /run/current-system nixpkgs#''${1}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run stuff directrly from Nixpks.
|
|
||||||
# Usage: nixpkgs_run <REV> <PACKAGE> [COMMAND]
|
|
||||||
function nixpkgs_run() {
|
|
||||||
local rev="''${1}"
|
|
||||||
local pkg="''${2}"
|
|
||||||
local cmd="''${@:3}"
|
|
||||||
|
|
||||||
if [[ "''${pkg}" = "" ]]; then
|
|
||||||
help nixpkgs_run
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
[[ "''${cmd}" = "" ]] && cmd="''${pkg}"
|
|
||||||
|
|
||||||
SHELL_NAME="''${pkg}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix shell --impure github:NixOS/nixpkgs/''${rev}#''${pkg} -c ''${cmd}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Prefetch to nix store.
|
|
||||||
# Usage: prefetch <URL>
|
|
||||||
function prefetch() {
|
|
||||||
local url="''${1}"
|
|
||||||
local name="''${1##*/}"
|
|
||||||
name=$(parse_alnum "''${name%%\?*}")
|
|
||||||
|
|
||||||
if [[ "''${url}" = "" ]]; then
|
|
||||||
help prefetch
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local result=$(nix hash convert --to sri --hash-algo sha256 $(nix-prefetch-url --name "''${name}" "''${url}"))
|
|
||||||
printf "%s" ''${result} | copy
|
|
||||||
printf "%s\n" ''${result}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run nix locally with no builders.
|
|
||||||
# Usage: nix_local <COMMAND>
|
|
||||||
function nix_local() {
|
|
||||||
nix --option max-jobs $(_core_count) --builders "" --substituters https://cache.nixos.org ''${@}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run test app from other people PRs.
|
|
||||||
# Usage: nix_test github:user/nixpkgs/<REV>#<PKG>
|
|
||||||
function nix_test() {
|
|
||||||
if [[ "''${@}" = "" ]]; then
|
|
||||||
help nix_test
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local name=''${*##*#}
|
|
||||||
SHELL_NAME="''${name}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix --option max-jobs $(_core_count) --builders "" --substituters https://cache.nixos.org shell --impure ''${@}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
85
home/program/bash/module/Nix.sh
Normal file
85
home/program/bash/module/Nix.sh
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
# Spawn shell with specified nix environment.
|
||||||
|
# Uses flake.nix in current dir by default.
|
||||||
|
# Usage: shell [NAME]
|
||||||
|
function shell() {
|
||||||
|
local target="${1}"
|
||||||
|
[[ ${target} == "" ]] && target="default"
|
||||||
|
|
||||||
|
SHELL_NAME="${target}" nix develop ".#${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Spawn temporary nix-shell with specified packages.
|
||||||
|
# Usage: tmpshell <PACKAGES>
|
||||||
|
function tmpshell() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local input=("${@}")
|
||||||
|
local pkgs=()
|
||||||
|
local tag="${1}"
|
||||||
|
|
||||||
|
if [[ ${input} == "" ]]; then
|
||||||
|
help tmpshell
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
for pkg in ${input[@]}; do
|
||||||
|
pkgs+=("nixpkgs#${pkg}")
|
||||||
|
done
|
||||||
|
|
||||||
|
SHELL_NAME="${tag}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix shell --impure ${pkgs[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nix_depends() {
|
||||||
|
nix why-depends /run/current-system nixpkgs#${1}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run stuff directrly from Nixpks.
|
||||||
|
# Usage: nixpkgs_run <REV> <PACKAGE> [COMMAND]
|
||||||
|
function nixpkgs_run() {
|
||||||
|
local rev="${1}"
|
||||||
|
local pkg="${2}"
|
||||||
|
local cmd="${@:3}"
|
||||||
|
|
||||||
|
if [[ ${pkg} == "" ]]; then
|
||||||
|
help nixpkgs_run
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ ${cmd} == "" ]] && cmd="${pkg}"
|
||||||
|
|
||||||
|
SHELL_NAME="${pkg}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix shell --impure github:NixOS/nixpkgs/${rev}#${pkg} -c ${cmd}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Prefetch to nix store.
|
||||||
|
# Usage: prefetch <URL>
|
||||||
|
function prefetch() {
|
||||||
|
local url="${1}"
|
||||||
|
local name="${1##*/}"
|
||||||
|
name=$(parse_alnum "${name%%\?*}")
|
||||||
|
|
||||||
|
if [[ ${url} == "" ]]; then
|
||||||
|
help prefetch
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local result=$(nix hash convert --to sri --hash-algo sha256 $(nix-prefetch-url --name "${name}" "${url}"))
|
||||||
|
printf "%s" ${result} | copy
|
||||||
|
printf "%s\n" ${result}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run nix locally with no builders.
|
||||||
|
# Usage: nix_local <COMMAND>
|
||||||
|
function nix_local() {
|
||||||
|
nix --option max-jobs $(_core_count) --builders "" --substituters https://cache.nixos.org ${@}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run test app from other people PRs.
|
||||||
|
# Usage: nix_test github:user/nixpkgs/<REV>#<PKG>
|
||||||
|
function nix_test() {
|
||||||
|
if [[ ${@} == "" ]]; then
|
||||||
|
help nix_test
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local name=${*##*#}
|
||||||
|
SHELL_NAME="${name}" NIXPKGS_ALLOW_INSECURE=1 NIXPKGS_ALLOW_UNFREE=1 nix --option max-jobs $(_core_count) --builders "" --substituters https://cache.nixos.org shell --impure ${@}
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
{ secret, ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Send Telegram notification.
|
|
||||||
# Usage: notify <MESSAGE>
|
|
||||||
function notify() {
|
|
||||||
curl -X POST -H 'Content-Type: Application/json' -d "${secret.tg.dt "false"}" ${secret.tg.bt} &> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Send silent Telegram notification.
|
|
||||||
# Usage: notify_silent <MESSAGE>
|
|
||||||
function notify_silent() {
|
|
||||||
curl -X POST -H 'Content-Type: Application/json' -d "${secret.tg.dt "true"}" ${secret.tg.bt} &> /dev/null
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
11
home/program/bash/module/Notify.sh
Normal file
11
home/program/bash/module/Notify.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Send Telegram notification.
|
||||||
|
# Usage: notify <MESSAGE>
|
||||||
|
function notify() {
|
||||||
|
curl -X POST -H 'Content-Type: Application/json' -d "@tgdata@" @tgbot@ &>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Send silent Telegram notification.
|
||||||
|
# Usage: notify_silent <MESSAGE>
|
||||||
|
function notify_silent() {
|
||||||
|
curl -X POST -H 'Content-Type: Application/json' -d "@tgdatasilent@" @tgbot@ &>/dev/null
|
||||||
|
}
|
|
@ -1,41 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Change file ownership to specified user id and restrict access to him.
|
|
||||||
# Root user by default. This directory recursively by default.
|
|
||||||
# Usage: own [USER] [FILES]
|
|
||||||
function own() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local files=("''${@:2}")
|
|
||||||
local user="''${1}"
|
|
||||||
local group="''${1}"
|
|
||||||
|
|
||||||
# default to current dir.
|
|
||||||
if [ "''${files[*]}" = "" ]; then
|
|
||||||
files=(".")
|
|
||||||
fi
|
|
||||||
|
|
||||||
# default to current user.
|
|
||||||
if [ "''${user}" = "" ]; then
|
|
||||||
user="''${UID}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If not root, default to users group.
|
|
||||||
[[ "''${user}" = 0 ]] && group="0" || group="100"
|
|
||||||
|
|
||||||
for file in "''${files[@]}"; do
|
|
||||||
# set ownership.
|
|
||||||
chown "''${user}":"''${group}" -R "''${file}" &> /dev/null
|
|
||||||
|
|
||||||
# remove access from group and others.
|
|
||||||
chmod -077 -R "''${file}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function _complete_own() {
|
|
||||||
_autocomplete $(_get_users)
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _complete_own own
|
|
||||||
'';
|
|
||||||
}
|
|
36
home/program/bash/module/Own.sh
Normal file
36
home/program/bash/module/Own.sh
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
# Change file ownership to specified user id and restrict access to him.
|
||||||
|
# Root user by default. This directory recursively by default.
|
||||||
|
# Usage: own [USER] [FILES]
|
||||||
|
function own() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local files=("${@:2}")
|
||||||
|
local user="${1}"
|
||||||
|
local group="${1}"
|
||||||
|
|
||||||
|
# default to current dir.
|
||||||
|
if [ "${files[*]}" = "" ]; then
|
||||||
|
files=(".")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# default to current user.
|
||||||
|
if [ "${user}" = "" ]; then
|
||||||
|
user="${UID}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If not root, default to users group.
|
||||||
|
[[ ${user} == 0 ]] && group="0" || group="100"
|
||||||
|
|
||||||
|
for file in "${files[@]}"; do
|
||||||
|
# set ownership.
|
||||||
|
chown "${user}":"${group}" -R "${file}" &>/dev/null
|
||||||
|
|
||||||
|
# remove access from group and others.
|
||||||
|
chmod -077 -R "${file}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function _complete_own() {
|
||||||
|
_autocomplete $(_get_users)
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _complete_own own
|
|
@ -1,209 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
export _unpack_supported=".tar$|.tgz$|.txz$|.tar.gz$|.tar.xz$|.zip$|.iso$|.rar$"
|
|
||||||
|
|
||||||
# Pack files into desired format.
|
|
||||||
# All files and directories by default.
|
|
||||||
# Usage: pack <TARGET.ext> [FILES]
|
|
||||||
function pack() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local output="''${1}"
|
|
||||||
local targets=("''${@:2}")
|
|
||||||
local format="''${output##*.}"
|
|
||||||
local name="''${output%.*}"
|
|
||||||
|
|
||||||
# report no output.
|
|
||||||
if [[ "''${output}" = "" ]]; then
|
|
||||||
help pack
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# report no format.
|
|
||||||
if [[ "''${format}" = "" ]]; then
|
|
||||||
_error "Could not determine output format."
|
|
||||||
help pack
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# All targets by default.
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*)
|
|
||||||
|
|
||||||
case "''${format}" in
|
|
||||||
"tgz")
|
|
||||||
_pack_tgz "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"txz")
|
|
||||||
_pack_txz "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"tar")
|
|
||||||
_pack_tar "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"zip")
|
|
||||||
_pack_zip "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"gz")
|
|
||||||
_pack_gz "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"xz")
|
|
||||||
_pack_xz "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
"iso")
|
|
||||||
_pack_iso "''${output}" "''${targets[@]}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
_error "''${target}: Format not supported."
|
|
||||||
return 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Attempt to unpack.
|
|
||||||
# All supported formats by default.
|
|
||||||
# Usage: unpack [FILES]
|
|
||||||
function unpack() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_files | grep -E ''${_unpack_supported}))
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Use full path to file.
|
|
||||||
target=''$(realpath "''${target}")
|
|
||||||
|
|
||||||
# Check for archive.
|
|
||||||
if $(_is_archive "''${target}"); then
|
|
||||||
unarchive "''${target}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Unpack file type.
|
|
||||||
local type="''${target##*.}"
|
|
||||||
|
|
||||||
[[ "''${target}" =~ .tar.gz$ ]] && type="tar.gz"
|
|
||||||
[[ "''${target}" =~ .tar.xz$ ]] && type="tar.xz"
|
|
||||||
|
|
||||||
# Make a dir for files.
|
|
||||||
local dir="''${target%.$type}"; dir="''${dir##*/}"
|
|
||||||
mkdir "''${dir}" > /dev/null
|
|
||||||
pushd "''${dir}" > /dev/null
|
|
||||||
|
|
||||||
# Unpack content.
|
|
||||||
case "''${type,,}" in
|
|
||||||
"zip")
|
|
||||||
_unpack_zip "''${target}"
|
|
||||||
;;
|
|
||||||
"7z")
|
|
||||||
_unpack_7z "''${target}"
|
|
||||||
;;
|
|
||||||
"tgz"|"tar.gz")
|
|
||||||
_unpack_tgz "''${target}"
|
|
||||||
;;
|
|
||||||
"txz"|"tar.xz")
|
|
||||||
_unpack_txz "''${target}"
|
|
||||||
;;
|
|
||||||
"tar")
|
|
||||||
_unpack_tar "''${target}"
|
|
||||||
;;
|
|
||||||
"iso")
|
|
||||||
_unpack_iso "''${target}"
|
|
||||||
;;
|
|
||||||
"rar")
|
|
||||||
_unpack_rar "''${target}"
|
|
||||||
;;
|
|
||||||
"xz")
|
|
||||||
_unpack_xz "''${target}"
|
|
||||||
;;
|
|
||||||
"gz")
|
|
||||||
_unpack_gz "''${target}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
_error "''${target}: Format not supported."
|
|
||||||
return 2
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# Cd back.
|
|
||||||
popd > /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_zip() {
|
|
||||||
zip -9 -r "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_tgz() {
|
|
||||||
tar -c "''${@:2}" | pv -s $(/usr/bin/env du -csb "''${@:2}" | sed -n -e '$p' | awk '{print $1}') | gzip -1 > "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_txz() {
|
|
||||||
tar -c "''${@:2}" | pv -s $(/usr/bin/env du -csb "''${@:2}" | sed -n -e '$p' | awk '{print $1}') | xz -9e > "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_tar() {
|
|
||||||
tar -c "''${@:2}" | pv -s $(/usr/bin/env du -csb "''${@:2}" | sed -n -e '$p' | awk '{print $1}') > "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_gz() {
|
|
||||||
pv "''${2}" | gzip -1 > "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_xz() {
|
|
||||||
pv "''${2}" | xz -9e > "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _pack_iso() {
|
|
||||||
local input=("''${@:2}")
|
|
||||||
local output="''${1}"
|
|
||||||
local args=()
|
|
||||||
|
|
||||||
for arg in ''${input[@]}; do
|
|
||||||
[[ -d "''${arg}" ]] || {
|
|
||||||
_error "''${arg} is not a directory."
|
|
||||||
return 1
|
|
||||||
};
|
|
||||||
|
|
||||||
args+=("''${arg}=''${arg}")
|
|
||||||
done
|
|
||||||
|
|
||||||
genisoimage -J -r -pad -o "''${output}" -graft-points "''${args[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_zip() {
|
|
||||||
unzip "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_7z() {
|
|
||||||
7za x "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_tgz() {
|
|
||||||
pv "''${1}" | gzip -d | tar -xf -
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_txz() {
|
|
||||||
pv "''${1}" | xz -d | tar -xf -
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_tar() {
|
|
||||||
pv "''${1}" | tar -xf -
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_iso() {
|
|
||||||
7za x "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_rar() {
|
|
||||||
unrar x "''${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_gz() {
|
|
||||||
pv "''${1}" | gzip -d > "''${1%.gz}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _unpack_xz() {
|
|
||||||
pv "''${1}" | xz -d > "''${1%.xz}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
205
home/program/bash/module/Pack.sh
Normal file
205
home/program/bash/module/Pack.sh
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
export _unpack_supported=".tar$|.tgz$|.txz$|.tar.gz$|.tar.xz$|.zip$|.iso$|.rar$"
|
||||||
|
|
||||||
|
# Pack files into desired format.
|
||||||
|
# All files and directories by default.
|
||||||
|
# Usage: pack <TARGET.ext> [FILES]
|
||||||
|
function pack() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local output="${1}"
|
||||||
|
local targets=("${@:2}")
|
||||||
|
local format="${output##*.}"
|
||||||
|
local name="${output%.*}"
|
||||||
|
|
||||||
|
# report no output.
|
||||||
|
if [[ ${output} == "" ]]; then
|
||||||
|
help pack
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# report no format.
|
||||||
|
if [[ ${format} == "" ]]; then
|
||||||
|
_error "Could not determine output format."
|
||||||
|
help pack
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
# All targets by default.
|
||||||
|
[[ ${targets} == "" ]] && targets=(*)
|
||||||
|
|
||||||
|
case "${format}" in
|
||||||
|
"tgz")
|
||||||
|
_pack_tgz "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"txz")
|
||||||
|
_pack_txz "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"tar")
|
||||||
|
_pack_tar "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"zip")
|
||||||
|
_pack_zip "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"gz")
|
||||||
|
_pack_gz "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"xz")
|
||||||
|
_pack_xz "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
"iso")
|
||||||
|
_pack_iso "${output}" "${targets[@]}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_error "${target}: Format not supported."
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
# Attempt to unpack.
|
||||||
|
# All supported formats by default.
|
||||||
|
# Usage: unpack [FILES]
|
||||||
|
function unpack() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_files | grep -E ${_unpack_supported}))
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Use full path to file.
|
||||||
|
target=$(realpath "${target}")
|
||||||
|
|
||||||
|
# Check for archive.
|
||||||
|
if $(_is_archive "${target}"); then
|
||||||
|
unarchive "${target}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Unpack file type.
|
||||||
|
local type="${target##*.}"
|
||||||
|
|
||||||
|
[[ ${target} =~ .tar.gz$ ]] && type="tar.gz"
|
||||||
|
[[ ${target} =~ .tar.xz$ ]] && type="tar.xz"
|
||||||
|
|
||||||
|
# Make a dir for files.
|
||||||
|
local dir="${target%.$type}"
|
||||||
|
dir="${dir##*/}"
|
||||||
|
mkdir "${dir}" >/dev/null
|
||||||
|
pushd "${dir}" >/dev/null
|
||||||
|
|
||||||
|
# Unpack content.
|
||||||
|
case "${type,,}" in
|
||||||
|
"zip")
|
||||||
|
_unpack_zip "${target}"
|
||||||
|
;;
|
||||||
|
"7z")
|
||||||
|
_unpack_7z "${target}"
|
||||||
|
;;
|
||||||
|
"tgz" | "tar.gz")
|
||||||
|
_unpack_tgz "${target}"
|
||||||
|
;;
|
||||||
|
"txz" | "tar.xz")
|
||||||
|
_unpack_txz "${target}"
|
||||||
|
;;
|
||||||
|
"tar")
|
||||||
|
_unpack_tar "${target}"
|
||||||
|
;;
|
||||||
|
"iso")
|
||||||
|
_unpack_iso "${target}"
|
||||||
|
;;
|
||||||
|
"rar")
|
||||||
|
_unpack_rar "${target}"
|
||||||
|
;;
|
||||||
|
"xz")
|
||||||
|
_unpack_xz "${target}"
|
||||||
|
;;
|
||||||
|
"gz")
|
||||||
|
_unpack_gz "${target}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_error "${target}: Format not supported."
|
||||||
|
return 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Cd back.
|
||||||
|
popd >/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_zip() {
|
||||||
|
zip -9 -r "${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_tgz() {
|
||||||
|
tar -c "${@:2}" | pv -s $(/usr/bin/env du -csb "${@:2}" | sed -n -e '$p' | awk '{print $1}') | gzip -1 >"${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_txz() {
|
||||||
|
tar -c "${@:2}" | pv -s $(/usr/bin/env du -csb "${@:2}" | sed -n -e '$p' | awk '{print $1}') | xz -9e >"${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_tar() {
|
||||||
|
tar -c "${@:2}" | pv -s $(/usr/bin/env du -csb "${@:2}" | sed -n -e '$p' | awk '{print $1}') >"${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_gz() {
|
||||||
|
pv "${2}" | gzip -1 >"${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_xz() {
|
||||||
|
pv "${2}" | xz -9e >"${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _pack_iso() {
|
||||||
|
local input=("${@:2}")
|
||||||
|
local output="${1}"
|
||||||
|
local args=()
|
||||||
|
|
||||||
|
for arg in ${input[@]}; do
|
||||||
|
[[ -d ${arg} ]] || {
|
||||||
|
_error "${arg} is not a directory."
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
args+=("${arg}=${arg}")
|
||||||
|
done
|
||||||
|
|
||||||
|
genisoimage -J -r -pad -o "${output}" -graft-points "${args[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_zip() {
|
||||||
|
unzip "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_7z() {
|
||||||
|
7za x "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_tgz() {
|
||||||
|
pv "${1}" | gzip -d | tar -xf -
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_txz() {
|
||||||
|
pv "${1}" | xz -d | tar -xf -
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_tar() {
|
||||||
|
pv "${1}" | tar -xf -
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_iso() {
|
||||||
|
7za x "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_rar() {
|
||||||
|
unrar x "${1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_gz() {
|
||||||
|
pv "${1}" | gzip -d >"${1%.gz}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _unpack_xz() {
|
||||||
|
pv "${1}" | xz -d >"${1%.xz}"
|
||||||
|
}
|
|
@ -1,173 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
export _PARSE_ALLOWED_CHARS="_-"
|
|
||||||
export _PARSE_SPLIT_CHARS="\.\ _-"
|
|
||||||
|
|
||||||
# Parse data and output simplified format.
|
|
||||||
# Usage: parse_simple <STRING>
|
|
||||||
function parse_simple() {
|
|
||||||
echo "''${*}" | sed \
|
|
||||||
-e "s/[''${_PARSE_SPLIT_CHARS}]/_/g" \
|
|
||||||
-e "s/[^[:alnum:]''${_PARSE_ALLOWED_CHARS}]//g" \
|
|
||||||
-e "s/_\+/_/g" -e "s/-\+/-/g" \
|
|
||||||
-e "s/_-/_/g" -e "s/-_/_/g" \
|
|
||||||
-e "s/_\+/_/g" \
|
|
||||||
-e "s/^_//" -e "s/_$//"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse to PascalCase.
|
|
||||||
# Usage: parse_pascal <STRING>
|
|
||||||
function parse_pascal() {
|
|
||||||
local parts=($(_get_parts $(parse_simple "''${*}")))
|
|
||||||
local result
|
|
||||||
|
|
||||||
for part in "''${parts[@]}"; do
|
|
||||||
local word="''${part,,}"
|
|
||||||
word="''${word^}"
|
|
||||||
result="''${result}''${word}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${result}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse to snake_case.
|
|
||||||
# Usage: parse_snake <STRING>
|
|
||||||
function parse_snake() {
|
|
||||||
local parts=($(_get_parts $(parse_simple "''${*}")))
|
|
||||||
local result
|
|
||||||
|
|
||||||
for part in "''${parts[@]}"; do
|
|
||||||
local word="''${part,,}"
|
|
||||||
result="''${result}_''${word}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${result#_}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse to kebab-case.
|
|
||||||
# Usage: parse_kebab <STRING>
|
|
||||||
function parse_kebab() {
|
|
||||||
local parts=($(_get_parts $(parse_simple "''${*}")))
|
|
||||||
local result
|
|
||||||
|
|
||||||
for part in "''${parts[@]}"; do
|
|
||||||
local word="''${part,,}"
|
|
||||||
result="''${result}-''${word}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${result#-}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse to camelCase.
|
|
||||||
# Usage: parse_camel <STRING>
|
|
||||||
function parse_camel() {
|
|
||||||
local parts=($(_get_parts $(parse_simple "''${*}")))
|
|
||||||
local result
|
|
||||||
|
|
||||||
for part in "''${parts[@]}"; do
|
|
||||||
local word="''${part,,}"
|
|
||||||
word="''${word^}"
|
|
||||||
result="''${result}''${word}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${result,}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse to SNAKE_CASE_UPPERCASE. **NOT STABLE! Repeating results in different output.**
|
|
||||||
# Usage: parse_snake_uppercase <STRING>
|
|
||||||
function parse_snake_uppercase() {
|
|
||||||
local parts=($(_get_parts $(parse_simple "''${*}")))
|
|
||||||
local result
|
|
||||||
|
|
||||||
for part in "''${parts[@]}"; do
|
|
||||||
local word="''${part^^}"
|
|
||||||
result="''${result}_''${word}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${result#_}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse data keeping only alphanumeric characters.
|
|
||||||
# Usage: parse_alnum <STRING>
|
|
||||||
function parse_alnum() {
|
|
||||||
echo "''${*}" | sed -e "s/[^[:alnum:]]//g"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse integers from mixed string.
|
|
||||||
# Usage: parse_ints <STRING>
|
|
||||||
function parse_ints() {
|
|
||||||
echo "''${*}" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to lowercase.
|
|
||||||
# Usage: parse_lowercase <STRING>
|
|
||||||
function parse_lowercase() {
|
|
||||||
echo "''${*,,}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to uppercase.
|
|
||||||
# Usage: parse_uppercase <STRING>
|
|
||||||
function parse_uppercase() {
|
|
||||||
echo "''${*^^}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to title case.
|
|
||||||
# Usage: parse_titlecase <STRING>
|
|
||||||
function parse_titlecase() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local parts=($(_parse_split ''${@}))
|
|
||||||
local minors=("is" "at" "of" "to" "in" "for" "the" "a" "an" "and" "but" "or" "on" "was" "were" "been" "be" "do" "did" "does")
|
|
||||||
|
|
||||||
echo -n "$(parse_sentencecase ''${parts[0]})"
|
|
||||||
for part in ''${parts[@]:1}; do
|
|
||||||
if _contains $(echo ''${part,,} | sed -e "s/[''${_PARSE_SPLIT_CHARS}]//g") ''${minors[@]}; then
|
|
||||||
echo -n "''${part,,}"
|
|
||||||
else
|
|
||||||
echo -n "$(parse_sentencecase ''${part})"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to sentence case.
|
|
||||||
# Usage: parse_sentencecase <STRING>
|
|
||||||
function parse_sentencecase() {
|
|
||||||
local lower="''${*,,}"
|
|
||||||
echo "''${lower^}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to start case.
|
|
||||||
# Usage: parse_startcase <STRING>
|
|
||||||
function parse_startcase() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local lower="''${*,,}"
|
|
||||||
local parts=($(_parse_split ''${lower}))
|
|
||||||
|
|
||||||
for part in ''${parts[@]}; do
|
|
||||||
echo -n "''${part^}"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
}
|
|
||||||
|
|
||||||
# Parse string to pretty Json.
|
|
||||||
# Usage: parse_json <STRING>
|
|
||||||
function parse_json() {
|
|
||||||
echo "''${*}" | jq
|
|
||||||
}
|
|
||||||
|
|
||||||
# Split string by separators.
|
|
||||||
# Usage: _parse_split <STRING>
|
|
||||||
function _parse_split() {
|
|
||||||
echo "''${*}" | sed -e "s/[A-Z]\+/\n&/g" -e "s/[0-9]\+/\n&\n/g" -e "s/[''${_PARSE_SPLIT_CHARS}]/&\n/g" | sed -e "/^$/d"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get name parts.
|
|
||||||
# Usage: _get_parts <STRING>
|
|
||||||
function _get_parts() {
|
|
||||||
_parse_split "''${*}" | sed -e "s/[''${_PARSE_SPLIT_CHARS}]//g" | sed -e "/^$/d"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
168
home/program/bash/module/Parse.sh
Normal file
168
home/program/bash/module/Parse.sh
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
export _PARSE_ALLOWED_CHARS="_-"
|
||||||
|
export _PARSE_SPLIT_CHARS="\.\ _-"
|
||||||
|
|
||||||
|
# Parse data and output simplified format.
|
||||||
|
# Usage: parse_simple <STRING>
|
||||||
|
function parse_simple() {
|
||||||
|
echo "${*}" | sed \
|
||||||
|
-e "s/[${_PARSE_SPLIT_CHARS}]/_/g" \
|
||||||
|
-e "s/[^[:alnum:]${_PARSE_ALLOWED_CHARS}]//g" \
|
||||||
|
-e "s/_\+/_/g" -e "s/-\+/-/g" \
|
||||||
|
-e "s/_-/_/g" -e "s/-_/_/g" \
|
||||||
|
-e "s/_\+/_/g" \
|
||||||
|
-e "s/^_//" -e "s/_$//"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse to PascalCase.
|
||||||
|
# Usage: parse_pascal <STRING>
|
||||||
|
function parse_pascal() {
|
||||||
|
local parts=($(_get_parts $(parse_simple "${*}")))
|
||||||
|
local result
|
||||||
|
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
local word="${part,,}"
|
||||||
|
word="${word^}"
|
||||||
|
result="${result}${word}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${result}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse to snake_case.
|
||||||
|
# Usage: parse_snake <STRING>
|
||||||
|
function parse_snake() {
|
||||||
|
local parts=($(_get_parts $(parse_simple "${*}")))
|
||||||
|
local result
|
||||||
|
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
local word="${part,,}"
|
||||||
|
result="${result}_${word}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${result#_}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse to kebab-case.
|
||||||
|
# Usage: parse_kebab <STRING>
|
||||||
|
function parse_kebab() {
|
||||||
|
local parts=($(_get_parts $(parse_simple "${*}")))
|
||||||
|
local result
|
||||||
|
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
local word="${part,,}"
|
||||||
|
result="${result}-${word}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${result#-}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse to camelCase.
|
||||||
|
# Usage: parse_camel <STRING>
|
||||||
|
function parse_camel() {
|
||||||
|
local parts=($(_get_parts $(parse_simple "${*}")))
|
||||||
|
local result
|
||||||
|
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
local word="${part,,}"
|
||||||
|
word="${word^}"
|
||||||
|
result="${result}${word}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${result,}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse to SNAKE_CASE_UPPERCASE. **NOT STABLE! Repeating results in different output.**
|
||||||
|
# Usage: parse_snake_uppercase <STRING>
|
||||||
|
function parse_snake_uppercase() {
|
||||||
|
local parts=($(_get_parts $(parse_simple "${*}")))
|
||||||
|
local result
|
||||||
|
|
||||||
|
for part in "${parts[@]}"; do
|
||||||
|
local word="${part^^}"
|
||||||
|
result="${result}_${word}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${result#_}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse data keeping only alphanumeric characters.
|
||||||
|
# Usage: parse_alnum <STRING>
|
||||||
|
function parse_alnum() {
|
||||||
|
echo "${*}" | sed -e "s/[^[:alnum:]]//g"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse integers from mixed string.
|
||||||
|
# Usage: parse_ints <STRING>
|
||||||
|
function parse_ints() {
|
||||||
|
echo "${*}" | tr '\n' ' ' | sed -e 's/[^0-9]/ /g' -e 's/^ *//g' -e 's/ *$//g' | tr -s ' ' | sed 's/ /\n/g'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to lowercase.
|
||||||
|
# Usage: parse_lowercase <STRING>
|
||||||
|
function parse_lowercase() {
|
||||||
|
echo "${*,,}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to uppercase.
|
||||||
|
# Usage: parse_uppercase <STRING>
|
||||||
|
function parse_uppercase() {
|
||||||
|
echo "${*^^}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to title case.
|
||||||
|
# Usage: parse_titlecase <STRING>
|
||||||
|
function parse_titlecase() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local parts=($(_parse_split ${@}))
|
||||||
|
local minors=("is" "at" "of" "to" "in" "for" "the" "a" "an" "and" "but" "or" "on" "was" "were" "been" "be" "do" "did" "does")
|
||||||
|
|
||||||
|
echo -n "$(parse_sentencecase ${parts[0]})"
|
||||||
|
for part in ${parts[@]:1}; do
|
||||||
|
if _contains $(echo ${part,,} | sed -e "s/[${_PARSE_SPLIT_CHARS}]//g") ${minors[@]}; then
|
||||||
|
echo -n "${part,,}"
|
||||||
|
else
|
||||||
|
echo -n "$(parse_sentencecase ${part})"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to sentence case.
|
||||||
|
# Usage: parse_sentencecase <STRING>
|
||||||
|
function parse_sentencecase() {
|
||||||
|
local lower="${*,,}"
|
||||||
|
echo "${lower^}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to start case.
|
||||||
|
# Usage: parse_startcase <STRING>
|
||||||
|
function parse_startcase() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local lower="${*,,}"
|
||||||
|
local parts=($(_parse_split ${lower}))
|
||||||
|
|
||||||
|
for part in ${parts[@]}; do
|
||||||
|
echo -n "${part^}"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
# Parse string to pretty Json.
|
||||||
|
# Usage: parse_json <STRING>
|
||||||
|
function parse_json() {
|
||||||
|
echo "${*}" | jq
|
||||||
|
}
|
||||||
|
|
||||||
|
# Split string by separators.
|
||||||
|
# Usage: _parse_split <STRING>
|
||||||
|
function _parse_split() {
|
||||||
|
echo "${*}" | sed -e "s/[A-Z]\+/\n&/g" -e "s/[0-9]\+/\n&\n/g" -e "s/[${_PARSE_SPLIT_CHARS}]/&\n/g" | sed -e "/^$/d"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get name parts.
|
||||||
|
# Usage: _get_parts <STRING>
|
||||||
|
function _get_parts() {
|
||||||
|
_parse_split "${*}" | sed -e "s/[${_PARSE_SPLIT_CHARS}]//g" | sed -e "/^$/d"
|
||||||
|
}
|
|
@ -1,14 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Recursively change permissions to allow read sharing with group and others.
|
|
||||||
function perm_share() {
|
|
||||||
find . -type d -exec chmod 755 {} \;; find . -type f -exec chmod 644 {} \;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Recursively change permissions to restrict access for group and others.
|
|
||||||
function perm() {
|
|
||||||
find . -type d -exec chmod 700 {} \;; find . -type f -exec chmod 600 {} \;
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
11
home/program/bash/module/Permission.sh
Normal file
11
home/program/bash/module/Permission.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Recursively change permissions to allow read sharing with group and others.
|
||||||
|
function perm_share() {
|
||||||
|
find . -type d -exec chmod 755 {} \;
|
||||||
|
find . -type f -exec chmod 644 {} \;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Recursively change permissions to restrict access for group and others.
|
||||||
|
function perm() {
|
||||||
|
find . -type d -exec chmod 700 {} \;
|
||||||
|
find . -type f -exec chmod 600 {} \;
|
||||||
|
}
|
|
@ -1,19 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Quick edit a picture and copy to clipboard.
|
|
||||||
# Usage: pic_copy <FILE>
|
|
||||||
function pic_copy() {
|
|
||||||
swappy -f "''${1}" -o - | copy
|
|
||||||
}
|
|
||||||
|
|
||||||
# Quick edit a pictures inplace.
|
|
||||||
# Usage: pic_edit <FILES>
|
|
||||||
function pic_edit() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
for file in "''${@}"; do
|
|
||||||
swappy -f "''${file}" -o "''${file}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
14
home/program/bash/module/Picture.sh
Normal file
14
home/program/bash/module/Picture.sh
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# Quick edit a picture and copy to clipboard.
|
||||||
|
# Usage: pic_copy <FILE>
|
||||||
|
function pic_copy() {
|
||||||
|
swappy -f "${1}" -o - | copy
|
||||||
|
}
|
||||||
|
|
||||||
|
# Quick edit a pictures inplace.
|
||||||
|
# Usage: pic_edit <FILES>
|
||||||
|
function pic_edit() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
for file in "${@}"; do
|
||||||
|
swappy -f "${file}" -o "${file}"
|
||||||
|
done
|
||||||
|
}
|
|
@ -1,10 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Printf shortcut.
|
|
||||||
# Usage: print [TEXT]
|
|
||||||
function print() {
|
|
||||||
printf "%s" "''${*}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
5
home/program/bash/module/Print.sh
Normal file
5
home/program/bash/module/Print.sh
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Printf shortcut.
|
||||||
|
# Usage: print [TEXT]
|
||||||
|
function print() {
|
||||||
|
printf "%s" "${*}"
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Find process and filter.
|
|
||||||
# Usage: fps [PROCESS]
|
|
||||||
function fps() {
|
|
||||||
local process="''${1}"
|
|
||||||
|
|
||||||
if [[ "''${process}" = "" ]]; then
|
|
||||||
ps aux
|
|
||||||
else
|
|
||||||
ps aux | sed -n -e "1p" -e "/''${process}/Ip" | sed -e "/sed -n -e 1p -e/d"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
11
home/program/bash/module/Ps.sh
Normal file
11
home/program/bash/module/Ps.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Find process and filter.
|
||||||
|
# Usage: fps [PROCESS]
|
||||||
|
function fps() {
|
||||||
|
local process="${1}"
|
||||||
|
|
||||||
|
if [[ ${process} == "" ]]; then
|
||||||
|
ps aux
|
||||||
|
else
|
||||||
|
ps aux | sed -n -e "1p" -e "/${process}/Ip" | sed -e "/sed -n -e 1p -e/d"
|
||||||
|
fi
|
||||||
|
}
|
|
@ -1,159 +0,0 @@
|
||||||
{ config, ... }:
|
|
||||||
let
|
|
||||||
accent = "${config.module.style.color.accentR};${config.module.style.color.accentG};${config.module.style.color.accentB}";
|
|
||||||
negative = "${config.module.style.color.negativeR};${config.module.style.color.negativeG};${config.module.style.color.negativeB}";
|
|
||||||
neutral = "${config.module.style.color.neutralR};${config.module.style.color.neutralG};${config.module.style.color.neutralB}";
|
|
||||||
positive = "${config.module.style.color.positiveR};${config.module.style.color.positiveG};${config.module.style.color.positiveB}";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
export PROMPT_COMMAND=(__prompt_command "''${PROMPT_COMMAND[@]}")
|
|
||||||
|
|
||||||
function __prompt_color() {
|
|
||||||
local color="''${1}"
|
|
||||||
if [[ "''${color}" = "" ]]; then
|
|
||||||
printf "\[\x1b[0m\]"
|
|
||||||
else
|
|
||||||
printf "\[\x1b[38;2;''${color}m\]"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Custom terminal prompt format.
|
|
||||||
function __prompt_command() {
|
|
||||||
local last_status="''${?}"
|
|
||||||
local is_error=false
|
|
||||||
local is_root=false
|
|
||||||
|
|
||||||
if [[ ''${last_status} != 0 && ''${last_status} != 130 ]]; then
|
|
||||||
is_error=true
|
|
||||||
fi
|
|
||||||
if [[ "''${UID}" -eq 0 ]]; then
|
|
||||||
is_root=true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add newline.
|
|
||||||
PS1="\n"
|
|
||||||
|
|
||||||
# Set error red.
|
|
||||||
if ''${is_error}; then
|
|
||||||
PS1+="$(__prompt_color '${negative}')"
|
|
||||||
PS1+="["
|
|
||||||
else
|
|
||||||
PS1+="$(__prompt_color)"
|
|
||||||
PS1+="["
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add time.
|
|
||||||
# PS1+="$(__prompt_color '${accent}')"
|
|
||||||
# PS1+="$(date +%H:%M) "
|
|
||||||
|
|
||||||
# Set root red.
|
|
||||||
if ''${is_root}; then
|
|
||||||
PS1+="$(__prompt_color '${negative}')"
|
|
||||||
else
|
|
||||||
PS1+="$(__prompt_color '${neutral}')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add user, host and working dir.
|
|
||||||
PS1+="\u@\h "
|
|
||||||
PS1+="$(__prompt_color '${positive}')"
|
|
||||||
PS1+="\w"
|
|
||||||
# PS1+="\''${PWD}"
|
|
||||||
|
|
||||||
# Add git branch if available.
|
|
||||||
local git_branch="$(_git_current_branch)"
|
|
||||||
if [[ "''${git_branch}" != "" ]]; then
|
|
||||||
PS1+=" $(__prompt_color '${accent}')@''${git_branch}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set error red.
|
|
||||||
if ''${is_error}; then
|
|
||||||
PS1+="$(__prompt_color '${negative}')"
|
|
||||||
PS1+="] "
|
|
||||||
else
|
|
||||||
PS1+="$(__prompt_color)"
|
|
||||||
PS1+="] "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If error, show code.
|
|
||||||
if ''${is_error}; then
|
|
||||||
PS1+="$(__prompt_color '${negative}')("
|
|
||||||
PS1+="''${last_status}"
|
|
||||||
local error_type="$(_ps1error ''${last_status})"
|
|
||||||
[[ "''${error_type}" != "" ]] && PS1+=" ''${error_type}"
|
|
||||||
PS1+=")$(__prompt_color) "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Command on new line.
|
|
||||||
PS1+="\n"
|
|
||||||
|
|
||||||
# Show nix shell name or shell depth.
|
|
||||||
if [ -n "''${SHELL_NAME}" ]; then
|
|
||||||
PS1+="''${SHELL_NAME} "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show remote connections.
|
|
||||||
if [ -n "''${SSH_TTY}" ]; then
|
|
||||||
PS1+=">"
|
|
||||||
fi
|
|
||||||
|
|
||||||
PS1+="$(__prompt_color)"
|
|
||||||
|
|
||||||
# Set user tag.
|
|
||||||
if ''${is_root}; then
|
|
||||||
PS1+="# "
|
|
||||||
else
|
|
||||||
PS1+="$ "
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Reset color.
|
|
||||||
PS1+="\[\033[0m\]"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Convert error code into short description.
|
|
||||||
# Usage: _ps1error <CODE>
|
|
||||||
function _ps1error() {
|
|
||||||
local type
|
|
||||||
case ''${1} in
|
|
||||||
1) type="GENERAL" ;;
|
|
||||||
2) type="MISUSE" ;;
|
|
||||||
126) type="CANTEXEC" ;;
|
|
||||||
127) type="CMDNF" ;;
|
|
||||||
129) type="SIGHUP" ;;
|
|
||||||
130) type="SIGINT" ;;
|
|
||||||
131) type="SIGQUIT" ;;
|
|
||||||
132) type="SIGILL" ;;
|
|
||||||
133) type="SIGTRAP" ;;
|
|
||||||
134) type="SIGABRT" ;;
|
|
||||||
135) type="SIGBUS" ;;
|
|
||||||
136) type="SIGFPE" ;;
|
|
||||||
137) type="SIGKILL" ;;
|
|
||||||
138) type="SIGUSR1" ;;
|
|
||||||
139) type="SIGSEGV" ;;
|
|
||||||
140) type="SIGUSR2" ;;
|
|
||||||
141) type="SIGPIPE" ;;
|
|
||||||
142) type="SIGALRM" ;;
|
|
||||||
143) type="SIGTERM" ;;
|
|
||||||
144) type="" ;;
|
|
||||||
145) type="SIGCHLD" ;;
|
|
||||||
146) type="SIGCONT" ;;
|
|
||||||
147) type="SIGSTOP" ;;
|
|
||||||
148) type="SIGTSTP" ;;
|
|
||||||
149) type="SIGTTIN" ;;
|
|
||||||
150) type="SIGTTOU" ;;
|
|
||||||
151) type="SIGURG" ;;
|
|
||||||
152) type="SIGXCPU" ;;
|
|
||||||
153) type="SIGXFSZ" ;;
|
|
||||||
154) type="SIGVTALRM" ;;
|
|
||||||
155) type="SIGPROF" ;;
|
|
||||||
156) type="SIGWINCH" ;;
|
|
||||||
157) type="SIGIO" ;;
|
|
||||||
158) type="SIGPWR" ;;
|
|
||||||
159) type="SIGSYS" ;;
|
|
||||||
*) type="" ;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
echo -n "''${type}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
144
home/program/bash/module/Ps1.sh
Normal file
144
home/program/bash/module/Ps1.sh
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
export PROMPT_COMMAND=(__prompt_command "${PROMPT_COMMAND[@]}")
|
||||||
|
|
||||||
|
function __prompt_color() {
|
||||||
|
local color="${1}"
|
||||||
|
if [[ ${color} == "" ]]; then
|
||||||
|
printf "\[\x1b[0m\]"
|
||||||
|
else
|
||||||
|
printf "\[\x1b[38;2;${color}m\]"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Custom terminal prompt format.
|
||||||
|
function __prompt_command() {
|
||||||
|
local last_status="${?}"
|
||||||
|
local is_error=false
|
||||||
|
local is_root=false
|
||||||
|
|
||||||
|
if [[ ${last_status} != 0 && ${last_status} != 130 ]]; then
|
||||||
|
is_error=true
|
||||||
|
fi
|
||||||
|
if [[ ${UID} -eq 0 ]]; then
|
||||||
|
is_root=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add newline.
|
||||||
|
PS1="\n"
|
||||||
|
|
||||||
|
# Set error red.
|
||||||
|
if ${is_error}; then
|
||||||
|
PS1+="$(__prompt_color '@negative@')"
|
||||||
|
PS1+="["
|
||||||
|
else
|
||||||
|
PS1+="$(__prompt_color)"
|
||||||
|
PS1+="["
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set root red.
|
||||||
|
if ${is_root}; then
|
||||||
|
PS1+="$(__prompt_color '@negative@')"
|
||||||
|
else
|
||||||
|
PS1+="$(__prompt_color '@neutral@')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add user, host and working dir.
|
||||||
|
PS1+="\u@\h "
|
||||||
|
PS1+="$(__prompt_color '@positive@')"
|
||||||
|
PS1+="\w"
|
||||||
|
# PS1+="\${PWD}"
|
||||||
|
|
||||||
|
# Add git branch if available.
|
||||||
|
local git_branch="$(_git_current_branch)"
|
||||||
|
if [[ ${git_branch} != "" ]]; then
|
||||||
|
PS1+=" $(__prompt_color '@accent@')@${git_branch}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Set error red.
|
||||||
|
if ${is_error}; then
|
||||||
|
PS1+="$(__prompt_color '@negative@')"
|
||||||
|
PS1+="] "
|
||||||
|
else
|
||||||
|
PS1+="$(__prompt_color)"
|
||||||
|
PS1+="] "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If error, show code.
|
||||||
|
if ${is_error}; then
|
||||||
|
PS1+="$(__prompt_color '@negative@')("
|
||||||
|
PS1+="${last_status}"
|
||||||
|
local error_type="$(_ps1error ${last_status})"
|
||||||
|
[[ ${error_type} != "" ]] && PS1+=" ${error_type}"
|
||||||
|
PS1+=")$(__prompt_color) "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Command on new line.
|
||||||
|
PS1+="\n"
|
||||||
|
|
||||||
|
# Show nix shell name or shell depth.
|
||||||
|
if [ -n "${SHELL_NAME}" ]; then
|
||||||
|
PS1+="${SHELL_NAME} "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show remote connections.
|
||||||
|
if [ -n "${SSH_TTY}" ]; then
|
||||||
|
PS1+=">"
|
||||||
|
fi
|
||||||
|
|
||||||
|
PS1+="$(__prompt_color)"
|
||||||
|
|
||||||
|
# Set user tag.
|
||||||
|
if ${is_root}; then
|
||||||
|
PS1+="# "
|
||||||
|
else
|
||||||
|
PS1+="$ "
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Reset color.
|
||||||
|
PS1+="\[\033[0m\]"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Convert error code into short description.
|
||||||
|
# Usage: _ps1error <CODE>
|
||||||
|
function _ps1error() {
|
||||||
|
local type
|
||||||
|
case ${1} in
|
||||||
|
1) type="GENERAL" ;;
|
||||||
|
2) type="MISUSE" ;;
|
||||||
|
126) type="CANTEXEC" ;;
|
||||||
|
127) type="CMDNF" ;;
|
||||||
|
129) type="SIGHUP" ;;
|
||||||
|
130) type="SIGINT" ;;
|
||||||
|
131) type="SIGQUIT" ;;
|
||||||
|
132) type="SIGILL" ;;
|
||||||
|
133) type="SIGTRAP" ;;
|
||||||
|
134) type="SIGABRT" ;;
|
||||||
|
135) type="SIGBUS" ;;
|
||||||
|
136) type="SIGFPE" ;;
|
||||||
|
137) type="SIGKILL" ;;
|
||||||
|
138) type="SIGUSR1" ;;
|
||||||
|
139) type="SIGSEGV" ;;
|
||||||
|
140) type="SIGUSR2" ;;
|
||||||
|
141) type="SIGPIPE" ;;
|
||||||
|
142) type="SIGALRM" ;;
|
||||||
|
143) type="SIGTERM" ;;
|
||||||
|
144) type="" ;;
|
||||||
|
145) type="SIGCHLD" ;;
|
||||||
|
146) type="SIGCONT" ;;
|
||||||
|
147) type="SIGSTOP" ;;
|
||||||
|
148) type="SIGTSTP" ;;
|
||||||
|
149) type="SIGTTIN" ;;
|
||||||
|
150) type="SIGTTOU" ;;
|
||||||
|
151) type="SIGURG" ;;
|
||||||
|
152) type="SIGXCPU" ;;
|
||||||
|
153) type="SIGXFSZ" ;;
|
||||||
|
154) type="SIGVTALRM" ;;
|
||||||
|
155) type="SIGPROF" ;;
|
||||||
|
156) type="SIGWINCH" ;;
|
||||||
|
157) type="SIGIO" ;;
|
||||||
|
158) type="SIGPWR" ;;
|
||||||
|
159) type="SIGSYS" ;;
|
||||||
|
*) type="" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
echo -n "${type}"
|
||||||
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
function qr() {
|
|
||||||
qrencode -t ansiutf8
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
3
home/program/bash/module/Qr.sh
Normal file
3
home/program/bash/module/Qr.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
function qr() {
|
||||||
|
qrencode -t ansiutf8
|
||||||
|
}
|
|
@ -1,16 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Adjust ryzen temp limit.
|
|
||||||
# Usage: radj [TEMP]
|
|
||||||
function radj() {
|
|
||||||
local limit="''${1}"
|
|
||||||
if [[ "''${limit}" = "" ]]; then
|
|
||||||
systemctl start radj.service
|
|
||||||
else
|
|
||||||
systemctl stop radj.service
|
|
||||||
ryzenadj --tctl-temp=''${limit}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
11
home/program/bash/module/Radj.sh
Normal file
11
home/program/bash/module/Radj.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
# Adjust ryzen temp limit.
|
||||||
|
# Usage: radj [TEMP]
|
||||||
|
function radj() {
|
||||||
|
local limit="${1}"
|
||||||
|
if [[ ${limit} == "" ]]; then
|
||||||
|
systemctl start radj.service
|
||||||
|
else
|
||||||
|
systemctl stop radj.service
|
||||||
|
ryzenadj --tctl-temp=${limit}
|
||||||
|
fi
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Generate random string.
|
|
||||||
# Usage: random <LENGTH>
|
|
||||||
function random() {
|
|
||||||
local length="''${1}"
|
|
||||||
if [[ "''${length}" = "" ]]; then
|
|
||||||
help random
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
head /dev/urandom | tr -dc A-Za-z0-9 | head -c''${length}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Picks a random file or directory.
|
|
||||||
function random_file() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local dirs=($(ls))
|
|
||||||
local total=''${#dirs[@]}
|
|
||||||
((total--))
|
|
||||||
local index=$(shuf -i 0-''${total} -n 1)
|
|
||||||
|
|
||||||
printf "%s" ''${dirs[$index]}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
21
home/program/bash/module/Random.sh
Normal file
21
home/program/bash/module/Random.sh
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Generate random string.
|
||||||
|
# Usage: random <LENGTH>
|
||||||
|
function random() {
|
||||||
|
local length="${1}"
|
||||||
|
if [[ ${length} == "" ]]; then
|
||||||
|
help random
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
head /dev/urandom | tr -dc A-Za-z0-9 | head -c${length}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Picks a random file or directory.
|
||||||
|
function random_file() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local dirs=($(ls))
|
||||||
|
local total=${#dirs[@]}
|
||||||
|
((total--))
|
||||||
|
local index=$(shuf -i 0-${total} -n 1)
|
||||||
|
|
||||||
|
printf "%s" ${dirs[$index]}
|
||||||
|
}
|
|
@ -1,85 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Run something recursively over all directories.
|
|
||||||
# Usage: recursive <COMMAND>
|
|
||||||
function recursive() {
|
|
||||||
if [[ "''${*}" = "" ]]; then
|
|
||||||
help recursive
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local IFS=$'\n'
|
|
||||||
local current="''${PWD}"
|
|
||||||
local dirs=$(find -type d)
|
|
||||||
local total=$(find -type d | wc -l) # TODO: don't call find twice. won't work with "echo ''${dirs}".
|
|
||||||
local count=0
|
|
||||||
local failed=0
|
|
||||||
|
|
||||||
for dir in ''${dirs}; do
|
|
||||||
# increment counter.
|
|
||||||
((count++))
|
|
||||||
|
|
||||||
# cd into the next dir.
|
|
||||||
cd "''${current}" || failed=''${?}
|
|
||||||
cd "''${dir}" || failed=''${?}
|
|
||||||
|
|
||||||
# echo status.
|
|
||||||
echo -e "''${color_bblue}[''${count}/''${total}] ''${dir}''${color_default}"
|
|
||||||
|
|
||||||
# run command.
|
|
||||||
''${*} || failed=''${?}
|
|
||||||
|
|
||||||
# Add newline if not the last one.
|
|
||||||
[[ "''${count}" = "''${total}" ]] || echo
|
|
||||||
done
|
|
||||||
|
|
||||||
# return back on complete.
|
|
||||||
cd "''${current}" || failed=''${?}
|
|
||||||
|
|
||||||
return ''${failed}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run something recursively over directories of 1 depth (excluding current dir).
|
|
||||||
# Usage: recursive1 <COMMAND>
|
|
||||||
function recursive1() {
|
|
||||||
if [[ "''${*}" = "" ]]; then
|
|
||||||
help recursive1
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local IFS=$'\n'
|
|
||||||
local current="''${PWD}"
|
|
||||||
local dirs=$(find -mindepth 1 -maxdepth 1 -type d)
|
|
||||||
local total=$(find -mindepth 1 -maxdepth 1 -type d | wc -l) # TODO: don't call find twice. won't work with "echo ''${dirs}".
|
|
||||||
local count=0
|
|
||||||
local failed=0
|
|
||||||
|
|
||||||
for dir in ''${dirs}; do
|
|
||||||
# increment counter.
|
|
||||||
((count++))
|
|
||||||
|
|
||||||
# cd into the next dir.
|
|
||||||
cd "''${current}"
|
|
||||||
cd "''${dir}"
|
|
||||||
|
|
||||||
# echo status.
|
|
||||||
echo -e "''${color_bblue}[''${count}/''${total}] ''${dir}''${color_default}"
|
|
||||||
|
|
||||||
# run command.
|
|
||||||
''${*} || failed=''${?}
|
|
||||||
|
|
||||||
# Add newline if not the last one.
|
|
||||||
[[ "''${count}" = "''${total}" ]] || echo
|
|
||||||
done
|
|
||||||
|
|
||||||
# return back on complete.
|
|
||||||
cd "''${current}"
|
|
||||||
|
|
||||||
return ''${failed}
|
|
||||||
}
|
|
||||||
|
|
||||||
# autocomplete.
|
|
||||||
complete -F _autocomplete_nested recursive recursive1
|
|
||||||
'';
|
|
||||||
}
|
|
80
home/program/bash/module/Recursive.sh
Normal file
80
home/program/bash/module/Recursive.sh
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
# Run something recursively over all directories.
|
||||||
|
# Usage: recursive <COMMAND>
|
||||||
|
function recursive() {
|
||||||
|
if [[ ${*} == "" ]]; then
|
||||||
|
help recursive
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local IFS=$'\n'
|
||||||
|
local current="${PWD}"
|
||||||
|
local dirs=$(find -type d)
|
||||||
|
local total=$(find -type d | wc -l) # TODO: don't call find twice. won't work with "echo ${dirs}".
|
||||||
|
local count=0
|
||||||
|
local failed=0
|
||||||
|
|
||||||
|
for dir in ${dirs}; do
|
||||||
|
# increment counter.
|
||||||
|
((count++))
|
||||||
|
|
||||||
|
# cd into the next dir.
|
||||||
|
cd "${current}" || failed=${?}
|
||||||
|
cd "${dir}" || failed=${?}
|
||||||
|
|
||||||
|
# echo status.
|
||||||
|
echo -e "${color_bblue}[${count}/${total}] ${dir}${color_default}"
|
||||||
|
|
||||||
|
# run command.
|
||||||
|
${*} || failed=${?}
|
||||||
|
|
||||||
|
# Add newline if not the last one.
|
||||||
|
[[ ${count} == "${total}" ]] || echo
|
||||||
|
done
|
||||||
|
|
||||||
|
# return back on complete.
|
||||||
|
cd "${current}" || failed=${?}
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run something recursively over directories of 1 depth (excluding current dir).
|
||||||
|
# Usage: recursive1 <COMMAND>
|
||||||
|
function recursive1() {
|
||||||
|
if [[ ${*} == "" ]]; then
|
||||||
|
help recursive1
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local IFS=$'\n'
|
||||||
|
local current="${PWD}"
|
||||||
|
local dirs=$(find -mindepth 1 -maxdepth 1 -type d)
|
||||||
|
local total=$(find -mindepth 1 -maxdepth 1 -type d | wc -l) # TODO: don't call find twice. won't work with "echo ${dirs}".
|
||||||
|
local count=0
|
||||||
|
local failed=0
|
||||||
|
|
||||||
|
for dir in ${dirs}; do
|
||||||
|
# increment counter.
|
||||||
|
((count++))
|
||||||
|
|
||||||
|
# cd into the next dir.
|
||||||
|
cd "${current}"
|
||||||
|
cd "${dir}"
|
||||||
|
|
||||||
|
# echo status.
|
||||||
|
echo -e "${color_bblue}[${count}/${total}] ${dir}${color_default}"
|
||||||
|
|
||||||
|
# run command.
|
||||||
|
${*} || failed=${?}
|
||||||
|
|
||||||
|
# Add newline if not the last one.
|
||||||
|
[[ ${count} == "${total}" ]] || echo
|
||||||
|
done
|
||||||
|
|
||||||
|
# return back on complete.
|
||||||
|
cd "${current}"
|
||||||
|
|
||||||
|
return ${failed}
|
||||||
|
}
|
||||||
|
|
||||||
|
# autocomplete.
|
||||||
|
complete -F _autocomplete_nested recursive recursive1
|
|
@ -1,9 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
function reload() {
|
|
||||||
source ~/.bashrc
|
|
||||||
}
|
|
||||||
trap reload USR1
|
|
||||||
'';
|
|
||||||
}
|
|
4
home/program/bash/module/Reload.sh
Normal file
4
home/program/bash/module/Reload.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
function reload() {
|
||||||
|
source ~/.bashrc
|
||||||
|
}
|
||||||
|
trap reload USR1
|
|
@ -1,28 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
shopt -s dotglob
|
|
||||||
shopt -s globstar
|
|
||||||
shopt -s autocd
|
|
||||||
shopt -s extglob
|
|
||||||
|
|
||||||
# Enable vim mode.
|
|
||||||
bind 'set editing-mode vi'
|
|
||||||
bind 'set show-mode-in-prompt on'
|
|
||||||
bind 'set keyseq-timeout 0'
|
|
||||||
|
|
||||||
# Set the mode string and cursor to indicate the vim mode
|
|
||||||
# For the number after `\e[`:
|
|
||||||
# 0: blinking block
|
|
||||||
# 1: blinking block (default)
|
|
||||||
# 2: steady block
|
|
||||||
# 3: blinking underline
|
|
||||||
# 4: steady underline
|
|
||||||
# 5: blinking bar (xterm)
|
|
||||||
# 6: steady bar (xterm)
|
|
||||||
bind 'set vi-ins-mode-string \1\e[6 q\2'
|
|
||||||
bind 'set vi-cmd-mode-string \1\e[2 q\2'
|
|
||||||
|
|
||||||
exec {BASH_XTRACEFD}>/dev/null
|
|
||||||
'';
|
|
||||||
}
|
|
23
home/program/bash/module/Shopt.sh
Normal file
23
home/program/bash/module/Shopt.sh
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
shopt -s dotglob
|
||||||
|
shopt -s globstar
|
||||||
|
shopt -s autocd
|
||||||
|
shopt -s extglob
|
||||||
|
|
||||||
|
# Enable vim mode.
|
||||||
|
bind 'set editing-mode vi'
|
||||||
|
bind 'set show-mode-in-prompt on'
|
||||||
|
bind 'set keyseq-timeout 0'
|
||||||
|
|
||||||
|
# Set the mode string and cursor to indicate the vim mode
|
||||||
|
# For the number after `\e[`:
|
||||||
|
# 0: blinking block
|
||||||
|
# 1: blinking block (default)
|
||||||
|
# 2: steady block
|
||||||
|
# 3: blinking underline
|
||||||
|
# 4: steady underline
|
||||||
|
# 5: blinking bar (xterm)
|
||||||
|
# 6: steady bar (xterm)
|
||||||
|
bind 'set vi-ins-mode-string \1\e[6 q\2'
|
||||||
|
bind 'set vi-cmd-mode-string \1\e[2 q\2'
|
||||||
|
|
||||||
|
exec {BASH_XTRACEFD}>/dev/null
|
|
@ -1,9 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Kill all ssh sockets.
|
|
||||||
function sshka() {
|
|
||||||
rm ~/.ssh/*.socket
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
4
home/program/bash/module/Ssh.sh
Normal file
4
home/program/bash/module/Ssh.sh
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Kill all ssh sockets.
|
||||||
|
function sshka() {
|
||||||
|
rm ~/.ssh/*.socket
|
||||||
|
}
|
|
@ -1,35 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Su shortcut for lazy me.
|
|
||||||
# Root by default.
|
|
||||||
# Usage: s [USER]
|
|
||||||
function s() {
|
|
||||||
su - ''${1}
|
|
||||||
}
|
|
||||||
alias su="SHELL_NAME=su su"
|
|
||||||
|
|
||||||
# Run something as root. Runs command as a current user if su is not available.
|
|
||||||
# Usage: sudo <COMMAND>
|
|
||||||
function sudo() {
|
|
||||||
if command -v su &> /dev/null; then
|
|
||||||
su -c "$(echo ''${*} | tr '\n' ' ')"
|
|
||||||
else
|
|
||||||
''${*}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Run something as current user. If fails, try to run with sudo.
|
|
||||||
# Usage: trysudo <COMMAND>
|
|
||||||
function trysudo() {
|
|
||||||
''${*} || sudo ''${*}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _complete_s() {
|
|
||||||
_autocomplete $(_get_users)
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _complete_s s
|
|
||||||
complete -F _autocomplete_nested sudo trysudo
|
|
||||||
'';
|
|
||||||
}
|
|
30
home/program/bash/module/Su.sh
Normal file
30
home/program/bash/module/Su.sh
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
# Su shortcut for lazy me.
|
||||||
|
# Root by default.
|
||||||
|
# Usage: s [USER]
|
||||||
|
function s() {
|
||||||
|
su - ${1}
|
||||||
|
}
|
||||||
|
alias su="SHELL_NAME=su su"
|
||||||
|
|
||||||
|
# Run something as root. Runs command as a current user if su is not available.
|
||||||
|
# Usage: sudo <COMMAND>
|
||||||
|
function sudo() {
|
||||||
|
if command -v su &>/dev/null; then
|
||||||
|
su -c "$(echo ${*} | tr '\n' ' ')"
|
||||||
|
else
|
||||||
|
${*}
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run something as current user. If fails, try to run with sudo.
|
||||||
|
# Usage: trysudo <COMMAND>
|
||||||
|
function trysudo() {
|
||||||
|
${*} || sudo ${*}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _complete_s() {
|
||||||
|
_autocomplete $(_get_users)
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _complete_s s
|
||||||
|
complete -F _autocomplete_nested sudo trysudo
|
|
@ -1,46 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Install on a Nintendo Switch.
|
|
||||||
# Usage: switch_install <FILES>
|
|
||||||
function switch_install() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local targets=(''${@})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=(*.ns[pz])
|
|
||||||
|
|
||||||
local id=$(_switch_id)
|
|
||||||
_switch_mount
|
|
||||||
|
|
||||||
install() {
|
|
||||||
gio copy -p "''${target}" ''${id}5:\ SD\ Card\ install/
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets install ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Backup a Nintendo Switch saves and album.
|
|
||||||
function switch_backup() {
|
|
||||||
local id=$(_switch_id)
|
|
||||||
_switch_mount
|
|
||||||
mkdir switch_backup || rm -r switch_backup/*
|
|
||||||
mkdir switch_backup/{save,album}
|
|
||||||
pushd switch_backup/save
|
|
||||||
cp -r /run/user/''${UID}/gvfs/mtp\:host\=-_DBI_*/7\:\ Saves/* .
|
|
||||||
popd
|
|
||||||
pushd switch_backup/album
|
|
||||||
cp -r /run/user/''${UID}/gvfs/mtp\:host\=-_DBI_*/8\:\ Album/* .
|
|
||||||
popd
|
|
||||||
pushd switch_backup
|
|
||||||
archive_fast album
|
|
||||||
archive save
|
|
||||||
}
|
|
||||||
|
|
||||||
function _switch_id() {
|
|
||||||
gio mount -l -i | rg 'mtp://-_DBI_' | sed "s/^.*=//" | head -1
|
|
||||||
}
|
|
||||||
|
|
||||||
function _switch_mount() {
|
|
||||||
test -d /run/user/''${UID}/gvfs/mtp\:host\=-_DBI_* || gio mount "$(_switch_id)"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
41
home/program/bash/module/Switch.sh
Normal file
41
home/program/bash/module/Switch.sh
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# Install on a Nintendo Switch.
|
||||||
|
# Usage: switch_install <FILES>
|
||||||
|
function switch_install() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local targets=(${@})
|
||||||
|
[[ ${targets} == "" ]] && targets=("*.ns[pz]")
|
||||||
|
|
||||||
|
local id=$(_switch_id)
|
||||||
|
_switch_mount
|
||||||
|
|
||||||
|
install() {
|
||||||
|
gio copy -p "${target}" ${id}5:\ SD\ Card\ install/
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets install ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Backup a Nintendo Switch saves and album.
|
||||||
|
function switch_backup() {
|
||||||
|
local id=$(_switch_id)
|
||||||
|
_switch_mount
|
||||||
|
mkdir switch_backup || rm -r switch_backup/*
|
||||||
|
mkdir switch_backup/{save,album}
|
||||||
|
pushd switch_backup/save
|
||||||
|
cp -r /run/user/${UID}/gvfs/mtp\:host\=-_DBI_*/7\:\ Saves/* .
|
||||||
|
popd
|
||||||
|
pushd switch_backup/album
|
||||||
|
cp -r /run/user/${UID}/gvfs/mtp\:host\=-_DBI_*/8\:\ Album/* .
|
||||||
|
popd
|
||||||
|
pushd switch_backup
|
||||||
|
archive_fast album
|
||||||
|
archive save
|
||||||
|
}
|
||||||
|
|
||||||
|
function _switch_id() {
|
||||||
|
gio mount -l -i | rg 'mtp://-_DBI_' | sed "s/^.*=//" | head -1
|
||||||
|
}
|
||||||
|
|
||||||
|
function _switch_mount() {
|
||||||
|
test -d /run/user/${UID}/gvfs/mtp\:host\=-_DBI_* || gio mount "$(_switch_id)"
|
||||||
|
}
|
|
@ -1,99 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Create/attach to named session.
|
|
||||||
# By default uses current dir name.
|
|
||||||
# Usage: ta [NAME]
|
|
||||||
function ta() {
|
|
||||||
local name="''${1}"
|
|
||||||
|
|
||||||
# Set default name.
|
|
||||||
# [[ "''${name}" = "" ]] && name="main"
|
|
||||||
[[ "''${name}" = "" ]] && name=$(parse_alnum "''${PWD##*/}")
|
|
||||||
|
|
||||||
# Create session.
|
|
||||||
tmux new-session -s "''${name}" -d &> /dev/null
|
|
||||||
|
|
||||||
# Attach to session.
|
|
||||||
if _is_tmux; then
|
|
||||||
tmux switch-client -t "''${name}"
|
|
||||||
else
|
|
||||||
tmux attach-session -t "''${name}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Detach from running session.
|
|
||||||
function td() {
|
|
||||||
tmux detach-client
|
|
||||||
}
|
|
||||||
|
|
||||||
# Detach all other tmux clients.
|
|
||||||
function tda() {
|
|
||||||
tmux detach-client -s $(tmux display-message -p '#S')
|
|
||||||
}
|
|
||||||
|
|
||||||
# List running sessions.
|
|
||||||
function tl() {
|
|
||||||
tmux list-sessions
|
|
||||||
}
|
|
||||||
|
|
||||||
# Assign name to session. Uses current dir name by default.
|
|
||||||
# Usage: tns [NAME]
|
|
||||||
function tns() {
|
|
||||||
local name="''${1}"
|
|
||||||
|
|
||||||
[[ "''${name}" = "" ]] && name=$(parse_alnum "''${PWD##*/}")
|
|
||||||
|
|
||||||
tmux rename-session "''${name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Assign name to window. Uses current dir name by default.
|
|
||||||
# Usage: tnw [NAME]
|
|
||||||
function tnw() {
|
|
||||||
local name="''${1}"
|
|
||||||
|
|
||||||
[[ "''${name}" = "" ]] && name=$(parse_alnum "''${PWD##*/}")
|
|
||||||
|
|
||||||
tmux rename-window "''${name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kill specified session.
|
|
||||||
# By default uses current dir name.
|
|
||||||
# Usage: tk [NAME]
|
|
||||||
function tk() {
|
|
||||||
local name="''${1}"
|
|
||||||
|
|
||||||
[[ "''${name}" = "" ]] && name=$(parse_alnum "''${PWD##*/}")
|
|
||||||
|
|
||||||
tmux kill-session -t "''${name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kill all sessions.
|
|
||||||
function tka() {
|
|
||||||
local sessions=$(tmux list-sessions | sed -e 's/:.*//')
|
|
||||||
|
|
||||||
for session in $sessions; do
|
|
||||||
tmux kill-session -t "$session"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with running sessions once.
|
|
||||||
function _complete_tmux_session() {
|
|
||||||
_autocomplete "$(tmux list-sessions 2> /dev/null | sed -e 's/:.*//')"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with running sessions.
|
|
||||||
function _complete_tmux_sessions() {
|
|
||||||
_autocomplete "$(tmux list-sessions 2> /dev/null | sed -e 's/:.*//')"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Autocomplete with current dir name and dirs inside this one.
|
|
||||||
function _complete_tmux_name() {
|
|
||||||
_autocomplete "''${PWD##*/}"$'\n'$(ls --classify | grep /$ | sed -e 's/\/$//')
|
|
||||||
}
|
|
||||||
|
|
||||||
complete -F _complete_tmux_session ta
|
|
||||||
complete -F _complete_tmux_sessions tk
|
|
||||||
complete -o nosort -F _complete_tmux_name tns tnw
|
|
||||||
'';
|
|
||||||
}
|
|
94
home/program/bash/module/Tmux.sh
Normal file
94
home/program/bash/module/Tmux.sh
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
# Create/attach to named session.
|
||||||
|
# By default uses current dir name.
|
||||||
|
# Usage: ta [NAME]
|
||||||
|
function ta() {
|
||||||
|
local name="${1}"
|
||||||
|
|
||||||
|
# Set default name.
|
||||||
|
# [[ "${name}" = "" ]] && name="main"
|
||||||
|
[[ ${name} == "" ]] && name=$(parse_alnum "${PWD##*/}")
|
||||||
|
|
||||||
|
# Create session.
|
||||||
|
tmux new-session -s "${name}" -d &>/dev/null
|
||||||
|
|
||||||
|
# Attach to session.
|
||||||
|
if _is_tmux; then
|
||||||
|
tmux switch-client -t "${name}"
|
||||||
|
else
|
||||||
|
tmux attach-session -t "${name}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detach from running session.
|
||||||
|
function td() {
|
||||||
|
tmux detach-client
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detach all other tmux clients.
|
||||||
|
function tda() {
|
||||||
|
tmux detach-client -s $(tmux display-message -p '#S')
|
||||||
|
}
|
||||||
|
|
||||||
|
# List running sessions.
|
||||||
|
function tl() {
|
||||||
|
tmux list-sessions
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assign name to session. Uses current dir name by default.
|
||||||
|
# Usage: tns [NAME]
|
||||||
|
function tns() {
|
||||||
|
local name="${1}"
|
||||||
|
|
||||||
|
[[ ${name} == "" ]] && name=$(parse_alnum "${PWD##*/}")
|
||||||
|
|
||||||
|
tmux rename-session "${name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Assign name to window. Uses current dir name by default.
|
||||||
|
# Usage: tnw [NAME]
|
||||||
|
function tnw() {
|
||||||
|
local name="${1}"
|
||||||
|
|
||||||
|
[[ ${name} == "" ]] && name=$(parse_alnum "${PWD##*/}")
|
||||||
|
|
||||||
|
tmux rename-window "${name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kill specified session.
|
||||||
|
# By default uses current dir name.
|
||||||
|
# Usage: tk [NAME]
|
||||||
|
function tk() {
|
||||||
|
local name="${1}"
|
||||||
|
|
||||||
|
[[ ${name} == "" ]] && name=$(parse_alnum "${PWD##*/}")
|
||||||
|
|
||||||
|
tmux kill-session -t "${name}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Kill all sessions.
|
||||||
|
function tka() {
|
||||||
|
local sessions=$(tmux list-sessions | sed -e 's/:.*//')
|
||||||
|
|
||||||
|
for session in $sessions; do
|
||||||
|
tmux kill-session -t "$session"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with running sessions once.
|
||||||
|
function _complete_tmux_session() {
|
||||||
|
_autocomplete "$(tmux list-sessions 2>/dev/null | sed -e 's/:.*//')"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with running sessions.
|
||||||
|
function _complete_tmux_sessions() {
|
||||||
|
_autocomplete "$(tmux list-sessions 2>/dev/null | sed -e 's/:.*//')"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Autocomplete with current dir name and dirs inside this one.
|
||||||
|
function _complete_tmux_name() {
|
||||||
|
_autocomplete "${PWD##*/}"$'\n'$(ls --classify | grep /$ | sed -e 's/\/$//')
|
||||||
|
}
|
||||||
|
|
||||||
|
complete -F _complete_tmux_session ta
|
||||||
|
complete -F _complete_tmux_sessions tk
|
||||||
|
complete -o nosort -F _complete_tmux_name tns tnw
|
|
@ -1,109 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Convert between different formats.
|
|
||||||
# By default tries to convert all files.
|
|
||||||
# Usage: transcode <FORMAT> [FILES]
|
|
||||||
function transcode() { local IFS=$'\n'
|
|
||||||
local format=''${1}
|
|
||||||
local targets=(''${@:2})
|
|
||||||
[[ "''${targets}" = "" ]] && targets=($(_ls_file))
|
|
||||||
|
|
||||||
# Report no format.
|
|
||||||
if [[ "''${format}" = "" ]] || [[ "''${format}" =~ "." ]]; then
|
|
||||||
_error "No format specified."
|
|
||||||
help transcode
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
process() {
|
|
||||||
# Define context names and status.
|
|
||||||
local from="''${target##*.}"
|
|
||||||
local to="''${format}"
|
|
||||||
local output="''${target##*/}"
|
|
||||||
output="''${output%.*}.''${to}"
|
|
||||||
|
|
||||||
# Skip if file exists.
|
|
||||||
[[ -f "''${output}" ]] && { _iterate_skip "Already exists."; return 0; }
|
|
||||||
|
|
||||||
# Support multiple inputs.
|
|
||||||
[[ "''${to}" = "flac" ]] && from=""
|
|
||||||
[[ "''${to}" = "jxl" ]] && from=""
|
|
||||||
[[ "''${to}" = "mka" ]] && from=""
|
|
||||||
[[ "''${to}" = "mkv" ]] && from=""
|
|
||||||
[[ "''${to}" = "mp3" ]] && from=""
|
|
||||||
|
|
||||||
# Send convert.
|
|
||||||
case "''${from}-''${to}" in
|
|
||||||
"gz-xz"|"tgz-txz")
|
|
||||||
_transcode_gz-xz "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"xz-gz"|"txz-tgz")
|
|
||||||
_transcode_xz-gz "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"-mp3")
|
|
||||||
_transcode_mp3 "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"-flac")
|
|
||||||
_transcode_flac "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"-mka")
|
|
||||||
_transcode_mka "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"-mkv")
|
|
||||||
_transcode_mkv "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
"-jxl")
|
|
||||||
_transcode_jxl "''${target}" "''${output}"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
_error "Conversion ''${target##*.}-''${to} not supported."
|
|
||||||
return 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_iterate_targets process ''${targets[@]}
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_gz-xz() {
|
|
||||||
[[ -f "''${2}" ]] && return 1
|
|
||||||
pv "''${1}" | gzip -d | xz -9e > "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_xz-gz() {
|
|
||||||
[[ -f "''${2}" ]] && return 1
|
|
||||||
pv "''${1}" | xz -d | gzip -1 > "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_mp3() {
|
|
||||||
ffmpeg -n -i "''${1}" -c:a libmp3lame -b:a 320k -f mp3 "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_flac() {
|
|
||||||
ffmpeg -n -i "''${1}" -c:a flac -f flac "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_mka() {
|
|
||||||
local braudio=$(_ffprobe_ba "''${1}")
|
|
||||||
[[ ''${braudio} -gt 128 ]] && braudio=128
|
|
||||||
|
|
||||||
ffmpeg -n -i "''${1}" -ac 2 -c:a libopus -b:a ''${braudio}k -vn "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_mkv() {
|
|
||||||
local keyint=$(_ffprobe_keyint "''${1}")
|
|
||||||
local braudio=$(_ffprobe_ba "''${1}")
|
|
||||||
local fps=$(_ffprobe_fps "''${1}")
|
|
||||||
[[ ''${braudio} -gt 128 ]] && braudio=128
|
|
||||||
[[ ''${fps} -gt 30 ]] && fps=30
|
|
||||||
|
|
||||||
# ffmpeg -n -i "''${1}" -c:a libopus -b:a ''${braudio}k -c:v libsvtav1 -crf 30 -svtav1-params "fast-decode=1:tune=0" -preset 8 -pix_fmt yuv420p10le -g ''${keyint} -vf "scale=-2:min'(1080,ih)'" "''${2}"
|
|
||||||
ffmpeg -n -i "''${1}" -map 0 -map -v -map V -map -t -dn -c:s srt -ac 2 -c:a libopus -b:a ''${braudio}k -c:v libsvtav1 -crf 30 -svtav1-params "tune=0" -pix_fmt yuv420p10le -g ''${keyint} -vf "scale=-2:min'(1080,ih)' , fps=''${fps}" "''${2}"
|
|
||||||
}
|
|
||||||
|
|
||||||
function _transcode_jxl() {
|
|
||||||
cjxl -e 10 --lossless_jpeg=1 -- "''${1}" "''${2}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
108
home/program/bash/module/Transcode.sh
Normal file
108
home/program/bash/module/Transcode.sh
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# Convert between different formats.
|
||||||
|
# By default tries to convert all files.
|
||||||
|
# Usage: transcode <FORMAT> [FILES]
|
||||||
|
function transcode() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local format=${1}
|
||||||
|
local targets=(${@:2})
|
||||||
|
[[ ${targets} == "" ]] && targets=($(_ls_file))
|
||||||
|
|
||||||
|
# Report no format.
|
||||||
|
if [[ ${format} == "" ]] || [[ ${format} =~ "." ]]; then
|
||||||
|
_error "No format specified."
|
||||||
|
help transcode
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
process() {
|
||||||
|
# Define context names and status.
|
||||||
|
local from="${target##*.}"
|
||||||
|
local to="${format}"
|
||||||
|
local output="${target##*/}"
|
||||||
|
output="${output%.*}.${to}"
|
||||||
|
|
||||||
|
# Skip if file exists.
|
||||||
|
[[ -f ${output} ]] && {
|
||||||
|
_iterate_skip "Already exists."
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Support multiple inputs.
|
||||||
|
[[ ${to} == "flac" ]] && from=""
|
||||||
|
[[ ${to} == "jxl" ]] && from=""
|
||||||
|
[[ ${to} == "mka" ]] && from=""
|
||||||
|
[[ ${to} == "mkv" ]] && from=""
|
||||||
|
[[ ${to} == "mp3" ]] && from=""
|
||||||
|
|
||||||
|
# Send convert.
|
||||||
|
case "${from}-${to}" in
|
||||||
|
"gz-xz" | "tgz-txz")
|
||||||
|
_transcode_gz-xz "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"xz-gz" | "txz-tgz")
|
||||||
|
_transcode_xz-gz "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"-mp3")
|
||||||
|
_transcode_mp3 "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"-flac")
|
||||||
|
_transcode_flac "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"-mka")
|
||||||
|
_transcode_mka "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"-mkv")
|
||||||
|
_transcode_mkv "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
"-jxl")
|
||||||
|
_transcode_jxl "${target}" "${output}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_error "Conversion ${target##*.}-${to} not supported."
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
_iterate_targets process ${targets[@]}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_gz-xz() {
|
||||||
|
[[ -f ${2} ]] && return 1
|
||||||
|
pv "${1}" | gzip -d | xz -9e >"${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_xz-gz() {
|
||||||
|
[[ -f ${2} ]] && return 1
|
||||||
|
pv "${1}" | xz -d | gzip -1 >"${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_mp3() {
|
||||||
|
ffmpeg -n -i "${1}" -c:a libmp3lame -b:a 320k -f mp3 "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_flac() {
|
||||||
|
ffmpeg -n -i "${1}" -c:a flac -f flac "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_mka() {
|
||||||
|
local braudio=$(_ffprobe_ba "${1}")
|
||||||
|
[[ ${braudio} -gt 128 ]] && braudio=128
|
||||||
|
|
||||||
|
ffmpeg -n -i "${1}" -ac 2 -c:a libopus -b:a ${braudio}k -vn "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_mkv() {
|
||||||
|
local keyint=$(_ffprobe_keyint "${1}")
|
||||||
|
local braudio=$(_ffprobe_ba "${1}")
|
||||||
|
local fps=$(_ffprobe_fps "${1}")
|
||||||
|
[[ ${braudio} -gt 128 ]] && braudio=128
|
||||||
|
[[ ${fps} -gt 30 ]] && fps=30
|
||||||
|
|
||||||
|
# ffmpeg -n -i "${1}" -c:a libopus -b:a ${braudio}k -c:v libsvtav1 -crf 30 -svtav1-params "fast-decode=1:tune=0" -preset 8 -pix_fmt yuv420p10le -g ${keyint} -vf "scale=-2:min'(1080,ih)'" "${2}"
|
||||||
|
ffmpeg -n -i "${1}" -map 0 -map -v -map V -map -t -dn -c:s srt -ac 2 -c:a libopus -b:a ${braudio}k -c:v libsvtav1 -crf 30 -svtav1-params "tune=0" -pix_fmt yuv420p10le -g ${keyint} -vf "scale=-2:min'(1080,ih)' , fps=${fps}" "${2}"
|
||||||
|
}
|
||||||
|
|
||||||
|
function _transcode_jxl() {
|
||||||
|
cjxl -e 10 --lossless_jpeg=1 -- "${1}" "${2}"
|
||||||
|
}
|
|
@ -1,26 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Retry command every 2 sec until it completes successfully.
|
|
||||||
# Usage: try <COMMAND>
|
|
||||||
function try() {
|
|
||||||
if [[ "''${*}" = "" ]]; then
|
|
||||||
help try
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
local result=-1
|
|
||||||
|
|
||||||
while [ "$result" != 0 ]; do
|
|
||||||
''${*}
|
|
||||||
result=$?
|
|
||||||
if [ "$result" != 0 ]; then
|
|
||||||
sleep 2
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# autocomplete.
|
|
||||||
complete -F _autocomplete_nested try
|
|
||||||
'';
|
|
||||||
}
|
|
21
home/program/bash/module/Try.sh
Normal file
21
home/program/bash/module/Try.sh
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Retry command every 2 sec until it completes successfully.
|
||||||
|
# Usage: try <COMMAND>
|
||||||
|
function try() {
|
||||||
|
if [[ ${*} == "" ]]; then
|
||||||
|
help try
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
local result=-1
|
||||||
|
|
||||||
|
while [ "$result" != 0 ]; do
|
||||||
|
${*}
|
||||||
|
result=$?
|
||||||
|
if [ "$result" != 0 ]; then
|
||||||
|
sleep 2
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# autocomplete.
|
||||||
|
complete -F _autocomplete_nested try
|
|
@ -1,159 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Get the number of avaialble cores (threads).
|
|
||||||
function _core_count() {
|
|
||||||
cat /proc/cpuinfo | grep ^processor | wc -l
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of available memory (in mebibytes).
|
|
||||||
function _mem_free() {
|
|
||||||
free -m | sed -n -e '2p' | awk '{print $7}'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function-wrapper to iterate with specified function with provided files.
|
|
||||||
# By default Iterates on all non-hidden files and directories.
|
|
||||||
# List of variables available to FUNCTION: target - current file, count - current item index, total - sum of targets, failed - count of previously failed items, skipped - count of skipped files, status - status line (not recommended to use).
|
|
||||||
# Usage: _iterate_targets <FUNCTION> [FILES]
|
|
||||||
function _iterate_targets() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local foo="''${1}"
|
|
||||||
local targets=("''${@:2}")
|
|
||||||
local total=''${#targets[@]}
|
|
||||||
local count=0
|
|
||||||
local failed=0
|
|
||||||
local skipped=0
|
|
||||||
local code=0
|
|
||||||
|
|
||||||
# set dafult value to target all supported archives.
|
|
||||||
if [[ "''${targets}" = "" ]]; then
|
|
||||||
_error "No targets provided."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# iterate each target.
|
|
||||||
for target in "''${targets[@]}"; do
|
|
||||||
# increment counter.
|
|
||||||
((count++))
|
|
||||||
|
|
||||||
# status info.
|
|
||||||
local status="[''${count}/''${total}] ''${target}"
|
|
||||||
_info "''${status}"
|
|
||||||
|
|
||||||
# Call function.
|
|
||||||
''${foo} "''${target}"
|
|
||||||
|
|
||||||
# Show error.
|
|
||||||
if [[ ''${?} != 0 ]]; then
|
|
||||||
((failed++))
|
|
||||||
_error "''${status}: Failed."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Add newline if not the last one.
|
|
||||||
[[ "''${count}" = "''${total}" ]] || _info
|
|
||||||
done
|
|
||||||
|
|
||||||
# Show skipped.
|
|
||||||
if [[ ''${skipped} != 0 ]]; then
|
|
||||||
_warn
|
|
||||||
_warn "''${color_byellow}Skipped: ''${skipped}.''${color_default}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Show error.
|
|
||||||
if [[ ''${failed} != 0 ]]; then
|
|
||||||
[[ "''${skipped}" = 0 ]] && _error
|
|
||||||
_error "''${color_bred}Failed: ''${failed}.''${color_default}"
|
|
||||||
false
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Skip current iteration.
|
|
||||||
# Usage: _iterate_skip [MESSAGE]
|
|
||||||
function _iterate_skip() {
|
|
||||||
((skipped++))
|
|
||||||
|
|
||||||
[[ "''${*}" != "" ]] && _warn "''${color_byellow}''${*}''${color_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Report an error.
|
|
||||||
# Always returns code 1.
|
|
||||||
# Usage: _error <MESSAGE>
|
|
||||||
function _error() {
|
|
||||||
>&2 echo -e "''${color_bred}''${*}''${color_default}"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Report a warning.
|
|
||||||
# Usage: _warn <MESSAGE>
|
|
||||||
function _warn() {
|
|
||||||
>&2 echo -e "''${color_byellow}''${*}''${color_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Report a debug.
|
|
||||||
# Usage: _debug <MESSAGE>
|
|
||||||
function _debug() {
|
|
||||||
>&2 echo -e "''${color_bwhite}''${*}''${color_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Report an info.
|
|
||||||
# Usage: _info <MESSAGE>
|
|
||||||
function _info() {
|
|
||||||
>&2 echo -e "''${color_bwhite}''${*}''${color_default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if array contains an element (strict).
|
|
||||||
# Usage: _contains <ELEMENT> <ARRAY>
|
|
||||||
function _contains() {
|
|
||||||
local IFS=$'\n'
|
|
||||||
local target="''${1}"
|
|
||||||
local array="''${@:2}"
|
|
||||||
|
|
||||||
if [[ "''${target}" = "" ]] || [[ "''${array}" = "" ]]; then
|
|
||||||
help _contains
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
for item in ''${array[@]}; do
|
|
||||||
[[ "''${item}" = "''${target}" ]] && return 0
|
|
||||||
done
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find an index of an element in array.
|
|
||||||
# Usage: _index_of <ELEMENT> <ARRAY>
|
|
||||||
function _index_of() {
|
|
||||||
local element="''${1}"
|
|
||||||
local array="''${@:2}"
|
|
||||||
local index=0
|
|
||||||
|
|
||||||
for item in ''${array[@]}; do
|
|
||||||
[[ "''${item}" = "''${element}" ]] && break
|
|
||||||
((index++))
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "''${index}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if inside Tmux.
|
|
||||||
function _is_tmux() {
|
|
||||||
[[ "''${TERM_PROGRAM}" = "tmux" ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if root.
|
|
||||||
function _is_root() {
|
|
||||||
[[ "''${UID}" = 0 ]]
|
|
||||||
}
|
|
||||||
|
|
||||||
# Ring a bell.
|
|
||||||
function _bell() {
|
|
||||||
echo -e '\a'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get users.
|
|
||||||
function _get_users() {
|
|
||||||
local users=("voronind" "dasha")
|
|
||||||
echo ''${users[@]}
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
154
home/program/bash/module/Util.sh
Normal file
154
home/program/bash/module/Util.sh
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
# Get the number of avaialble cores (threads).
|
||||||
|
function _core_count() {
|
||||||
|
cat /proc/cpuinfo | grep ^processor | wc -l
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get the number of available memory (in mebibytes).
|
||||||
|
function _mem_free() {
|
||||||
|
free -m | sed -n -e '2p' | awk '{print $7}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function-wrapper to iterate with specified function with provided files.
|
||||||
|
# By default Iterates on all non-hidden files and directories.
|
||||||
|
# List of variables available to FUNCTION: target - current file, count - current item index, total - sum of targets, failed - count of previously failed items, skipped - count of skipped files, status - status line (not recommended to use).
|
||||||
|
# Usage: _iterate_targets <FUNCTION> [FILES]
|
||||||
|
function _iterate_targets() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local foo="${1}"
|
||||||
|
local targets=("${@:2}")
|
||||||
|
local total=${#targets[@]}
|
||||||
|
local count=0
|
||||||
|
local failed=0
|
||||||
|
local skipped=0
|
||||||
|
local code=0
|
||||||
|
|
||||||
|
# set dafult value to target all supported archives.
|
||||||
|
if [[ ${targets} == "" ]]; then
|
||||||
|
_error "No targets provided."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# iterate each target.
|
||||||
|
for target in "${targets[@]}"; do
|
||||||
|
# increment counter.
|
||||||
|
((count++))
|
||||||
|
|
||||||
|
# status info.
|
||||||
|
local status="[${count}/${total}] ${target}"
|
||||||
|
_info "${status}"
|
||||||
|
|
||||||
|
# Call function.
|
||||||
|
${foo} "${target}"
|
||||||
|
|
||||||
|
# Show error.
|
||||||
|
if [[ ${?} != 0 ]]; then
|
||||||
|
((failed++))
|
||||||
|
_error "${status}: Failed."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Add newline if not the last one.
|
||||||
|
[[ ${count} == "${total}" ]] || _info
|
||||||
|
done
|
||||||
|
|
||||||
|
# Show skipped.
|
||||||
|
if [[ ${skipped} != 0 ]]; then
|
||||||
|
_warn
|
||||||
|
_warn "${color_byellow}Skipped: ${skipped}.${color_default}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show error.
|
||||||
|
if [[ ${failed} != 0 ]]; then
|
||||||
|
[[ ${skipped} == 0 ]] && _error
|
||||||
|
_error "${color_bred}Failed: ${failed}.${color_default}"
|
||||||
|
false
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip current iteration.
|
||||||
|
# Usage: _iterate_skip [MESSAGE]
|
||||||
|
function _iterate_skip() {
|
||||||
|
((skipped++))
|
||||||
|
|
||||||
|
[[ ${*} != "" ]] && _warn "${color_byellow}${*}${color_default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report an error.
|
||||||
|
# Always returns code 1.
|
||||||
|
# Usage: _error <MESSAGE>
|
||||||
|
function _error() {
|
||||||
|
>&2 echo -e "${color_bred}${*}${color_default}"
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report a warning.
|
||||||
|
# Usage: _warn <MESSAGE>
|
||||||
|
function _warn() {
|
||||||
|
>&2 echo -e "${color_byellow}${*}${color_default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report a debug.
|
||||||
|
# Usage: _debug <MESSAGE>
|
||||||
|
function _debug() {
|
||||||
|
>&2 echo -e "${color_bwhite}${*}${color_default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Report an info.
|
||||||
|
# Usage: _info <MESSAGE>
|
||||||
|
function _info() {
|
||||||
|
>&2 echo -e "${color_bwhite}${*}${color_default}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if array contains an element (strict).
|
||||||
|
# Usage: _contains <ELEMENT> <ARRAY>
|
||||||
|
function _contains() {
|
||||||
|
local IFS=$'\n'
|
||||||
|
local target="${1}"
|
||||||
|
local array="${@:2}"
|
||||||
|
|
||||||
|
if [[ ${target} == "" ]] || [[ ${array} == "" ]]; then
|
||||||
|
help _contains
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
for item in ${array[@]}; do
|
||||||
|
[[ ${item} == "${target}" ]] && return 0
|
||||||
|
done
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find an index of an element in array.
|
||||||
|
# Usage: _index_of <ELEMENT> <ARRAY>
|
||||||
|
function _index_of() {
|
||||||
|
local element="${1}"
|
||||||
|
local array="${@:2}"
|
||||||
|
local index=0
|
||||||
|
|
||||||
|
for item in ${array[@]}; do
|
||||||
|
[[ ${item} == "${element}" ]] && break
|
||||||
|
((index++))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "${index}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if inside Tmux.
|
||||||
|
function _is_tmux() {
|
||||||
|
[[ ${TERM_PROGRAM} == "tmux" ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if root.
|
||||||
|
function _is_root() {
|
||||||
|
[[ ${UID} == 0 ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ring a bell.
|
||||||
|
function _bell() {
|
||||||
|
echo -e '\a'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Get users.
|
||||||
|
function _get_users() {
|
||||||
|
local users=("voronind" "dasha")
|
||||||
|
echo ${users[@]}
|
||||||
|
}
|
|
@ -1,44 +0,0 @@
|
||||||
{ ... }:
|
|
||||||
{
|
|
||||||
text = ''
|
|
||||||
# Download video from URL. When no `[LINK]` specified, it tries to update previously downloaded link.
|
|
||||||
# Usage: vdl [LINK]
|
|
||||||
function vdl() {
|
|
||||||
# Check that ffmpeg and ffprobe are available.
|
|
||||||
if [[ "$(ffmpeg -version)" = "" ]] || [[ "$(ffprobe -version)" = "" ]]; then
|
|
||||||
_error "ffmpeg and ffprobe are required."
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
local target="''${@}" # What to download/update.
|
|
||||||
|
|
||||||
# If no [LINK] provided, try to read from `Src.txt`.
|
|
||||||
[[ "''${target}" = "" ]] && target="$(cat Src.txt)"
|
|
||||||
|
|
||||||
# If could not get [LINK] eventually, show an error and exit.
|
|
||||||
if [[ "''${target}" = "" ]]; then
|
|
||||||
_error "Could not determine [LINK] to download."
|
|
||||||
help vdl
|
|
||||||
return 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Save [LINK] for later use.
|
|
||||||
[[ -f "Src.txt" ]] || echo "''${target}" > Src.txt
|
|
||||||
|
|
||||||
# Download [LINK] content.
|
|
||||||
yt-dlp -4 -S 'res:1080,codec:av1,codec:vp9,codec:h264' --download-archive Index.txt --embed-thumbnail --embed-subs --write-auto-subs --embed-metadata --merge-output-format mkv -cio '%(playlist_index)000006d_%(id)s.%(ext)s' ''${target} # || _vdl_retry
|
|
||||||
}
|
|
||||||
|
|
||||||
# Temporary fix for vk downloads.
|
|
||||||
# Usage: vdl_vk <LINK>
|
|
||||||
function vdl_vk() {
|
|
||||||
vdl --format mp4 "''${@}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Download all videos from file with links.
|
|
||||||
# Usage: vdl_file <FILE>
|
|
||||||
function vdl_file() {
|
|
||||||
vdl -a "''${@}"
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue