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")
# «.bash_source»		(to "bash_source")
# «.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")
# «.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")




# 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 "")




#####
#
# bash source (3.0)
# 2007jan17
#
#####

# «bash_source»  (to ".bash_source")
# http://ftp.debian.org/debian/pool/main/b/bash/bash_3.0-14.diff.gz
# http://ftp.debian.org/debian/pool/main/b/bash/bash_3.0.orig.tar.gz
# (find-node "(tar)Writing to Standard Output" "tar -xOzf foo.tgz bigfile | process")
#*
rm -Rv ~/usrc/bash-3.0/
tar -xOzf \
    $S/http/ftp.debian.org/debian/pool/main/b/bash/bash_3.0.orig.tar.gz \
    bash-3.0.orig/bash-3.0.tar.gz \
  | tar -C ~/usrc/ -xvzf -
cd     ~/usrc/bash-3.0/

#*
# (code-c-d "bash" "~/usrc/bash-3.0/" :grep)
# (find-bashfile "")
# (find-bashgrep "grep -niH here.doc *")





#####
#
# 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
#
#####

# «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-")
#*
rm -R /tmp/red/
mkdir /tmp/red/
cd    /tmp/red/
{ 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

* (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[@]}



#####
#
# 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")




#####
#
# 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 "[email protected]")
# (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)









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




#  Local Variables:
#  coding:               utf-8-unix
#  End: