Last active
October 24, 2024 03:25
-
-
Save Masterxilo/29ac0df083827bbd45a7c8ddcf3936d7 to your computer and use it in GitHub Desktop.
permfunction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script adds a program/script/command called 'permfunction' to you PATH | |
# permfunction allows you to write system-wide, on-PATH instantly available, persisted scripts, i.e. improved shell functions/aliases/abbreviations/short programs. | |
# | |
# TODO also persist these functions as gists for the user | |
# inspired by | |
# https://askubuntu.com/questions/1414/how-to-create-a-permanent-alias | |
# https://askubuntu.com/a/80290/521770 | |
# | |
# installation/update to latest version for current user (this takes precedence over global version, if your PATH is set up as usually): | |
# | |
# curl -s https://gist.githubusercontent.com/Masterxilo/29ac0df083827bbd45a7c8ddcf3936d7/raw/permfunction | bash - ; hash -d permfunction &> /dev/null || true | |
# | |
# installation/update of global version for all users (depending on your PATH only this might work out of the box): | |
# | |
# curl -s https://gist.githubusercontent.com/Masterxilo/29ac0df083827bbd45a7c8ddcf3936d7/raw/permfunction | sudo -E bash - ; hash -d permfunction &> /dev/null || true | |
# | |
# This last way of installing is required if you want to use sudo permfunction. | |
# | |
# uninstall: | |
# rm ~/bin/permfunction | |
# sudo rm /usr/bin/permfunction | |
# Note: Installation of the very latest version should be done with a hardlink to the current version /raw/.../functionname instead, because http caching | |
# in the gist server makes the /raw/functionname route not always reflect the latest update | |
set -e | |
# note that -e only exits immediately if top level error occus - except pipelines (see below) and sequences (unconditional continuation), expressions are evaluated to completion | |
set -o pipefail | |
installdir="/usr/bin" | |
! [ -w "$installdir" ] && { installdir="$HOME/bin" ; } | |
mkdir "$installdir" &> /dev/null || true | |
file="$installdir/permfunction" | |
[ -f "$file" ] && { echo >&2 "warning: $file exists, overwriting" ; } | |
echo "installing permfunction at $file..." ; | |
which permfunction &> /dev/null && ! [ "`which permfunction`" == "$file" ] && { echo >&2 "error: permfunction is already installed elsewhere at `which permfunction`. Prefer to have one up-to-date installation to avoid version confusion." ; exit 1 ; } | |
# -------- permfunction source code ----------- | |
cat > "$file" <<'EOF' | |
#!/bin/bash | |
set -e | |
set -o pipefail | |
[ "$1" == "--redefine" ] && { shift ; redefine=true ; } | |
[ "$1" == "--file" ] && { shift ; file=true ; } | |
name="$1" | |
if [ -z "$redefine" ] ; then | |
which "$name" &>/dev/null && { echo "error: command with name $name exists at `which "$name"`. use --redefine to overwrite" ; exit 1 ; } || true # refuse to overwrite/take precedence over existing commands to avoid confusion! | |
fi | |
shift || true # shift fails if there are no variables! | |
code=$(echo "$@") # code is not just $2, but all remaining args, space separated | |
[ ! -z "$file" ] && { code=$(cat "$code") ; } | |
FD_NUMBER_STDIN=0 # this is a system constant in linux | |
if [ -z "$code" ] && [[ -t $FD_NUMBER_STDIN ]] ; then | |
echo >&2 "code is not defined and STDIN is a tty which is not allowed. use 'cat - | permfunction $name' if you want a simple editor. or use 'echo code | permfunction $name'"; | |
echo "" | |
# will display usage below: | |
else | |
[ -z "$code" ] && { | |
code="$(cat /dev/stdin)"; | |
} | |
fi | |
( [ "$name" == "-help" ] || [ "$name" == "-?" ] || [ "$name" == "--?" ] || [ "$name" == "--help" ] || [ -z "$name" ] || [ -z "$code" ] ) && { cat >&2 <<'USAGEEOF' | |
permfunction allows you to write system-wide, on-PATH instantly available, persisted scripts, i.e. improved shell functions/aliases/abbreviations/short programs. | |
usage: [sudo] permfunction [--redefine] name code | |
[sudo] permfunction [--redefine] name code more-code even-more-code | |
[sudo] permfunction [--redefine] name <<'EOF' | |
code | |
EOF | |
[sudo] permfunction [--redefine] name < file_containing_code | |
-command generating code on stdout- | [sudo] permfunction [--redefine] name | |
[sudo] permfunction [--redefine] --file name file_containing_code | |
where stdin cannot be a tty (we don't want to implement any line/terminal editing in this tool). | |
usage examples: | |
permfunction cls "clear" | |
after this, cls does the same as clear or ctrl+l in any open terminal (with the same PATH) | |
sudo permfunction cls "clear" | |
same, but install for all users | |
permfunction sayhi 'echo Hello $1' | |
after this, "sayhi World" prints "Hello World". Note that we cannot let the shell expand $1!!! | |
permfunction dosomething ' | |
echo "this script does" | |
echo "something with $1" | |
echo "which is so complex that it needs this many lines!!!" | |
' | |
after this, try 'dosomething "your shell"', and check out 'cat `which dosomething`' | |
USAGEEOF | |
exit 1 ; } | |
re="[[:space:]]+" | |
if [[ "$name" =~ $re ]]; then | |
echo >&2 "usage: permfunction [--redefine] name code" ; | |
echo >&2 "error: name may not contain spaces, was '$name'" ; | |
exit 1 ; | |
fi | |
installdir="/usr/bin" # system install. requires sudo to write | |
! [ -w "$installdir" ] && { installdir="$HOME/bin" ; } | |
mkdir "$installdir" &> /dev/null || true | |
file="$installdir/$name" | |
[ -f "$file" ] && [ -z $redefine ] && { | |
echo >&2 "error: $file exists. Use --redefine to force overwriting" ; | |
[ -w ] && echo >&2 "or use rm $file to delete the existing command manually first"; | |
! [ -w ] && echo >&2 "or use sudo rm $file to delete the existing command manually first"; | |
exit 1 ; | |
} | |
[ -f "$file" ] && ! [ -z $redefine ] && { echo >&2 "warning: $file exists. Redefining." ; } | |
echo "$code" > "$file" | |
chmod +x "$file" | |
echo "installed $name to $file" | |
echo "-------------- code listing 'cat $file' ---------------" | |
cat "$file" | |
echo "-------------- code listing end ---------------" | |
! [ "`which $name`" == "$file" ] && { echo >&2 """ | |
error: Installation in PATH failed | |
which $name | |
returns | |
`which $name` | |
instead of expected | |
$file | |
Probably '$installdir' is not in your PATH or another program of the same name is taking precedence. If you used [sudo] permfunction, try to use with/without sudo instead. | |
""" ; exit 1 ; } | |
[ "`which $name`" == "$file" ] && { echo "successfully installed $name in PATH, you can now use it" ; } | |
hash -d $name &> /dev/null || true # no idea if this helps something/escapes the scope of this script | |
EOF | |
chmod +x $file | |
name="permfunction" | |
echo "installed $name to $file" | |
! [ "`which $name`" == "$file" ] && { echo >&2 """ | |
error: Installation in PATH failed | |
which $name | |
returns | |
`which $name` | |
instead of expected | |
$file | |
Probably '$installdir' is not in your PATH or another program of the same name is taking precedence. If you used [sudo] permfunction, try to use with/without sudo instead. | |
"""; exit 1 ; } | |
[ "`which $name`" == "$file" ] && { echo "successfully installed $name in PATH, you can now use it" ; } | |
hash -d permfunction &> /dev/null || true # no idea if this helps something/escapes the scope of this script | |
Recommended aliases:
- define
- pfunction
- persistent_function
- persist
definition using:
permfunction --redefine palias $'name=$1; shift; permfunction $name "$@"\' "$@"\''
# then
palias define permfunction
palias pfunction permfunction
palias persistent_function permfunction
palias persist permfunction
palias persistent_alias palias
nice command: recursive touch/mkdir -p
palias mkdirp 'mkdir -p'
permfunction touchp 'mkdir -p "$(dirname "$1")" && touch "$1" ;'
palias touch2 touchp
https://askubuntu.com/questions/800845/create-file-and-its-parent-directory
touchp test/about/me
find test
tree test
touchp src/main/java/hello/Application.java
for
https://spring.io/guides/gs/testing-web/
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://unix.stackexchange.com/a/276558/266802