Skip to content

Instantly share code, notes, and snippets.

@s1037989
Last active July 6, 2023 00:47
Show Gist options
  • Save s1037989/1133fa25bf751238126e3b65745781d4 to your computer and use it in GitHub Desktop.
Save s1037989/1133fa25bf751238126e3b65745781d4 to your computer and use it in GitHub Desktop.
exec 73>&- 74<&- 74> >(perl -nE 'say "...$_..."') 73> >(LANG=C exec stdbuf -o0 perl -nE 'say ,,,$_,,,' >&74 2>&1)
function perl::start {
read TMPDIR < <(/usr/bin/mktemp -d /dev/shm/conn_shell_XXXXXXX)
mkfifo $TMPDIR/perl
nextFd PERLIN
echo $PERLIN
eval "exec $PERLIN> >(LANG=C exec stdbuf -o0 -i0 perl -pE '\$_="1\n\r"' >$TMPDIR/perl 2>&1)"
nextFd PERLOUT
echo $PERLOUT
eval "exec $PERLOUT<$TMPDIR/perl"
rm -v $TMPDIR/perl
rmdir -v $TMPDIR
}
function perl::perl { [ -z "$PERLIN" -o -z "$PERLOUT" ] && return; local VAR=$1; shift; echo -e "$*" 1>&$PERLIN && IFS= read -r -d $'\r' -u $PERLOUT $VAR; }
function perl::stop { [ -n "$PERLIN" -a -n "$PERLOUT" ] && eval "exec $PERLIN>&- $PERLOUT<&-"; true; }
perl::tput() { echo -e "$1\ncr" 1>&$PERLIN && IFS= read -r -d $'\r' -u $PERLOUT $2; }
function ln::start {
local fd=3;
while [ -e /dev/fd/$fd ]; do ((fd++)); done
eval "exec $fd<> >(LANG=C exec stdbuf -o0 perl -n -E 'chomp;@_=split/\\t/;say link \$_[0], \$_[1]' &>/dev/null)";
echo $fd
}
function ln::ln { eval 'echo -e "$2\t$3" 1>&'$1; }
function ln::stop { eval "exec $1>&-"; }
function varcmd::one {
[ -z "$2" ] && { echo "usage: $FUNCNAME var command ..."; return 1; }
local fd=3 VAR=$1; shift
while [ -e /dev/fd/$fd ]; do ((fd++)); done
local shm=/dev/shm/conn_shell_$$_${fd}
mkfifo $shm
eval "exec $fd<> $shm"
unlink $shm
eval '"$@" 1>&'$fd
mapfile -u$fd -n1 -t $VAR
eval "exec $fd>&-"
}
function varcmd::start {
local __varcmd_fd=3; while [ -e /dev/fd/$__varcmd_fd ]; do ((__varcmd_fd++)); done
# ALT: find -L /dev/fd/ -mindepth 1 -maxdepth 1 -type d 2>/dev/null
local shm=/dev/shm/conn_shell_$$_${__varcmd_fd}
mkfifo $shm
eval "exec $__varcmd_fd<> $shm"
unlink $shm
echo "FD: $__varcmd_fd"
}
function varcmd {
[ -z "$3" ] && { echo "usage: $FUNCNAME fd var command ..."; return 1; }
local FD=$1 VAR=$2; shift; shift
test -e /dev/fd/$FD || return 255
eval '"$@" 1>&'$FD
mapfile -u$FD -n1 -t $VAR
}
function varcmd::end {
[ -z "$1" ] && { echo "usage: $FUNCNAME fd"; return 1; }
eval "exec $1>&-"
}
tputConnector() {
read TMPDIR < <(/usr/bin/mktemp -d /dev/shm/conn_shell_XXXXXXX)
mkfifo $TMPDIR/tput
nextFd TPUTIN
eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)"
nextFd TPUTOUT
eval "exec $TPUTOUT<$TMPDIR/tput"
rm $TMPDIR/tput
rmdir $TMPDIR
}
myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2; }
#!/bin/bash
# $ $0 forks
# $ $0 1fork
# https://unix.stackexchange.com/a/521120
function forks {
for ((i=0; i<256; i++)); do
echo -n ' '
tput setab $i
tput setaf $(( ( (i>231&&i<244 ) || ( (i<17)&& (i%8<2)) ||
(i>16&&i<232)&& ((i-16)%6 <(i<100?3:2) ) && ((i-16)%36<15) )?7:16))
printf " C %03d " $i
tput op
(( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
printf "\n" ''
done
}
# ... Then, because I hate runnig more than 200 forks in a little script, I wrote this:
function one_fork {
# Connector fifos directory
fd=3
# find next free fd
nextFd() { while [ -e /dev/fd/$fd ];do ((fd++)) ;done;printf -v $1 %d $fd;}
tputConnector() {
read TMPDIR < <(/usr/bin/mktemp -d /dev/shm/conn_shell_XXXXXXX)
mkfifo $TMPDIR/tput
nextFd TPUTIN
eval "exec $TPUTIN> >(LANG=C exec stdbuf -o0 tput -S - >$TMPDIR/tput 2>&1)"
nextFd TPUTOUT
eval "exec $TPUTOUT<$TMPDIR/tput"
rm $TMPDIR/tput
rmdir $TMPDIR
}
myTput() { echo -e "$1\ncr" 1>&$TPUTIN && IFS= read -r -d $'\r' -u $TPUTOUT $2; }
tputConnector
myTput op op
myTput "setaf 7" grey
myTput "setaf 16" black
fore=("$black" "$grey")
for ((i=0; i<256; i++)) ;do
myTput "setab $i" bgr
printf " %s%s %3d %s" "$bgr" "${fore[ i>231 && i<244||(i<17)&& (i%8<2)||
(i>16&&i<232)&&((i-16)%6*11+(i-16)/6%6*14+(i-16)/36*10)<58
? 1 : 0 ]}" $i "$op"
(( ((i<16||i>231) && ((i+1)%8==0)) || ((i>16&&i<232)&& ((i-15)%6==0)) )) &&
printf "\n" ''
done
}
# With only 1 fork! Same result, but approx 10x faster!
# If first script run in ~1.12 second on my desk, they take upto ~47.4 seconds on my raspberry-pi!!
# While second script run in ~0.11 second on my desk and ~4.97 seconds on my raspberry.
case $1 in
forks) forks;;
1fork) one_fork;;
esac
function backup-mpfs {
[ -n "$1" ] || backup::✗ "usage: $FUNCNAME mount-point" || return
local mp="$1"; shift
#[[ $mp =~ ^/dev/ ]] && mp=$(grep ^$mp /proc/mounts | cut -f2 -d' ')
#mp=$(stat -c%m $mp)
local DATE=$(date +"%Y%m%dT%H%M%S")
local SNAPSHOTS=$mp/.snapshots; mkdir -pv $SNAPSHOTS
local FILESTORE=$mp/.filestore; mkdir -pv $FILESTORE
rsync -vaziHl --link-dest "$mp" --exclude ".snapshots" --exclude ".filestore" "$mp" "$SNAPSHOTS/$DATE"
local sha staging file dirname i
backup::varcmd::start; local fd=$__backup_fd
trap "backup::varcmd::end $fd" RETURN
while read i; do
test ! -e "$i" -o -L "$i" -o -d "$i" && continue
backup::varcmd $fd sha sha256sum "$i"
sha=${sha:0:64}
filestore=$FILESTORE/${sha:0:1}/${sha:0:2}/${sha:0:3}
{
test -d "$filestore" || mkdir -pv "$filestore"
} && {
test -e "$filestore/$sha" || ln -v "$i" "$filestore/$sha"
} && {
! backup::samefile "$i" "$filestore/$sha"
} && {
backup::samecontents "$i" "$filestore/$sha"
} && {
ln -fv "$filestore/$sha" "$i"
};
echo;
done < <(find $SNAPSHOTS/$DATE -type f)
}
function backup::samefile {
[ -e "$1" -a -e "$2" ] && [ $(stat -c%i "$1") == $(stat -c%i "$2") ] && echo "samefile $1 => $2" && return 0
return 1
}
function backup::samecontents {
[ -e "$1" -a -e "$2" ] && [ $(stat -c%s "$1") == $(stat -c%s "$2") -a "$(head -c100 "$1")" == "$(head -c100 "$2")" -a "$(tail -c100 "$1")" == "$(tail -c100 "$2")" ] && echo "samecontents $1 ~~ $2" && return 0
return 1
}
GREEN="$(tput setaf 2)"
RED="$(tput setaf 1)"
RESET="$(tput setaf 0)"
err_color=("${GREEN}" "${RED}")
err_prompt=("✓" "✗")
PS1='\[${err_color[(($??1:0))]}\]${err_prompt[(($??1:0))]}\[${RESET}\] \[\033[01;33m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
function cd { if [ "$1" == -q ]; then shift; test -d "$1" || return; fi; builtin cd "$@"; echo $(pwd) > ${HISTFILE/bash_histories/pwd}; }
function history-file { echo $HISTFILE; }
function history-reconfig { history-config ; history-file ;}
function history-config {
test -d ~/.bash_histories || mkdir ~/.bash_histories
test -d ~/.pwd || mkdir ~/.pwd
HISTCONTROL=ignoreboth
HISTIGNORE="history:ls:pwd"
HISTSIZE=10000
HISTFILESIZE=
HISTTIMEFORMAT="%F %T "
LC_HISTFILE=${LC_HISTFILE/~}
LC_HISTFILE=${LC_HISTFILE:1}
HISTFILE=~/$(test -n "$TMUX" && tmux display -p ".bash_histories/#{host}-#{session_name}-#{window_index}-#{pane_index}" 2>/dev/null || echo ${LC_HISTFILE:-.bash_histories/$HOSTNAME})
export LC_HISTFILE=$HISTFILE
shopt -s histappend
test -f ${HISTFILE/bash_histories/pwd} && cd -q "$(< ${HISTFILE/bash_histories/pwd})"
}
history-config
set -g mouse on
bind -n WheelUpPane if-shell -F -t = "#{mouse_any_flag}" "send-keys -M" "if -Ft= '#{pane_in_mode}' 'send-keys -M' 'select-pane -t=; copy-mode -e; send-keys -M'"
bind -n WheelDownPane select-pane -t= \; send-keys -M
bind -n C-WheelUpPane select-pane -t= \; copy-mode -e \; send-keys -M
bind -T copy-mode-vi C-WheelUpPane send-keys -X halfpage-up
bind -T copy-mode-vi C-WheelDownPane send-keys -X halfpage-down
bind -T copy-mode-emacs C-WheelUpPane send-keys -X halfpage-up
bind -T copy-mode-emacs C-WheelDownPane send-keys -X halfpage-down
# To copy, left click and drag to highlight text in yellow,
# once you release left click yellow text will disappear and will automatically be available in clibboard
# # Use vim keybindings in copy mode
setw -g mode-keys vi
# Update default binding of `Enter` to also use copy-pipe
unbind -T copy-mode-vi Enter
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "xclip -selection c"
bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X copy-pipe-and-cancel "xclip -in -selection clipboard"
$ cd $(mktemp -d /dev/shm/qaz.XXXXX) \
exec $out>&- $in<&- ; \
tmp=$(mktemp -u /dev/shm/abc.XXX); \
mkfifo $tmp; \
exec $out> >(LANG=C exec stdbuf -o0 -i0 perl -nE 'BEGIN{$|=1}eval $_' >$tmp); \
exec $in<$tmp; \
rm $tmp ; \
TIMEFORMAT=%3R
$ date > date ; rm -f ? ?? ??? ; \
time for i in {1..10000}; do \
ln -v date $i; rm -v $i; \
done | wc -l ; \
time for i in {10001..20000}; do \
echo "say link 'date', '$i'; say unlink '$i'" >&$out \
&& read -t 0.1 -r -u $in \
&& echo $REPLY \
&& read -t 0.1 -r -u $in \
&& echo $REPLY; \
done | wc -l
20000
29.618
20000
0.461
$ date > date ; rm -f ? ?? ??? ; \
time for i in {1..10}; do \
ln -v date $i; rm -v $i; \
done | wc -l ; \
time for i in {11..20}; do \
echo "say link 'date', '$i'; say unlink '$i'" >&$out \
&& read -t 0.1 -r -u $in \
&& echo $REPLY \
&& read -t 0.1 -r -u $in \
&& echo $REPLY; \
done | wc -l
20
0.030
20
0.002
# $ pack 'H*' 6162
# ab
function pack { perl -E '$/=undef; say join " ", pack($ARGV[0], $ARGV[1]||<STDIN>)' "$@"; }
# $ unpack 'H*' ab
# 6162
function unpack { perl -E '$/=undef; say join " ", unpack($ARGV[0], $ARGV[1]||<STDIN>)' "$@"; }
# $ unpack 'H*' abcdefghijklmnopqrstuvwxyz | pfold -b=2 -w=4 -l=8
# 61 62 63 64 65 66 67 68
# 69 6a 6b 6c 6d 6e 6f 70
# 71 72 73 74 75 76 77 78
# 79 7a
function pfold { perl -spE 'BEGIN{$bd//=" ";$b//=2;$wd//=" ";$w//=4;$l//=16}s/(.{$b})/$1.(!$w||++$c%($w)?$bd:$wd).(!$l||$c%$l?"":$\/)/ge' -- "$@"; }
# $ unpack 'H*' abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz | grephex 48 6a6b
# 616263646566676869 6a6b 6c6d6e6f707172737475767778797a616263646566676869 6a6b 6c6d6e6f707172737475767778797a
function grephex { perl -pE "\$l=$1;\$l=length(\$_)-length(q($2)) if $1>length(\$_)-length(q($2));s/(.*?)(.{0,$1})?($2)(.{0,$1})?(.*?)/(\$1?'...':'').\$2.qq( \\e[31m\$3\\e[0m \$4).(\$5?'...':'')/eg"; }
# $ seq 1 10 | pivot 5 :
# 1:2:3:4:5
# 6:7:8:9:10
function pivot { printf -v dashes -- '- %.0s' $(eval echo {1..$1}); paste -d"${2:- }" $dashes; }
# $ echo 123 | printfp "%05d\n"
# 00123
function printfp { exec {fd}<&0; readarray -t -u $fd var; printf ${1:-%s\n} "${var[@]}"; }
function random_chunks { A=$1 P=$2 S=$3 C=$4 perl -nE 'BEGIN{$|=1;srand;our $q=0;$SIG{ALRM}=sub{$q=$ENV{C}+1 and say " ::" and alarm($ENV{A})};alarm($ENV{A})}alarm($ENV{A}) if $.<$ENV{S}+1||$q==1;$q-- if $q>0;do{alarm(0);print} if($.<$ENV{S}||$q||($ENV{P} and !(int(rand(100/$ENV{P}))) and $q=$ENV{C} and say " :"))'; }
[ $# -eq 4 ] && random_chunks "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment