|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
#######
#
# E-scripts on Bash.
#
# Note 1: use the eev command (defined in eev.el) and the
# ee alias (in my .zshrc) to execute parts of this file.
# Executing this file as a whole makes no sense.
# An introduction to eev can be found here:
#
# (find-eev-quick-intro)
# http://angg.twu.net/eev-intros/find-eev-quick-intro.html
#
# Note 2: be VERY careful and make sure you understand what
# you're doing.
#
# Note 3: If you use a shell other than zsh things like |&
# and the for loops may not work.
#
# Note 4: I always run as root.
#
# Note 5: some parts are too old and don't work anymore. Some
# never worked.
#
# Note 6: the definitions for the find-xxxfile commands are on my
# .emacs.
#
# Note 7: if you see a strange command check my .zshrc -- it may
# be defined there as a function or an alias.
#
# Note 8: the sections without dates are always older than the
# sections with dates.
#
# This file is at <http://angg.twu.net/e/bash.e>
# or at <http://angg.twu.net/e/bash.e.html>.
# See also <http://angg.twu.net/emacs.html>,
# <http://angg.twu.net/.emacs[.html]>,
# <http://angg.twu.net/.zshrc[.html]>,
# <http://angg.twu.net/escripts.html>,
# and <http://angg.twu.net/>.
#
#######
# «.use-bash» (to "use-bash")
# «.bash-debian» (to "bash-debian")
# «.dash» (to "dash")
# «.bash_source_old» (to "bash_source_old")
# «.bashfaq» (to "bashfaq")
#
# «.arrays» (to "arrays")
# «.case» (to "case")
# «.colon» (to "colon")
# «.command-subst» (to "command-subst")
# «.eval» (to "eval")
# «.function» (to "function")
# «.here-documents» (to "here-documents")
# «.multiline-comments» (to "multiline-comments")
# «.parameter-exp» (to "parameter-exp")
# «.parameter-exp-bang» (to "parameter-exp-bang")
# «.pipe_stdout_stderr» (to "pipe_stdout_stderr")
# «.source» (to "source")
# «.BASH_SOURCE» (to "BASH_SOURCE")
# «.redirection» (to "redirection")
# «.special-params» (to "special-params")
# «.test» (to "test")
# «.which» (to "which")
#
# «.args_with_spaces» (to "args_with_spaces")
# «.pdsc» (to "pdsc")
# «.exit-code-and-if» (to "exit-code-and-if")
# «.here-docs-verbose-mode» (to "here-docs-verbose-mode")
# «.mailing-list» (to "mailing-list")
# «.bash-3.1-info» (to "bash-3.1-info")
# «.bash-3.2-info» (to "bash-3.2-info")
# «.bash-4.1-info» (to "bash-4.1-info")
# «.bash-doc» (to "bash-doc")
# «.prompt» (to "prompt")
# «.tty-var» (to "tty-var")
# «.login-shell» (to "login-shell")
# «.process-substitution» (to "process-substitution")
# «.shellshock» (to "shellshock")
# «.julio-neves» (to "julio-neves")
# «.set» (to "set")
# «.unset-f» (to "unset-f")
# «.letter-combos-for-6397» (to "letter-combos-for-6397")
# «.blau-2021-05» (to "blau-2021-05")
# «.vagner-2022-04» (to "vagner-2022-04")
# «.emacs-as-a-bash-ide» (to "emacs-as-a-bash-ide")
# «.ping-and-date» (to "ping-and-date")
# «.sh-mode» (to "sh-mode")
# «.shellcheck» (to "shellcheck")
# «.crdt-12» (to "crdt-12")
# https://www.quora.com/What-are-some-good-books-for-learning-Linux-bash-or-shell-scripting
# (Very old) note: I'm just learning bash now (sep/2000), and mainly
# to port my zsh scripts to it, as zsh doesn't run on the Hurd
# (yet)...
#####
#
# use-bash
# 2022dec08
#
#####
# «use-bash» (to ".use-bash")
# (find-angg ".emacs" "eepitch-shell")
#####
#
# Bash on Debian
# 2011nov19
#
#####
# «bash-debian» (to ".bash-debian")
# (find-angg ".emacs" "bash")
# (find-zsh "availabledebs | sort | grep bash")
# The Bash Manual is considered to be non-dfsg...
# I need to clean up my scripts that download and install it.
# (find-es "bash" "bash-3.1-info")
# (find-es "bash" "bashfaq")
# (code-c-d "bashfaq" "$S/ftp/ftp.cwru.edu/pub/bash/")
# (code-c-d "bashsrc" "~/usrc/bash-3.1/")
# (find-fline "~/info/" "bashref")
# (find-status "bash")
# (find-vldifile "bash.list")
# (find-udfile "bash/")
# (find-status "bash-doc")
# (find-vldifile "bash-doc.list")
# (find-udfile "bash-doc/")
# (find-bashnode "Top")
# (find-bashnode "Builtin Index")
# (find-bashnode "Reserved Word Index")
# (find-bashnode "Variable Index")
# (find-bashnode "Function Index")
# (find-bashnode "Concept Index")
# (find-udfile "bash/examples/")
# (find-udfile "bash/examples/")
# (find-udfile "bash/examples/bashdb/")
# (find-udfile "bash/examples/functions/")
# (find-udfile "bash/examples/misc/")
# (find-udfile "bash/examples/scripts/")
# (find-udfile "bash/examples/scripts.noah/")
# (find-udfile "bash/examples/scripts.v2/")
# (find-udfile "bash/examples/startup-files/")
#*
zcatinfo /usr/share/info/bash > /tmp/bash.info
#*
# (find-fline "/tmp/bash.info")
#####
#
# dash
# 2011nov19
#
#####
# «dash» (to ".dash")
# (find-angg ".emacs" "dash")
# (find-status "dash")
# (find-vldifile "dash.list")
# (find-udfile "dash/")
# (find-udfile "dash/NEWS.Debian.gz")
# (find-udfile "dash/README.source")
# (find-man "1 dash")
# (find-man "1 sh")
#####
#
# bash source (woody)
# 2000sep10
#
#####
# «bash_source_old» (to ".bash_source_old")
#*
rm -Rv /usr/src/bash-2.04/
pdsc $SDEBIAN/dists/woody/main/source/base/bash_2.04-6.dsc
cd /usr/src/bash-2.04/
#*
# (code-c-d "bash" "/usr/src/bash-2.04/" "bash")
# (find-bashfile "")
# (find-bashfile "builtins/")
# (find-bashfile "builtins/set.def" "o_options[] =" "verbose")
# (find-bashnode "")
#####
#
# the bash FAQ
# 2006aug03
#
#####
# «bashfaq» (to ".bashfaq")
# The license of the FAQ is not DFSG-free:
# (find-udfile "bash/FAQ")
# Use the version from the web:
# ftp://ftp.cwru.edu/pub/bash/FAQ
# (code-c-d "bashfaq" "$S/ftp/ftp.cwru.edu/pub/bash/")
# (find-bashfaqfile "FAQ")
#####
#
# more on redirections
# 2006aug03 / 2025mar21
#
#####
# «redirection» (to ".redirection")
# (find-es "busybox" "ash-redirection")
# Note: I still don't understand "1>&2 > output".
# (find-bashnode "Redirections" "[N]>>WORD")
# (find-bashnode "Redirections" "[N]>[|]WORD")
# (find-bashnode "Redirections" ">&WORD")
# (find-bashnode "Redirections" "[N]>&WORD")
# (find-bashnode "Redirections" "[N]>&DIGIT-")
# https://en.wikipedia.org/wiki/Standard_streams
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
rm -R /tmp/red/
mkdir /tmp/red/
cd /tmp/red/
echo12 () { echo one; echo two 1>&2; }
echo12
echo12 1> /dev/null
echo12 2> /dev/null
echo12 1> /dev/null 2> /dev/null
echo12 1>&2
echo12 1>&2 1> /dev/null
{ echo one; echo two 1>&2 } 1> one 2> two
for i in *; do echo "$i: $(cat $i)"; done
{ echo one; echo two 1>&2 } 1>&2 1> one 2> two
for i in *; do echo "$i: $(cat $i)"; done
# (find-node "(libc)Creating a Pipe")
#####
#
# arrays
# 2024oct15
#
#####
# «arrays» (to ".arrays")
# (find-bashnode "Arrays")
# (find-bashnode "Arrays" "without a subscript")
# (find-bashnode "Bash Builtins" "declare [-aAfFgiIlnrtux] [-p]")
# https://unix.stackexchange.com/questions/246026/check-variable-is-an-array-in-bourne-like-shell
# (find-fline "~/LOGS/2024dec12.bash" "BashSheet#Arrays")
# http://mywiki.wooledge.org/BashSheet#Arrays
# http://mywiki.wooledge.org/BashFAQ/005
# https://web.archive.org/web/20230403055152/https://wiki.bash-hackers.org/syntax/arrays
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
unset myarray
typeset -p myarray
declare -a myarray
typeset -p myarray
myarray[0]=zero
myarray[1]=one
myarray[2]=two
echo $myarray
echo ${myarray[2]}
echo ${myarray[@]}
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
FRAMES=(/tmp/frame_*.pdf)
echo ${FRAMES[1]}
for i in a "${FRAMES[@]}" b; do echo $i; done
#####
#
# case
# 2000nov15
#
#####
# «case» (to ".case")
# (find-bashnode "Conditional Constructs" "case")
# (find-bashnode "Conditional Constructs" "dog | cat")
# (find-fline "~/bin/eev-wconfig" "case \"_$1_\" in")
# (ee-find-grep "/etc/init.d/" "grep --color=auto -nH --null -e case *")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
f () {
case "_$1_" in
_o_) echo one;;
_t_) echo two;;
__) echo empty;;
*) echo other;;
esac
}
f o; f t; f; f bla
#####
#
# colon
# 2024nov08
#
#####
# «colon» (to ".colon")
# (find-bashnode "Bourne Shell Builtins" ": (a colon)")
# (find-bashnode "Bourne Shell Builtins" ": [ARGUMENTS]")
# (find-eev2021hsubs "03:39" "In some cases I had to improvise a bit")
# (find-eev2021hsubs "03:48" "this weird syntax using a here-document")
# (find-eev "eev-testblocks.el" "examples")
# (find-eev "eev-testblocks.el" "examples" "ee-insert-test-sh-mode")
# (to "multiline-comments")
# (to "here-documents")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
: <<'%%%'
This
is
ignored
%%%
#####
#
# command-subst
# 2024oct15
#
#####
# «command-subst» (to ".command-subst")
# (find-bashnode "Command Substitution")
# (find-bashnode "Command Substitution" "$(COMMAND)")
# (find-bashnode "Command Substitution" "`COMMAND`")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
f () { echo _ $* _; }
echo a $(f b c d)
#####
#
# eval
# 2024nov07
#
#####
# «eval» (to ".eval")
# (find-bashnode "Bourne Shell Builtins" "eval [ARGUMENTS]")
#####
#
# function
# 2024oct15
#
#####
# «function» (to ".function")
# (to "parameter-exp")
# (find-bashnode "Shell Functions")
# (find-bashnode "Positional Parameters")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
f () { echo $*; }
g () { echo $@; }
h () { echo ${@:2}; }
f a b c d e
g a b c d e
h a b c d e
#####
#
# here-documents
# 2024nov08
#
#####
# «here-documents» (to ".here-documents")
# (find-bashnode "Redirections" "Here Documents")
# (to "multiline-comments")
# (to "colon")
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
tac <<'%%%'
a
b
c
%%%
#####
#
# multiline-comments
# 2024nov08
#
#####
# «multiline-comments» (to ".multiline-comments")
# https://stackoverflow.com/questions/43158140/way-to-create-multiline-comments-in-bash
# https://stackoverflow.com/questions/43158140/way-to-create-multiline-comments-in-bash/#46049228
# (to "here-documents")
# (to "colon")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
: <<'END_COMMENT'
This is a heredoc (<<) redirected to a NOP command (:).
The single quotes around END_COMMENT are important,
because it disables variable resolving and command resolving
within these lines. Without the single-quotes around END_COMMENT,
the following two $() `` commands would get executed:
$(gibberish command)
`rm -fr mydir`
comment1
comment2
comment3
END_COMMENT
#####
#
# Parameter expansion: the cases ${...:...}
# 2024oct12
#
#####
# «parameter-exp» (to ".parameter-exp")
# (find-bashnode "Shell Parameter Expansion")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:-WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:=WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:?WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:+WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:OFFSET}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER:OFFSET:LENGTH}")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
string=01234567890abcdefgh
echo ${string:7} ;# 7890abcdefgh
echo ${string:7:0} ;#
echo ${string:7:2} ;# 78
echo ${string:7:-2} ;# 7890abcdef
echo ${string: -7} ;# bcdefgh
echo ${string: -7:0} ;#
echo ${string: -7:2} ;# bc
echo ${string: -7:-2} ;# bcdef
set -- 01234567890abcdefgh
echo ${1:7} ;# 7890abcdefgh
echo ${1:7:0} ;#
echo ${1:7:2} ;# 78
echo ${1:7:-2} ;# 7890abcdef
echo ${1: -7} ;# bcdefgh
echo ${1: -7:0} ;#
echo ${1: -7:2} ;# bc
echo ${1: -7:-2} ;# bcdef
array[0]=01234567890abcdefgh
echo ${array[0]:7} ;# 7890abcdefgh
echo ${array[0]:7:0} ;#
echo ${array[0]:7:2} ;# 78
echo ${array[0]:7:-2} ;# 7890abcdef
echo ${array[0]: -7} ;# bcdefgh
echo ${array[0]: -7:0} ;#
echo ${array[0]: -7:2} ;# bc
echo ${array[0]: -7:-2} ;# bcdef
set -- 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
echo ${@:7} ;# 7 8 9 0 a b c d e f g h
echo ${@:7:0} ;#
echo ${@:7:2} ;# 7 8
echo ${@:7:-2} ;# bash: -2: substring expression < 0
echo ${@: -7:2} ;# b c
echo ${@:0} ;# ./bash 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
echo ${@:0:2} ;# ./bash 1
echo ${@: -7:0}
array=(0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h)
echo ${array[@]:7} ;# 7 8 9 0 a b c d e f g h
echo ${array[@]:7:2} ;# 7 8
echo ${array[@]: -7:2} ;# b c
echo ${array[@]: -7:-2} ;# bash: -2: substring expression < 0
echo ${array[@]:0} ;# 0 1 2 3 4 5 6 7 8 9 0 a b c d e f g h
echo ${array[@]:0:2} ;# 0 1
echo ${array[@]: -7:0} ;#
#####
#
# Parameter expansion: the cases !, #, etc (incomplete!)
# 2024oct12
#
#####
# «parameter-exp-bang» (to ".parameter-exp-bang")
# (find-bashnode "Shell Parameter Expansion" "${!PREFIX*}")
# (find-bashnode "Shell Parameter Expansion" "${!PREFIX@}")
# (find-bashnode "Shell Parameter Expansion" "${!NAME[@]}")
# (find-bashnode "Shell Parameter Expansion" "${!NAME[*]}")
# (find-bashnode "Shell Parameter Expansion" "${#PARAMETER}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER#WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER##WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER%WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER%%WORD}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER/PATTERN/STRING}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER^PATTERN}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER^^PATTERN}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER,PATTERN}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER,,PATTERN}")
# (find-bashnode "Shell Parameter Expansion" "${PARAMETER@OPERATOR}")
#*
FOO=BAR
echo $FOO
unset FOO
echo $FOO
#*
# (find-bashnode "Shell Parameter Expansion")
#*
FOO=BAR
unset BAR
VOID=
echo ${FOO:-QUUX}
echo ${BAR:-QUUX}
echo ${VOID:-QUUX}
echo $FOO
echo $BAR
echo $VOID
echo ${FOO:=QUUX}
echo ${BAR:=QUUX}
echo ${VOID:=QUUX}
echo $FOO
echo $BAR
echo $VOID
#*
# (find-bashnode "Shell Parameter Expansion" "`${PARAMETER:-WORD}'")
SET=hello
unset UNSET
VOID=
echo ${SET:-WORD} ;# -> hello
echo ${UNSET:-WORD} ;# -> WORD
echo ${VOID:-WORD} ;# -> WORD
echo ${UNSET:-$SET} ;# -> hello
#*
#####
#
# What is the bash equivalent of zsh's "|&"?
# 2000sep10
#
#####
# «pipe_stdout_stderr» (to ".pipe_stdout_stderr")
# (find-bashnode "Redirections")
# (find-bashnode "Redirections" "2>&1")
# (find-bashnode "Redirections" "Redirecting Standard Output and Standard E")
# (find-bashnode "Pipelines")
# (find-bashnode "Redirections" "duplicate output file descriptors")
# (find-node "(zsh)Redirection")
# (find-node "(zsh)Redirection" "duplicated")
# (eeman "2 dup2")
# (find-bashnode "Invoking Bash" "`-c STRING'")
# Hey, the FAQ has a quick answer:
# (find-fline "/usr/doc/bash/FAQ.gz" "like csh does with `|&'?")
# (find-fline "/usr/doc/bash/FAQ.gz" "command 2>&1 | command2")
# (find-bashfaqfile "FAQ" "like csh does with `|&'?")
# (find-bashfaqfile "FAQ" "command 2>&1 | command2")
# zsh's "command |& commands"
# is bash's "command 2>&1 | command2".
#*
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
(echo stdout; echo stderr 1>&2)
(echo stdout; echo stderr 1>&2) > /dev/null
(echo stdout; echo stderr 1>&2) 1> /dev/null
(echo stdout; echo stderr 1>&2) 2> /dev/null
(echo stdout; echo stderr 1>&2) | rev
(echo stdout; echo stderr 1>&2) 2>&1 | rev
{ echo stdout; echo stderr 1>&2; }
{ echo stdout; echo stderr 1>&2; } > /dev/null
{ echo stdout; echo stderr 1>&2; } 1> /dev/null
{ echo stdout; echo stderr 1>&2; } 2> /dev/null
{ echo stdout; echo stderr 1>&2; } | rev
{ echo stdout; echo stderr 1>&2; } 2>&1 | rev
function echo1 () { echo $*; }
function echo2 () { echo $* 1>&2; }
{ echo1 stdout; echo2 stderr; }
{ echo1 stdout; echo2 stderr; } 1> /dev/null
{ echo1 stdout; echo2 stderr; } 2> /dev/null
{ echo1 stdout; echo2 stderr; } | rev
#####
#
# source
# 2024nov07
#
#####
# «source» (to ".source")
# (find-bashnode "Bourne Shell Builtins" ". (a period)")
# (find-bashnode "Bourne Shell Builtins" ". (a period)" "equivalent to" "source")
# (find-bashnode "Bash Builtins" "source FILENAME")
#####
#
# BASH_SOURCE
# 2024dec13
#
#####
# «BASH_SOURCE» (to ".BASH_SOURCE")
# (find-fline "~/LOGS/2024dec13.bash" "from the same place")
# (find-bashnode "Bash Variables" "'BASH_SOURCE'")
# https://mywiki.wooledge.org/BashFAQ/028
#####
#
# special-params
# 2024oct12
#
#####
# «special-params» (to ".special-params")
# (find-es "make" "variables")
# (find-bashnode "Special Parameters")
# (find-bashnode "Special Parameters" "($*)")
# (find-bashnode "Special Parameters" "($@)")
# (find-bashnode "Special Parameters" "($#)")
# (find-bashnode "Special Parameters" "($?)")
# (find-bashnode "Special Parameters" "($-, a hyphen)")
# (find-bashnode "Special Parameters" "($$)")
# (find-bashnode "Special Parameters" "($!)")
# (find-bashnode "Special Parameters" "($0)")
#####
#
# test
# 2021may15
#
#####
# «test» (to ".test")
# (find-es "sh" "test")
# (find-bashnode "Bourne Shell Builtins" "'test'")
# (find-bashnode "Bash Conditional Expressions")
# (find-bashnode "Bash Conditional Expressions" "'STRING1 == STRING2'")
# (find-bashnode "Shell Functions")
* (eepitch-dash)
* (eepitch-kill)
* (eepitch-dash)
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
function f () {
if [ $1 == yes ]; then
echo Yes!
elif [ $1 == no ]; then
echo No!
else
echo Argh!
fi
}
f foo
#####
#
# which
# 2024oct15
#
#####
# «which» (to ".which")
# (find-es "zsh" "which")
# (find-bashnode "Bash Builtins" "type [-afptP] [NAME ...]")
#####
#
# posix sh syntax
# 2000sep27
#
#####
# (find-bashnode "Bourne Shell Builtins" "`test'")
# (find-bashnode "Bourne Shell Builtins" "'test'")
# (find-bashnode "Bash Conditional Expressions")
# (find-bashnode "Bash Conditional Expressions" "`STRING1 == STRING2'")
# (find-bashnode "Bash POSIX Mode")
# (find-bashnode "Conditional Constructs")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
#*
cat > /tmp/tmp.sh <<'---'
if [ $1 == yes ]; then
echo Yes!
elif [ $1 == no ]; then
echo No!
else
echo Argh!
fi
---
bash /tmp/tmp.sh yes
bash /tmp/tmp.sh no
bash /tmp/tmp.sh "no "
bash /tmp/tmp.sh
bash /tmp/tmp.sh foo
#*
cat > /tmp/tmp.sh <<'---'
if [ "$1" == yes ]; then
echo Yes!
elif [ "$1" == no ]; then
echo No!
else
echo Argh!
fi
---
bash /tmp/tmp.sh yes
bash /tmp/tmp.sh no
bash /tmp/tmp.sh "no "
bash /tmp/tmp.sh
bash /tmp/tmp.sh foo
#*
#####
#
# some "test"s (for a makefile)
# 2000oct12
#
#####
rm -Rv /tmp/test/
mkdir /tmp/test/
cd /tmp/test/
mkdir dir
echo -n > file
ln -s nowhere brokenlink
ln -s dir dirlink
ln -s file filelink
# (find-bashnode "Bash Conditional Expressions" "`test'")
#*
cat > $EEG <<'---'
cd
ls -lAFd a e s quux
test -a a ;echo $?
test -a e ;echo $?
test -a s ;echo $?
test -a quux ;echo $?
test ! -a quux ;echo $?
test -a quux -o -a nuug -o -a faa ;echo $?
test -a quux -o -a a -o -a faa ;echo $?
exit
---
eeg bash
#*
#####
#
# arguments with spaces
# 2000nov26 / 2024oct15
#
#####
# «args_with_spaces» (to ".args_with_spaces")
# (to "pdsc")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
perl -e 'print "$ARGV[0]::$ARGV[1]\n";' foo bar
perl -e 'print "$ARGV[0]::$ARGV[1]\n";' 'print "Hi!\n";' bar
perl -e 'print "$ARGV[0]::$ARGV[1]\n";''print "Hi!\n";' bar
function f1 () { perl -e 'print "$ARGV[0]::$ARGV[1]\n";' $*; }
function f2 () { perl -e 'print "$ARGV[0]::$ARGV[1]\n";'$*; }
f1 'print "Hi!\n";' bar
f2 'print "Hi!\n";' bar
f1 'print"Hi!\n";' bar
f2 'print"Hi!\n";' bar
#####
#
# adapting pdsc to bash
# 2000nov26
#
#####
# «pdsc» (to ".pdsc")
# (to "args_with_spaces")
# (find-angg ".zshrc" "pdsc")
# (find-angg ".bashrc" "pdsc")
# (find-bashnode "Bourne Shell Builtins" "`shift'")
#*
cat > $EEG <<'---'
function perldsc () {
perl -e '
$_ = $dsc = $ARGV[0];
(($path, $name, $ver, $build) =
m%^(.*/)?(.*?)_(.*?)(-[0-9.a-z]+)?\.dsc$% )
|| die "\"$ARGV[0]\": not a dsc\n";
'$*
}
perldsc 'print "/usr/src/$name-$ver\n"' /somedir/vrms_1.4.dsc
perldsc 'print"/usr/src/$name-$ver\n"' /somedir/vrms_1.4.dsc
function dscdir () { perldsc 'print"/usr/src/$name-$ver\n"' $*; }
function pdsc () {
D=$(dscdir $*) && {
echo rm -Rv $D
echo cd /usr/src/
echo dpkg-source -sn -x $1
echo cd $D
}
}
pdsc /somedir/vrms_1.4.dsc
---
eeg bash
#*
# (find-angg ".bashrc" "pdsc")
cat > $EEG <<'---'
pdsc $SDEBIAN/dists/potato/main/source/admin/vrms_1.4.dsc
---
eeg bash
#*
/snarf/ftp/ftp.debian.org/debian/dists/potato/main/source/admin/vrms_1.4.dsc
function dscdir () { perldsc 'print "/usr/src/$name-$ver\n"' $* }
function pdsc () {
D=$(dscdir $*) && {
rm -Rv $D
cd /usr/src/
dpkg-source -sn -x $1
cd $D
}
}
# Example:
# pdsc /debian/dists/slink/main/source/sound/workbone_2.40-1.dsc
# (find-fline "/usr/bin/dpkg-source")
#*
# (find-bashnode "Looping Constructs")
# (find-bashnode "Conditional Constructs")
# (find-bashnode "Bash Conditional Expressions")
i=1
while [[ $i -le 10 ]]; do
echo $i
i=$[$i+1]
done
#*
#####
#
# bashref
# 2001oct27
#
#####
# (find-sftpfile "ftp.gnu.org/pub/gnu/bash/")
# (find-sftpfile "ftp.gnu.org/pub/gnu/bash/bashref.texi.gz")
# (find-bashnode "Redirections" "format of here-documents")
#####
#
# exit codes and if
# 2004oct14
#
#####
# «exit-code-and-if» (to ".exit-code-and-if")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
function foo () { return $1; }
foo 99; echo $?
if foo 0; then echo y; else echo n; fi
if foo 1; then echo y; else echo n; fi
# function absolute () { readlink -f $1 }
function absolute () { case $1 in; /*) echo $1;; *) echo $PWD/$1;; esac; }
absolute ~/foo
absolute foo
#####
#
# completion
# 2004oct04
#
#####
# (find-fline "/etc/")
# (find-fline "/etc/bash.bashrc")
# (find-fline "/etc/bash_completion")
# (find-fline "/etc/bash_completion.d/")
# (find-bashnode "Programmable Completion Builtins")
#####
#
# bash doesn't echo here-docs in "source" in verbose mode
# 2006sep11
#
#####
# «here-docs-verbose-mode» (to ".here-docs-verbose-mode")
# «mailing-list» (to ".mailing-list")
# http://lists.nongnu.org/mailman/listinfo/bug-bash
# http://lists.gnu.org/archive/html/bug-bash/2006-09/threads.html
# http://lists.gnu.org/archive/html/bug-bash/2006-09/msg00053.html
# (eekill "bug-bash@gnu.org")
# (eekill "Here-doc lines not echoed in \"source\" in verbose mode")
Hello list,
There's one situation in which I prefer zsh's behaviour over bash's...
Can anyone help me to make bash behave like zsh in this case? The fix
doesn't need to be a pure shell thing, there's no problem if I need
to patch the C source locally, I can keep a patched bash in ~/bin/, as
this is just for interactive use...
Here it is: when "verbose" mode is on (i.e., after "set -v") then
"source"ing (a.k.a. "."-ing) a script in zsh outputs all the script
lines and, as they are executed, also their output; doing the same in
bash outputs the script lines _minus the ones that belong to
here-documents_, plus their outputs. Here's an example:
/home/edrx(zsh)$ # Prepare the temporary script
/home/edrx(zsh)$ cat > /tmp/ee.sh <<'%%%'
> cd /tmp/
> rev <<'---'
> foo
> bar
> ---
> echo $[1+2]
> %%%
/home/edrx(zsh)$
/home/edrx(zsh)$ # Make 'ee' run it in verbose mode
/home/edrx(zsh)$ function ee () { set -v; . /tmp/ee.sh; set +v; }
/home/edrx(zsh)$
/home/edrx(zsh)$ # Run it - note how in zsh the here-doc lines
/home/edrx(zsh)$ # ARE echoed
/home/edrx(zsh)$ ee
cd /tmp/
rev <<'---'
foo
bar
---
oof
rab
echo $[1+2]
3
/tmp(zsh)$
/home/edrx(bash)$ # Prepare the temporary script
/home/edrx(bash)$ cat > /tmp/ee.sh <<'%%%'
> cd /tmp/
> rev <<'---'
> foo
> bar
> ---
> echo $[1+2]
> %%%
/home/edrx(bash)$
/home/edrx(bash)$ # Make 'ee' run it in verbose mode
/home/edrx(bash)$ function ee () { set -v; . /tmp/ee.sh; set +v; }
/home/edrx(bash)$
/home/edrx(bash)$ # Run it - note how in bash the here-doc lines
/home/edrx(bash)$ # are NOT echoed
/home/edrx(bash)$ ee
cd /tmp/
rev <<'---'
oof
rab
echo $[1+2]
3
/tmp(bash)$
Thanks in advance,
Eduardo Ochs
http://angg.twu.net/
P.S.: here are some links that explain why I need to source
temporary scripts in verbose mode...
http://angg.twu.net/eev-article.html
http://angg.twu.net/eev-current/eev.el.html#eev
http://angg.twu.net/eev-current/README.html
http://angg.twu.net/eev-current/doc/shot-f3.png
#####
#
# bash-3.1 (for its manual in info formal - it's non-DFSG and not in etch)
# 2007may14
#
#####
# «bash-3.1-info» (to ".bash-3.1-info")
# (find-angg ".emacs" "bash")
# (find-es "dpkg" "install-info")
# (find-bashsrcfile "doc/bashref.info" "START-INFO-DIR-ENTRY")
# (find-status "bash")
# (find-vldifile "bash.list")
# (find-udfile "bash/")
# (find-status "bash-doc")
# (find-vldifile "bash-doc.list")
# (find-udfile "bash-doc/")
# (find-man "8 install-info")
# (find-node "(bashref)")
# (find-fline "~/info/bashref.info")
# (find-status "bash")
# (find-vldifile "bash.list")
# (find-udfile "bash/")
# (find-status "bash-doc")
# (find-vldifile "bash-doc.list")
# (find-udfile "bash-doc/")
# Strange, bash-doc in etch says that it includes the info docs, but
# it doesn't...
# http://ftp.gnu.org/gnu/bash/bash-3.1.tar.gz
#*
rm -Rfv ~/usrc/bash-3.1/
tar -C ~/usrc/ -xvzf \
$S/http/ftp.gnu.org/gnu/bash/bash-3.1.tar.gz
cd ~/usrc/bash-3.1/
#*
# Not really needed... what we want is bashref.info,
# that comes in the tarball.
# (find-bashsrcfile "")
# (find-bashsrcfile "omd")
# (find-bashsrcfile "doc/" "bashref.info")
# (find-bashsrcfile "doc/bashref.info")
cd ~/usrc/bash-3.1/
./configure |& tee oc
make doc |& tee omd
#*
# «bash-3.2-info» (to ".bash-3.2-info")
# http://ftp.gnu.org/gnu/bash/bash-3.2.tar.gz
#
rm -Rv ~/usrc/bash-3.2/
tar -C ~/usrc/ -xvzf \
$S/http/ftp.gnu.org/gnu/bash/bash-3.2.tar.gz
cd ~/usrc/bash-3.2/
#*
# (find-fline "~/info/")
# (find-fline "~/info/bashref.info")
# (find-zsh "cd ~/info/ && mydiff bashref.info")
# cd ~/usrc/bash-3.1/doc/
cd ~/usrc/bash-3.2/doc/
cp -v bash*info ~/info/
cd ~/info/
patch -p0 bashref.info <<'%%%'
30c30
< * Bash: (bash). The GNU Bourne-Again SHell.
---
> * Bash: (bashref). The GNU Bourne-Again SHell.
%%%
# install-info --section Shells Shells --quiet /usr/share/info/zsh.info.gz
# sudo install-info --section Shells Shells ~/info/bashref.info
sudo ginstall-info \
--section=Shells \
--dir-file=/usr/share/info/dir \
~/info/bashref.info
#*
# (find-man "1 ginstall-info")
# (find-sh "locate -i info/dir")
# (find-fline "/usr/share/info/" "dir\n")
# (find-fline "/usr/share/info/dir")
# (find-sh "locate -i info/dir")
# (find-zsh "dmissing info/bash")
#*
# «bash-4.1-info» (to ".bash-4.1-info")
# http://ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
# (eev-bounded)
#
rm -Rfv ~/usrc/bash-4.1/
tar -C ~/usrc/ -xvzf \
$S/http/ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
cd ~/usrc/bash-4.1/
cd ~/usrc/bash-4.1/doc/
cp -v bash*info ~/info/
# (find-fline "~/info/")
# (find-bashnode "")
#*
# (code-c-d "bashsrc" "~/usrc/bash-4.1/")
# (find-bashsrcfile "")
# (find-bashsrcfile "doc/")
#*
# (code-c-d "bashsrc" "~/usrc/bash-3.1/")
# (find-bashsrcfile "")
# (find-bashsrcfile "Makefile.in")
# (find-bashsrcfile "Makefile")
# (find-bashnode "")
# (find-bashnode "Bash Variables" "`TMOUT'")
# http://ftp.gnu.org/gnu/bash/bash-3.2.tar.gz
# http://ftp.gnu.org/gnu/bash/bash-4.0.tar.gz
# http://ftp.gnu.org/gnu/bash/bash-4.1.tar.gz
#*
# (code-c-d "bash" "~/usrc/bash-3.2/")
# (find-bashfile "")
#####
#
# bash-doc
# 2010sep11
#
#####
# «bash-doc» (to ".bash-doc")
# (find-status "bash-doc")
# (find-vldifile "bash-doc.list")
# (find-udfile "bash-doc/")
# (find-bashfile "examples/bashdb/bashdb.el")
# (find-zsh "availabledebs | sort | grep bash")
# (find-bashnode "Bourne Shell Variables" "PS1")
# (find-bashnode "Bourne Shell Variables" "PS2")
# (find-bashnode "Interactive Shell Behavior" "PS1")
# (find-bashnode "Interactive Shell Behavior" "PS2")
#####
#
# Prompt (PS1)
# 2012oct27
#
#####
# «prompt» (to ".prompt")
# (find-angg ".bashrc" "prompt")
# (find-sh "uname --help")
# (find-sh0 "uname -n")
# (find-sh0 "uname -n | cut -b1-2")
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
export PS1='\u@\h:\w\$ '
echo PS1="\$PWD# "
export PS1="\$PWD# "
export PS1="\$PWD(\\u)# "
export PS1="\$PWD(\\u)\\\$ "
export PS1="\$PWD(\\u:$(uname -n))# "
export PS1="\$PWD(\\u:$(uname -n | cut -b1-2))# "
export PS1="\$PWD(\\u:$(uname -n | cut -b1-2))\$ "
export PS1="\$PWD(\\u:$(uname -n | cut -b1-2))\\\$ "
echo $PS1
uname
uname -a
uname -n
#####
#
# Something corresponding to the TTY var in zsh
# 2012mar28
#
#####
# «tty-var» (to ".tty-var")
# (find-es "zsh" "tty-var")
# (find-man "chvt")
# (find-status "console-tools")
# (find-vldifile "console-tools.list")
# (find-udfile "console-tools/")
# (find-status "kbd")
# (find-vldifile "kbd.list")
# (find-udfile "kbd/")
#####
#
# .bashrc (making it always be read)
# 2012mar28
#
#####
# «login-shell» (to ".login-shell")
# (find-bashnode "Interactive Shell Behavior")
# (find-bashnode "Invoking Bash" "`--norc'")
# (find-bashnode "Invoking Bash" "`--login'")
# (find-bashnode "Invoking Bash" "A _login_ shell is one")
# (find-bashnode "Bash Startup Files" "`--login'")
# (find-eevfile "BUGS" "bash doesn't read ~/.bashrc")
#####
#
# process substitution
# 2013oct02
#
#####
# «process-substitution» (to ".process-substitution")
# http://mywiki.wooledge.org/ProcessSubstitution
# http://mywiki.wooledge.org/BashFAQ/024
# (find-bashnode "Process Substitution")
# (find-bashnode "Process Substitution" "<(LIST)")
#####
#
# shellshock
# 2014sep26
#
#####
# «shellshock» (to ".shellshock")
# http://safeandsavvy.f-secure.com/2014/09/26/shellshock-only-concerns-server-admins-wrong/
# http://www.ibtimes.co.uk/what-shellshock-os-x-linux-bash-bug-that-could-be-bigger-heartbleed-1467201
# https://www.digitalocean.com/community/tutorials/how-to-protect-your-server-against-the-shellshock-bash-vulnerability
# (find-status "bash")
# (find-vldifile "bash.list")
# (find-udfile "bash/")
# (find-udfile "bash/changelog.Debian.gz" "which contain shell functions.")
sudo apt-get update && sudo apt-get install --only-upgrade bash
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
env x='() { :;}; echo vulnerable' bash -c 'echo hello'
vulnerable
hello
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for 'x'
hello
#####
#
# Julio Neves
# 2015aug28
#
#####
# «julio-neves» (to ".julio-neves")
# http://wiki.softwarelivre.org/TWikiBar/WebHome
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo001
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo002
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo003
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo004
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo005
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo006
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo007
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo008
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo009
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo010
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarPapo011
# http://wiki.softwarelivre.org/TWikiBar/TWikiBarBirinaite
#####
#
# set
# 2021aug19
#
#####
# «set» (to ".set")
# (find-es "zsh" "which")
# (find-node "(bash)The Set Builtin")
# (find-node "(bash)The Set Builtin" "If no options")
# (find-node "(bash)Bash Builtins" "'typeset'")
# (find-node "(bash)Bash Builtins" "'declare'")
# (find-node "(bash)Bash Builtins" "'alias'")
# How can I determine whether a command exists anywhere in my PATH?
# http://mywiki.wooledge.org/BashFAQ/081
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
shelisp_dired () { printf '\e_#EMACS# (dired \"%s\") \a' "$@"; }
alias dired=shelisp_dired
set
typeset -fp shelisp_dired
declare -fp shelisp_dired
alias dired
#####
#
# unset -f
# 2021aug18
#
#####
# «unset-f» (to ".unset-f")
# (find-node "(bash)Bourne Shell Builtins" "unset [-fnv] [NAME]")
#####
#
# letter-combos-for-6397
# 2021oct01
#
#####
# «letter-combos-for-6397» (to ".letter-combos-for-6397")
# https://news.ycombinator.com/item?id=28721403 Learning Common Lisp to beat Java and Rust on a phone encoding problem (athaydes.com)
# https://news.ycombinator.com/item?id=28722448 All letter combos for the number "6397":
* (eepitch-bash)
* (eepitch-kill)
* (eepitch-bash)
m[0]=0;m[1]=1;m[2]="{a,b,c}";m[3]="{d,e,f}";m[4]="{g,h,i}";m[5]="{j,k,l}";
m[6]="{m,n,o}";m[7]="{p,q,r,s}";m[8]="{t,u,v}";m[9]="{w,x,y,z}"
var=$(echo ${m[6]}${m[3]}${m[9]}${m[7]})
eval echo $var
#####
#
# Curso de shell do Blau (2021), aula 5
# 2021nov17
#
#####
# «blau-2021-05» (to ".blau-2021-05")
# https://blauaraujo.com/curso-shell-gnu/aula-05-depois-do-enter/
# https://blauaraujo.com/curso-shell-gnu/aula-05-depois-do-enter/#5.3
# https://blauaraujo.com/shell/
# https://blauaraujo.com/shell/livro/05-depois_do_enter#regras_de_citacao_quoting
# http://blauaraujo.com/
# https://www.youtube.com/watch?v=kPeMKkPB4KQ
• (eepitch-bash)
• (eepitch-kill)
• (eepitch-bash)
# Seção 5.3:
alias zzz='echo Está dormindo?'
zzz
alias
alias | grep zzz
fruta=banana
alias teste1='echo $fruta'
alias teste2="echo $fruta"
alias | grep 'alias teste'
teste1
teste2
fruta=laranja
teste1
teste2
#####
#
# vagner-2022-04
# 2022apr03
#
#####
# «vagner-2022-04» (to ".vagner-2022-04")
# 1. Install bash-doc to have access to the info manual
# 2. Learn code-c-d in the sections 9, 9.1. and 9.2 of the main eev tutorial
# 3. Learn how to use `M-h M-h' to generate links to the bash manual
# 4. Learn how to make `find-es' and `find-angg' wget files from angg.twu.net
# 5. Learn how to use test blocks in shell scripts
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
sudo apt-get install bash-doc
# https://packages.debian.org/bullseye/bash-doc
# (find-status "bash-doc")
# (find-vldifile "bash-doc.list")
# (find-udfile "bash-doc/")
# (find-node "(bash)Top")
;; Copy this to your ~/.emacs:
;; (find-eev-quick-intro "9. Shorter hyperlinks")
;; (find-eev-quick-intro "9.1. `code-c-d'")
;; (find-eev-quick-intro "9.2. Extra arguments to `code-c-d'")
(code-c-d "bash" "/usr/share/doc/bash/examples/" "bash")
;; (find-bashfile "")
;; (find-bashfile "INDEX.txt")
;; (find-bashfile "misc/aliasconv.sh")
;; (find-bashnode "")
;; (find-bashnode "Indexes")
;; (find-1stclassvideos)
;; (find-1stclassvideo-links "2022findeevangg")
;; (find-1stclassvideoindex "2022findeevangg")
;; Title: Running executable notes from http://angg.twu.net/ with find-angg and find-wget
;; Page: http://angg.twu.net/eev-find-angg.html
;; Play: (find-2022findeevanggvideo "0:00")
;; Try: (find-angg-es-links)
;; (find-eev-quick-intro "4. Creating Elisp Hyperlinks")
;; (find-eev-quick-intro "4.1. `find-here-links'")
;; (find-eev-quick-intro "4.1. `find-here-links'" "`M-h M-h'")
;; (find-eev-quick-intro "4.2. `find-ekey-links' and friends")
;; (find-eev-quick-intro "4.2. `find-ekey-links' and friends" "M-h M-k")
;; (find-eev-quick-intro "10.2. Generating short hyperlinks to info nodes")
;; (find-1stclassvideos)
;; (find-1stclassvideo-links "eev2021")
;; Title: Test blocks
;; Page: http://angg.twu.net/emacsconf2021.html
;; Play: (find-eev2021video "0:00")
;; (eek "M-h M-f eeit")
;; (find-efunction 'eeit)
;; (find-eepitch-intro "3. Test blocks")
#####
#
# emacs-as-a-bash-ide
# 2022oct07
#
#####
# «emacs-as-a-bash-ide» (to ".emacs-as-a-bash-ide")
# https://irreal.org/blog/?p=10842 Emacs As A Bash IDE
# https://www.youtube.com/watch?v=LTC6SP7R1hA&t=2s
#####
#
# ping-and-date
# 2023may07
#
#####
# «ping-and-date» (to ".ping-and-date")
# (find-fline "~/LOGS/2023may07.emacs" "<twb> x & y & wait")
* (eepitch-shell3)
* (eepitch-kill)
* (eepitch-shell3)
{
ping 8.8.8.8 2>&1 &
while true; do date; sleep 5; done &
wait
} |& tee /tmp/op
#####
#
# sh-mode
# 2024jan06
#
#####
# «sh-mode» (to ".sh-mode")
# Setting up indent for shell type bash
# Indentation variables are now local.
# Indentation setup for shell type bash
# (find-efunctiondescr 'sh-mode)
# (find-efunction 'sh-mode)
# (sh-shell . bash)
# (find-efunction 'ee-insert-test-sh-mode)
#####
#
# shellcheck
# 2024dec12
#
#####
# «shellcheck» (to ".shellcheck")
# (find-fline "~/LOGS/2024dec12.bash")
#####
#
# crdt-12
# 2025jun27
#
#####
# «crdt-12» (to ".crdt-12")
# https://holdtherobot.com/blog/crdt-messenger-in-12-lines-of-bash/
http://tldp.org/LDP/abs/html/
<zendeavor> !type
<greybot> type tells you how a command will be interpreted by the
shell. Don't use 'which'; use 'type -P' instead, because
it's portable and consistent.
http://mywiki.wooledge.org/BashPitfalls#pf25
# (find-node "(bashref)Invoking Bash" "`--norc'")
# (find-node "(bashref)Invoking Bash" "`--norc'" "invoked as `sh'")
# (find-man "bash")
(find-man "1 bash" "--norc" "~/.bashrc" "invoked as sh")
(find-man "1 bash" "\nINVOCATION\n" "interactive shell")
(find-man "1 bash" "\nINVOCATION\n" "interactive shell" " ~/.bashrc")
(find-man "1 bash" "\nFILES\n" "~/.bashrc" "individual per-interactive-shell")
# (find-man "1 bash" "\nINVOCATION\n")
# http://tldp.org/LDP/abs/html/index.html
# http://tldp.org/guides.html
# http://tldp.org/LDP/Bash-Beginners-Guide/Bash-Beginners-Guide.txt.gz
# http://tldp.org/LDP/abs/abs-guide.txt.gz
https://blog.dnmfarrell.com/post/bash-function-names-can-be-almost-anything/
https://wiki.bash-hackers.org/howto/redirection_tutorial
https://news.ycombinator.com/item?id=28324311 Illustrated Redirection Tutorial (bash-hackers.org)
# (find-man "7 bash-builtins")
# (find-man "7 bash-builtins" "cd [-L|[-P [-e]] [-@]] [dir]")
https://news.ycombinator.com/item?id=29318751 Bash Patterns I Use Weekly (will-keleher.com)
https://news.ycombinator.com/item?id=29845232 Why “process substitution” is a late feature in Unix shells (utoronto.ca)
https://news.ycombinator.com/item?id=30363506 Pure Bash Bible – A collection of pure bash alternatives to external processes (github.com/dylanaraps)
https://superuser.com/questions/232885/can-you-share-wisdom-on-using-histignore-in-bash
https://news.ycombinator.com/item?id=31250275 Bash-Oneliner: A collection of handy Bash One-Liners and terminal tricks (github.com/onceupon)
https://news.ycombinator.com/item?id=31796261 Pipes, deadlocks, and strace annoyingly fixing them (complete.org)
https://github.com/ThomasHabets/goodpipe
https://blog.habets.se/2021/06/The-uselessness-of-bash.html
https://news.ycombinator.com/item?id=33048618 Bash one-liner to produce a list of HEX color codes that read like English words (gist.github.com)
https://abochannek.github.io/bash/globbing/2021/09/10/bash-pattern-matching.html
https://en.wikipedia.org/wiki/Shellshock_(software_bug)
https://news.ycombinator.com/item?id=36605869 Tell HN: People forget that you can stick any data at the end of a bash script
https://muhammadraza.me/2023/shell-functions/
https://github.com/dylanaraps/writing-a-tui-in-bash
https://wizardzines.com/comics/bash-debugging/
https://news.ycombinator.com/item?id=39568728 Bash Debugging (wizardzines.com)
https://massimo-nazaria.github.io/nlp.html
https://github.com/metal3d/bashsimplecurses
https://news.ycombinator.com/item?id=41086789 Bashsimplecurses: Simple curses library made in bash to draw terminal interfaces (github.com/metal3d)
https://www.shell.how/
https://news.ycombinator.com/item?id=41336497 Shell.how: Explain Shell Commands (shell.how)
https://nochlin.com/blog/6-techniques-i-use-to-create-a-great-user-experience-for-shell-scripts
https://news.ycombinator.com/item?id=41512899 Techniques I Use to Create a Great User Experience for Shell Scripts (nochlin.com)
https://www.oilshell.org/blog/2024/09/retrospective.html
https://www.oilshell.org/blog/2024/09/project-overview.html
https://www.oilshell.org/blog/2021/12/backlog-project.html
https://www.oilshell.org/blog/2024/09/line-counts.html
https://news.ycombinator.com/item?id=41548278 A bullet hell game written in bash (twitter.com/someunusualgame)
https://github.com/SomeUnusualGames/Tux-vs-Mutant-Window/
https://xcancel.com/SomeUnusualGame/status/1834946212610400522
https://github.com/oils-for-unix/oils/wiki/The-Biggest-Shell-Programs-in-the-World
https://holdtherobot.com/blog/heredocs-can-make-your-bash-scripts-self-documenting/
https://utcc.utoronto.ca/~cks/space/blog/programming/BashGoodSetEReports
https://journal.bsd.cafe/2025/07/28/the-bard-and-the-shell/
https://news.ycombinator.com/item?id=44666984 Getting decent error reports in Bash when you're using 'set -e' (utcc.utoronto.ca)
http://mywiki.wooledge.org/BashSheet#Arrays
# Local Variables:
# coding: utf-8-unix
# End: