syntactic sugar
oneline commands
[!TIP]
cat and EOF
[!NOTE|label:references:]
using heredoc with ssh
ssh -T user@host.com << EOF echo "The current local working directory is: $PWD" echo "The current remote working directory is: \$PWD" EOF
...an operand naming a file can be specified as '-', which means to use the standard input instead of a named file ....
kubectl apply from stdin
[!NOTE|label:references:]
$ cat << 'EOF' | kubectl apply -f - ... ... EOF # or $ kubectl apply -f - << EOF ... ... EOF
git apply from stdin
$ cat >> 'EOF' | git apply --inaccurate-eof --ignore-whitespace ... ... EOF # or $ git apply --inaccurate-eof --ignore-whitespace --stat << 'EOF' ... ... EOF install | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
git apply from clipboard
[!NOTE|label:references:]
$ pbpaste | git apply $ xsel --clipboard --input | git apply # or $ xclip -selection clipboard -o | git apply
patch from stdin
[!NOTE|label:references:]
$ patch --dry-run --ignore-whitespace << 'EOF' ... ... EOF
while read from input
[!NOTE|label:references:]
$ while IFS=\| read -r col1 col2; do echo ">> $col1 .. $col2 <<"; done <<\INPUT
a|b
INPUT
>> a .. b <<
$ tail -f file | while read line; do echo -n $(date -u -Ins); echo -e "\t$line"; done
$ cp -bfS.bak filename filename
ssh
compress and ssh and extract
$ tar cf - . | ssh elsewhere tar xf - -C /other/dir # or: https://www.commandlinefu.com/commands/view/4034/copy-a-folder-tree-through-ssh-using-compression-no-temporary-files $ ssh <host> 'tar -cz /<folder>/<subfolder>' | tar -xvz
tips
[!NOTE|label:references:]
# tips $ tar cfz - . | ssh otherhost "cd /mydir; tar xvzf -" # or: https://www.commandlinefu.com/commands/view/1629/pack-up-some-files-into-a-tarball-on-a-remote-server-without-writing-to-the-local-filesystem $ tar -czf - * | ssh example.com "cat > files.tar.gz" # the z-flag to tar does compression. Or you can use -C to ssh: $ tar cf - . | ssh -C otherhost "cd /mydir; tar xvf -"
find and tar
$ find . -name builds -prune -o -type f -print | tar czf ~/m.tar.gz --files-from -
# or find with maxdepth
$ find . -type f -name "config.xml" -maxdepth 2 -prune -print | tar czf ~/config.xml.130.tar.gz --files-from -
# find with special name
$ find . -name config\.xml -type f -print | tar czf ~/m.tar.gz --files-from -
# and ssh and extract
$ tar cf - . | ssh -C otherhost "cd /mydir; tar xvf -"
for JENKINS_HOME
backup all
config.xml
in JENKINS_HOME$ find ${JENKINS_HOME}/jobs \ -maxdepth 2 \ -name config\.xml \ -type f -print | tar czf ~/config.xml.tar.gz --files-from -
back build history
$ find ${JENKINS_HOME}/jobs \ -name builds \ -prune -o \ -type f \ -print | tar czf ~/m.tar.gz --files-from -
$ find $PWD -maxdepth 1 -printf '%.5m %10M %#9u:%-9g %#5U:%-5G [%AD | %TD | %CD] [%Y] %p\n' # or $ find $PWD -maxdepth 1 -printf '%.5m %10M %#9u:%-9g %#5U:%-5G [%AD | %TD | %CD] [%Y] %p\n' | sort -rgbS 50%
[!TIP|label:references:]
$ tar czv file1 file2 file3 | ssh user@host 'tar xzv -C /target/dir'
recursively unrar into dir containing archive
$ find . -name '*.rar' -execdir unrar e {} \;
find and rename
$ find -iname "*.sh" -exec rename "s/.sh$/.shell/" {} \; -print
find and sort
via timestamp
[!NOTE]
How to Find and Sort Files Based on Modification Date and Time in Linux
$ find . -type f -printf "\n%AD %AT %p" | head -n 11 | sort -k1.8n -k1.1nr -k1 # or $ find . -type f -printf "\n%Tm/%Td/%TY %TT %p" | sort -k1.8n -k1.1nr -k1
$ find . -printf "%T<format>\n"
# via %T+ $ find ~/.marslo -type f -printf "%10T+ | %p\n" | sort -r | head -10 # via %Td-%Tm-%TY $ find ~/.marslo -type f -printf "\n%Td-%Tm-%TY %TT %p" | sort -b -k1.7,1.10 -k1.4,1.5 -k1.1,1.2 -r
via awk+sort
$ cat a.txt ABC,1/02/2022,05:50 OPQ,18/10/2023,07:50 HIJ,31/09/2023,08:50 DEF,1/02/2021,06:00 $ awk -F'[,/]' '{printf "%04d-%02d-%02d\t%s\n", $4,$3,$2, $0}' a | sort -r | cut -f2- OPQ,18/10/2023,07:50 HIJ,31/09/2023,08:50 ABC,1/02/2022,05:50 DEF,1/02/2021,06:00
find and copy
[!TIP]
$ find . -type f -newermt '2023-10-16 00:00:00' -exec cp -a --parents -t /path/to/target "{}" \+
# or
$ diff=$(( ($(date --date "24-02-29" +%s) - $(date --date "231016" +%s) )/(60*60*24) ))
$ find . -type f -daystart -mtime -$((diff+1)) -exec cp -a --parents -t /path/to/target "{}" \+
download and extract
[!TIP|label:references:]
gz
$ wget -O - http://example.com/a.gz | tar xz # or $ curl -fsSL http://example.com/a.gz | tar xz # or $ curl -fsSL "http://example.com/a.gz" | tar zxvf - # or: https://www.commandlinefu.com/commands/view/353/extract-tarball-from-internet-without-local-saving $ wget -qO - "http://www.tarball.com/tarball.gz" | tar zxvf -
tar.gz
$ curl -fsSL https://dlcdn.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz | tar xzf - -C /path/to/targeT
tar.xz
$ curl -fsSL https://ftp.gnu.org/gnu/glibc/glibc-2.38.tar.xz | tar -xJf - -C /path/to/target
zip
$ curl -fsSL https://downloads.gradle.org/distributions/gradle-8.4-bin.zip | bsdtar xzf - -C /path/to/target # with password $ curl -fsSL https://path/to/file.zip | bsdtar -xzf- --passphrase <PASSWD_OF_ZIP> - -C <EXTRACT_PATH>
$ wget --mirror --page-requisites --html-extension --convert-links $URL
# https://www.linuxjournal.com/content/downloading-entire-web-site-wget
$ wget --recursive --no-clobber --page-requisites --html-extension --convert-links --restrict-file-names=windows --domains website.org --no-parent sample.com
# or download entire website: https://www.commandlinefu.com/commands/view/901/download-an-entire-website
$ wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com
# https://superuser.com/a/1415765/112396
$ wget --recursive --level 5 --no-clobber --page-requisites --adjust-extension --span-hosts --convert-links --restrict-file-names=windows --domains sample.com --no-parent sample.com
# https://www.commandlinefu.com/commands/view/30/retrieve-a-list-of-all-webpages-on-a-site
$ URL=www.example.com && wget -rq --spider --force-html "http://$URL" && find $URL -type d > url-list.txt && rm -rf $URL
$ wget -r -l1 --no-parent -nH -nd -P/tmp -A".gif,.jpg" http://example.com/images
kubectl apply from stdin
$ cat << EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: $(echo -n 'admin' | base64)
password: $(echo -n 'password' | base64)
EOF
$ for code in {0..255}; do echo -e "\e[38;05;${code}m $code: Test"; done)
# or: https://www.commandlinefu.com/commands/view/6138/show-numerical-values-for-each-of-the-256-colors-in-bash
$ for i in {0..255}; do echo -e "\e[38;05;${i}m${i}"; done | column -c 80 -s ' '; echo -e "\e[m"
# or: https://www.commandlinefu.com/commands/view/11759/show-numerical-values-for-each-of-the-256-colors-in-bash-for-bold-and-normal-fonts
$ for code in $(seq -w 0 255); do for attr in 0 1; do printf "%s-%03s %bTest%b\n" "${attr}" "${code}" "\e[${attr};38;05;${code}m" "\e[m"; done; done | column -c $((COLUMNS*2))
# better vesion
$ for code in $(seq -w 0 255); do for attr in 0 1; do printf "%b%s-%03s%b\n" "\e[${attr};38;05;${code}m" "${attr}" "${code}" "\e[m"; done; done | column -c $((COLUMNS*3))
# .. zsh ..
# or: https://www.commandlinefu.com/commands/view/5876/show-numerical-values-for-each-of-the-256-colors-in-zsh
$ for code in {000..255}; do print -P -- "$code: %F{$code}Test%f"; done
# or: https://www.commandlinefu.com/commands/view/12471/show-numerical-values-for-each-of-the-256-colors-in-zsh
for i in {0..255}; do echo -e "\e[38;05;${i}m\\\e[38;05;${i}m"; done | column -c 80 -s ' '; echo -e "\e[m"
$ rm !(*.foo|*.bar|*.baz)
# https://www.commandlinefu.com/commands/view/4576/remove-everything-except-that-file
$ find . ! -name <FILENAME> -delete
# https://www.commandlinefu.com/commands/view/4570/remove-everything-except-that-file
$ ( shopt -s extglob; rm !(<PATTERN>) )
$ split -b4m file.tgz file.tgz. ; for i in file.tgz.*; do SUBJ="Backup Archive"; MSG="Archive File Attached"; echo $MSG | mutt -a $i -s $SUBJ YourEmail@(E)mail.com
sync mirror
[!NOTE]
$ rsync -aqzH --delay-updates --delete-after msync.centos.org::CentOS /path/to/local/mirror/root
# stream 9
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-All /path/to/local/mirror/root
# or src
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-nosrc /path/to/local/mirror/root
# exclude debuginfo
$ rsync -aqzH --delay-updates --delete-after rsync.stream.centos.org::CentOS-Stream-nodebug /path/to/local/mirror/root
get all declare
[!NOTE|label:references:]
$ declare
$ declare -p
$ declare -xp
# or
$ typeset
$ typeset -p
# or
$ compgen -v
$ compgen -v | while read line; do echo $line=${!line};done
$ compgen -v | while read line; do declare -p $line; done
# or
$ export
$ printenv
print env
[!NOTE|label:references:]
$ set -o posix ; set | awk -F '=' '{ print $1 }'
# or
$ env
$ env | awk -F '=' '{ print $1 }'
$ env | awk -F '=' '{ print $1 }' | tr '\n' ' '
# or
$ printenv
using string as variable name
[!NOTE|label:references:]
$ aa='echo me' $ var='aa' $ eval echo \$$var echo me
$ var1="this is the real value" $ a="var1" $ echo "${!a}" this is the real value
more usage
$ sunny=''' \033[38;5;226m \\ / \033[0m \033[38;5;226m .-. \033[0m \033[38;5;226m ― ( ) ― \033[0m \033[38;5;226m `-’ \033[0m \033[38;5;226m / \\ \033[0m ''' $ fewClouds=''' \033[38;5;226m \\ /\033[0m \033[38;5;226m _ /\"\"\033[38;5;250m.-. \033[0m \033[38;5;226m \\_\033[38;5;250m( ). \033[0m \033[38;5;226m /\033[38;5;250m(___(__) \033[0m ''' $ codeMap=( ["01"]="sunny" ["02"]="fewClouds" ) $ icon="$(/usr/bin/curl -sg "https://api.openweathermap.org/data/3.0/onecall?lat=37.3541132&lon=-121.955174&units=metric&exclude=hourly,daily,minutely,alerts&appid=${OWM_API_TOKEN}" | jq -r .current.weather[].icon)" $ echo ${icon} 02n $ echo -e "${!codeMap["${icon:0:-1}"]}"
using string as var name
<<<
, < <(..)
<<<
, < <(..)
[!TIP]
< <(
is Process Substitution
The difference between
<(...)
and>(...)
is merely which way the redirections are done
< <(..)
&& > >(..)
< <(..)
&& > >(..)
[!NOTE]
$ command1 < <( command2 ) # equals to $ command2 | command1 # if read from file, then using `< /path/to/file`
example:
$ while read line; do echo "-- ${line} --"; done < <(ls -1) # equals to: http://mywiki.wooledge.org/BashFAQ/024 $ ls -1 | while read line; do echo "-- ${line} --"; done # equals to $ ls -1 | xargs -n1 -i bash -c "echo \"-- {} --\"" # equals to read from file via `< /path/to/file` $ ls -1 > ls.txt $ while read line; do echo "-- ${line} --"; done < ls.txt
$ wc < <(date)
1 6 29
# same as:
$ date | wc
1 6 29
< <(..)
[!TIP|label:referencs:]
tips:
# If commandA can read the data from stdin commandB | commandA # You can now get the exit code of commandB from PIPESTATUS. commandB > >(commandA) # You can now get the exit code of commandB from $? (or by putting this in an if) # If commandA cannot read it from stdin, but requires a file argument commandB > >(commandA <(cat)) # Again, commandB's exit code is available from $? # You can also keep commandB's output in memory. When you do this, you can get commandB's exit code from $? or put the assignment in an if b=$(commandB); commandA <<< "$b" # Here, commandA reads commandB's output from stdin
common usage
$ diff <(sort list1) <(sort list2) # or $ while read file; do echo -e "\n\033[1;33m${file}\n---\033[0m" sed -n "/<<<<<<< HEAD/,/>>>>>>> /!d;=;p" ${file} echo -e "\n\033[1;33m---\033[0m" done < <(git grep --no-color -l "<<<<<<< HEAD")
> >(..)
[!TIP]
>(...)
is used less frequently; the most common situation is in conjunction withtee(1)
.>(...)
is handy when redirecting the output to multiple files, based on some criteria.
# For example: $ some_command | tee >(grep A > A.out) >(grep B > B.out) >(grep C > C.out) > /dev/null
parameter substitution
${variable-default}
if variable is unset, use default
${variable=default}
if variable is unset, set variable to default
${variable+alt}
if variable is set, use alt, else use null string
${variable:-default}
with ":[-=+]"
, condition takes also "declared but null"
arguments substitution
$@
p1 p2 p3 p4 p5 p6
${@: 0}
./args.sh p1 p2 p3 p4 p5 p6
${@: 1}
p1 p2 p3 p4 p5 p6
${@: 2}
p2 p3 p4 p5 p6
${@: 2:1}
p2
${@: 2:2}
p2 p3
${@: -2}
p5 p6
${@: -2:1}
p5
${*: -1}
or ${@: $#}
p6
${@: 1:$#-1}
p1 p2 p3 p4 p5
sample with uncertain parameters
local opt='' local loop=true local path params while ${loop} && [[ $# -gt 0 ]]; do case "$1" in -*) opt+="$1 "; shift;; *) loop=false ;; esac done if [[ 1 = "$#" ]]; then path='' params="$1" else path=${*: -1} params=${*:1:$#-1} fi
echo '---------------- before shift -------------------' echo ".. \$# : $#" echo ".. \$@ : $@" echo ".. \$* : $*" echo '---------------- after shift -------------------' opt='' ss='' loop=true while $loop && [[ $# -gt 0 ]]; do case "$1" in -*) opt+="$1 "; shift;; *) loop=false ;; esac done echo ".. \$# : $#" echo ".. \$@ : $@" echo ".. \$* : $*" echo ".. \$opt : $opt" if [[ 0 = "$#" ]]; then echo -e "\033[0;33mERROR: must provide at least one non-opt param\033[0m" exit 2 elif [[ 1 = "$#" ]]; then path='' params="$1" else path=${*: -1} params=${*:1:$#-1} fi echo '---------------- result -------------------' echo ">> opt : ${opt}" echo ">> params : ${params}" echo ">> path : ${path}"
$ ./c.sh -1 -2 --3-4 a b c d e ---------------- before shift ------------------- .. $# : 8 .. $@ : -1 -2 --3-4 a b c d e .. $* : -1 -2 --3-4 a b c d e ---------------- after shift ------------------- .. $# : 5 .. $@ : a b c d e .. $* : a b c d e .. $opt : -1 -2 --3-4 .. $ss : a b c d e ---------------- result ------------------- >> opt : -1 -2 --3-4 >> params : a b c d >> path : e $ ./c.sh aa bb ---------------- before shift ------------------- .. $# : 2 .. $@ : aa bb .. $* : aa bb ---------------- after shift ------------------- .. $# : 2 .. $@ : aa bb .. $* : aa bb .. $opt : .. $ss : aa bb ---------------- result ------------------- >> opt : >> params : aa >> path : bb $ ./c.sh -1 ---------------- before shift ------------------- .. $# : 1 .. $@ : -1 .. $* : -1 ---------------- after shift ------------------- .. $# : 0 .. $@ : .. $* : .. $opt : -1 ERROR: must provide at least one non-opt param
quotas
${@@Q}
# a.sh line="${@@Q}" echo $line $ bash a.sh -a -b --c='1 2 3' '-a' '-b' '--c=1 2 3'
# https://stackoverflow.com/a/39463371/2940319 $ expand-q() { for i; do echo ${i@Q}; done; } $ expand-q -a -b --c='1 2 3' '-a' '-b' '--c=1 2 3'
# https://stackoverflow.com/a/72745869/2940319 function quote() { local QUOTED_ARRAY=() for ARGUMENT; do case ${ARGUMENT} in --*=*) QUOTED_ARRAY+=( "${ARGUMENT%%=*}=$(printf "%q" "${ARGUMENT#*=}")" ) shift ;; *) QUOTED_ARRAY+=( "$(printf " %q" "${ARGUMENT}")" ) ;; esac done echo ${QUOTED_ARRAY[@]} } ARGUMENTS="$(quote "${@}")" echo "${ARGUMENTS}"
printf " %q" "${@}"
[!NOTE]
while test -n "$1"; do case "$1" in -- ) shift; GIT_OPT=$(printf " %q" "${@}"); break ;; esac done GIT_OPT="${GIT_OPT#\ \'\'}"
# https://stackoverflow.com/a/39463371/2940319 $ params-q() { printf "%q\n" "$@"; } $ params-q -a -b --c='1 2 3' -a -b --c=1\ 2\ 3
String replacement
[!TIP]
# a.sh while test -n "$1"; do case "$1" in -- ) shift; GIT_OPT="$@";; * ) shift;; esac done GIT_OPT=$(echo "${GIT_OPT}" | sed -r 's/\s+--/\n--/g' | sed -r "s/^([^=]+)=(.+)$/\1='\2'/g" | sed -e 'N;s/\n/ /' ) echo $GIT_OPT $ bash a.sh -a -b -- --c='1 2 3' --c='1 2 3'
# https://stackoverflow.com/a/8723305/2940319 # a.sh C='' for i in "$@"; do i="${i//\\/\\\\}" C="$C \"${i//\"/\\\"}\"" done echo $C $ bash ~/a.sh -a -b --c='1 2 3' "-a" "-b" "--c=1 2 3"
string manipulations
${#string}
length
${string:position}
substring, or positional parameter with $*
and $#
${string:position:length}
substring
${string#substring}
deletes shortest match of $substring from front of $string
${string##substring}
same but longest match
${string%substring}
shortest from back
${string%%substring}
longest from back
${string/substring/replacement}
replace first match
${string//substring/replacement}
replace all matches
${string/#substring/replacement}
replace if matches front end of $string
${string/%substring/replacement}
replace if matches back end of $string
${var^}
uppercase first char
${var^^}
uppercase all chars
${var,}
lowercase first char
${var,,}
lowercase all chars
compound comparison
problematic code:
([ "$x" ] || [ "$y" ]) && [ "$z" ]
correct code:
{ [ "$x" ] || [ "$y" ]; } && [ "$z" ]
example
problematic code:
export foo="$(mycmd)"
correct code:
foo="$(mycmd)" export foo
escape code
[!TIP] references:
\x1b
Node.js
hex char
\x1b
Node.js w/ TS
hex char
\u001b
Python
hex char
\033
GNU Cpp
octal char
\033
ANSI C
octal char
\033
POSIX-compliant shells
octal char
\e
Bash
-
\c[
-
control char
echo
echo var name from variable
[!NOTE]
sample:
$ foo=bar # `bar` is the var name $ bar=baz # `baz` is the var value
typeset
$ typeset -p "${foo}"$ declare -- bar="baz"
eval \$$
$ eval echo \$$foo baz
more:
$ echo \$$foo $bar # or $ echo '$'$foo $bar
{!parameter}
$ echo "${!foo}" baz
echo var name
[!NOTE]
sample
$ a1='a' $ a2='aa' $ c1='c' $ c2='cc'
typeset
$ typeset -p c2 declare -- c2="cc"
{!parameter@}
$ echo "${!c@}" c1 c2 $ echo "${!a@}" a1 a2
more
superEcho() { echo "$1 = ${!1}" } $ superEcho foo foo = bar $ superEcho bar bar = baz
ls
[!NOTE|label:references]
# show file only
$ ls -p | command grep -v /
# show folder only
$ ls -p | command grep / | command grep "^."
# show all files ( including hidden )
$ ls -Ap | command grep -v / | command grep "^."
# show all folders ( including hidden )
$ ls -Ap | command grep / | command grep "^."
# show hidden folder only
$ ls -Ap | command grep / | command grep "^\." | command grep "\."
# show hidden file only
$ ls -Ap | command grep -v / | command grep "^\." | command grep "\."
# show all including hidden
$ ls -Ap
# show hidden file and folder
$ ls -Ap | command grep "^\."
bash completion
[!NOTE|label:references]
create bash completion
* An introduction to bash completion: part 2
$ complete -W "--help --verbose --version" foo $ foo --<TAB> --help --verbose --version
paths:
osx:
$(brew --prefix)/etc/bash_completion.d
completion files in
bash-completion@2
:$(brew --prefix bash-completion@2)/share/bash-completion/completions/
centos:
/usr/share/bash-completion/completions
or/etc/bash_completion.d
ubuntu:
/usr/share/bash-completion/completions
print existing completion
$ complete -p vim complete -o bashdefault -o default -F _fzf_opts_completion vim $ complete -p ffs complete -o bashdefault -o default -o nosort -F _fd ffs $ complete -p ff complete -o bashdefault -o default -o nosort -F _fd ff
remove completion
$ complete -p vim complete -o bashdefault -o default -F _fzf_opts_completion vim $ complete -r vim $ complete -p vim -bash: complete: vim: no completion specification
[!TIP|label:references:]
$ compgen --help Display possible completions depending on the options
$ complete # show all commands $ compgen -c
COMMANDDESCRIPTION$ compgen -c
commands
$ compgen -a
aliases
$ compgen -b
built-ins
$ compgen -k
keywords
$ compgen -A function
functions
$ compgen -A function -abck
all above
$ complete complete -o default -F _quotaon quotaon complete -o default -F _fzf_path_completion mv complete -F _postcat postcat complete -o default -o nospace -v -F _fzf_var_completion printenv complete -o default -F __start_kubectl kcn complete -F _filedir_xspec mpg321 complete -F _filedir_xspec tex complete -F _make gmake complete -o bashdefault -o default -F _fzf_path_completion diff3 complete -o default -F _ansible ansible complete -o default -F _fzf_path_completion head complete -o default -F __start_kubectl kt1 complete -o default -F __start_kubectl kt2 complete -o default -F _fzf_path_completion uniq complete -F _command else complete -o default -F __start_kubectl kt3 complete -F _ldapdelete ldapdelete complete -F _configure configure complete -F _filedir_xspec freeamp complete -F _lzma lzma complete -o default -F __start_kubectl kcc complete -F _filedir_xspec gqmpeg complete -F _filedir_xspec texi2html complete -o default -F _complete_groovydoc groovydoc complete -F _filedir_xspec hbpp complete -F _xsltproc xsltproc complete -F _filedir_xspec jadetex complete -F _docker droot complete -o default -F _longopt mkfifo complete -o bashdefault -o default -F _fzf_path_completion svn complete -o default -F _fzf_path_completion tee complete -F _javaws javaws complete -F _mktemp mktemp complete -F _filedir_xspec rpm2cpio complete -F _docker dvi complete -F _make pmake complete -o default -F _repquota repquota complete -F _filedir_xspec hbrun complete -F _autoscan autoscan complete -o default -F __start_kubectl kubectl complete -o default -F _screen screen complete -F _filedir_xspec ps2pdf14 complete -o default -F _fzf_path_completion grep complete -F _fzf_path_completion vi complete -F _autoreconf autoheader complete -F _composite composite complete -F _fzf_path_completion bat complete -F _filedir_xspec ps2pdf13 complete -o default -F _longopt objdump complete -F _filedir_xspec ps2pdf12 complete -o default -F _longopt sha1sum complete -o default -F _longopt cut complete -F _filedir_xspec lyx complete -o bashdefault -o default -F _fzf_path_completion file complete -F _gcc gpc complete -F _filedir_xspec latex complete -o default -F _look look complete -F _gradle gradlew.bat complete -o bashdefault -o default -F _fzf_path_completion hx complete -F _filedir_xspec poedit complete -F _fzf_path_completion view complete -o bashdefault -o default -F _fzf_path_completion dirname complete -F _function typeset complete -o bashdefault -o default -F _fzf_path_completion hg complete -F _command nohup complete -a -F _fzf_alias_completion unalias complete -F _vipw vipw complete -g groupdel complete -F _make gnumake complete -u groups complete -F _filedir_xspec chromium-browser complete -F _filedir_xspec opera complete -F _filedir_xspec kbabel complete -F _fzf_host_completion telnet complete -F _gcc g77 complete -F _filedir_xspec bzme complete -o bashdefault -o default -F _fzf_complete_ssh ssh complete -F _command vsound complete -c which complete -F _fzf_path_completion tar complete -o default -F _longopt m4 complete -F _filedir_xspec madplay complete -o default -F _fzf_opts_completion fzf-tmux complete -F _docker drm complete -F _filedir_xspec dviselect complete -o default -F _fzf_path_completion cp complete -F _mas mas complete -F _animate animate complete -F _man whatis complete -o default -F _complete_groovysh groovysh.sh complete -F _filedir_xspec evince complete -o bashdefault -o default -F _brew brew complete -F _docker dcleanall complete -F _filedir_xspec realplay complete -o default -F _longopt strip complete -o bashdefault -o default -o nospace -F __git_wrap__gitk_main gitk complete -v readonly complete -o nospace -F _fzf_path_completion rsync complete -F _ctest ctest complete -o nospace -F _fzf_dir_completion cd complete -o default -F _complete_groovydoc groovydoc.bash complete -F _known_hosts showmount complete -F _filedir_xspec kdvi complete -o default -F _longopt tac complete -F _ldapaddmodify ldapmodify complete -F _filedir_xspec elinks complete -F _known_hosts fping complete -o default -F _longopt env complete -o default -F _quota quota complete -F _gradle ./gradlew complete -u chfn complete -F _docker drp complete -F _filedir_xspec compress complete -F _filedir_xspec pdfjadetex complete -F _filedir_xspec kghostview complete -F _man man complete -F _filedir_xspec pbunzip2 complete -o default -F _brctl brctl complete -c type complete -F _ldapcompare ldapcompare complete -F _known_hosts ssh-installkeys complete -F _filedir_xspec iceweasel complete -F _filedir_xspec gtranslator complete -F _fzf_path_completion unzip complete -o default -F _longopt expand complete -o default -F _complete_groovyConsole groovyConsole.bash complete -o bashdefault -o default -o nospace -F _fzf_path_completion git complete -F _filedir_xspec lrunzip complete -o default -F _fzf_path_completion ln complete -F _command aoss complete -F _docker drps complete -F _filedir_xspec ggv complete -F _filedir_xspec oomath complete -F _filedir_xspec dvipdfmx complete -o default -F _fzf_path_completion ld complete -F _fzf_path_completion gunzip complete -F _filedir_xspec makeinfo complete -F _filedir_xspec okular complete -o default -F _complete_groovysh groovysh complete -F _ldapsearch ldapsearch complete -F _command xargs complete -j -P '"%' -S '"' jobs complete -o default -F _complete_groovy groovy.sh complete -F _filedir_xspec oowriter complete -o bashdefault -o default -F _fzf_path_completion emacsclient complete -F _cpack cpack complete -o default -F _fzf_path_completion tail complete -o default -F _longopt unexpand complete -o default -F _longopt netstat complete -F _docker dexe complete -o default -F _fzf_path_completion ls complete -F _filedir_xspec epiphany complete -o nospace -F __gio gio complete -o bashdefault -o default -F _fzf_path_completion nvim complete -o dirnames -o nospace -F _fzf_dir_completion pushd complete -F _filedir_xspec acroread complete -o default -o nospace -v -F _fzf_var_completion unset complete -F _postmap postalias complete -F _nmap nmap complete -o default -F _longopt csplit complete -F _known_hosts rsh complete -F _filedir_xspec sxemacs complete -F _command exec complete -F _filedir_xspec aviplay complete -F _ldapmodrdn ldapmodrdn complete -F _filedir_xspec rgvim complete -F _chsh chsh complete -F _autoconf autoconf complete -o default -F _longopt nm complete -o default -F _longopt nl complete -o default -F _complete_grape grape.bash complete -o nospace -F _user_at_host ytalk complete -F _fzf_proc_completion kill complete -F _fzf_path_completion java complete -F _cmake cmake complete -u sux complete -F _cancel cancel complete -F _filedir_xspec znew complete -o default -F _complete_groovydoc groovydoc.sh complete -F _id id complete -o default -F _longopt paste complete -F _ldapaddmodify ldapadd complete -F _docker dip complete -o bashdefault -F _perldoc perldoc complete -F _filedir_xspec kwrite complete -F _root_command really complete -o default -F _complete_groovyc groovyc.bash complete -o bashdefault -o default -o nospace -F __git_wrap__tig_main tig complete -F _filedir_xspec firefox complete -o bashdefault -o default -F _fzf_path_completion open complete -F _ip ip complete -o default -F __start_kubectl klc complete -F _docker drit complete -F _filedir_xspec dvipdfm complete -F _filedir_xspec ly2dvi complete -F _filedir_xspec oodraw complete -F _docker drun complete -F _import import complete -o default -F __start_kubectl kcswatch complete -F _gzip pigz complete -o default -F __start_kubectl kln complete -F _autoscan autoupdate complete -F _known_hosts dig complete -o nospace -F _user_at_host talk complete -F _filedir_xspec xemacs complete -F _docker dls complete -o nospace -F _dd dd complete -F _jarsigner jarsigner complete -F _filedir_xspec kpdf complete -F _man apropos complete -o default -F _longopt df complete -F _command eval complete -F _docker di complete -F _postsuper postsuper complete -F _postconf postconf complete -F _filedir_xspec bibtex complete -o default -F _pip_completion pip complete -F _docker dclr complete -F _postfix postfix complete -F _fzf_path_completion chown complete -F _filedir_xspec netscape complete -o default -F _longopt wget complete -F _command do complete -F _cargo cargo complete -F _gradle gradle complete -F _pgrep pgrep complete -F _filedir_xspec gview complete -F _filedir_xspec lzfgrep complete -o bashdefault -o default -o nosort -F _fd ffs complete -F _filedir_xspec lzless complete -o default -F _fzf_path_completion du complete -F _renice renice complete -F _lsof lsof complete -F _docker dv complete -F _known_hosts tracepath complete -o default -F __start_kubectl kit complete -o default -F _fzf_path_completion wc complete -F _fzf_path_completion gzip complete -F _newgrp newgrp complete -o default -F _ansible-galaxy ansible-galaxy complete -F _filedir_xspec cdiff complete -F _fzf_path_completion emacs complete -F _filedir_xspec zipinfo complete -F _docker dcleani complete -F _filedir_xspec google-chrome complete -F _gcc c++ complete -F _crontab crontab complete -F _filedir_xspec rview complete -A shopt shopt complete -F _docker dcleanc complete -F _root_command sudo complete -F _killall pkill complete -F _fzf_path_completion javac complete -F _fzf_path_completion ftp complete -o default -F _longopt uname complete -o bashdefault -o default -F _rg rg complete -F _known_hosts ping complete -F _filedir_xspec wine complete -F _filedir_xspec galeon complete -F _filedir_xspec pdflatex complete -F _docker dex complete -F _known_hosts rlogin complete -o default -F _fzf_opts_completion fzf complete -F _filedir_xspec portecle complete -o default -F _longopt sha384sum complete -o default -F _fzf_path_completion rm complete -F _filedir_xspec modplugplay complete -F _ri ri complete -o default -F _quotaoff quotaoff complete -F _filedir_xspec dillo complete -F _filedir_xspec fbxine complete -F _filedir_xspec lokalize complete -F _root_command gksudo complete -F _command nice complete -o default -F _longopt tr complete -o default -F _npm_completion npm complete -F _filedir_xspec oocalc complete -o default -F _complete_groovyc groovyc.sh complete -F _gradle gradlew complete -o default -F _longopt sha256sum complete -F _root_command gksu complete -F _filedir_xspec qiv complete -F _chgrp chgrp complete -F _filedir_xspec ps2pdfwr complete -o default -F _edquota edquota complete -F _filedir_xspec harbour complete -o bashdefault -o default -F _fzf_path_completion basename complete -o default -F _longopt ptx complete -F _filedir_xspec dvitype complete -o nospace -F __gsettings gsettings complete -F _gradle ./gradlew.bat complete -F _known_hosts traceroute complete -F _fzf_path_completion bzip2 complete -j -P '"%' -S '"' fg complete -o bashdefault -o default -o nosort -F _fd ff complete -F _convert convert complete -F _filedir_xspec unpigz complete -o default -F _complete_groovy groovy complete -o bashdefault -o default -o nosort -F _fd fd complete -F _filedir_xspec mozilla complete -F _filedir_xspec dvips complete -o default -F _longopt who complete -F _montage montage complete -F _complete compgen complete -F _filedir_xspec ps2pdf complete -F _filedir_xspec gpdf complete -F _complete complete complete -F _filedir_xspec texi2dvi complete -o dirnames -F _umount umount complete -F _function function complete -o bashdefault -o default -F _fzf_path_completion mvim complete -o default -F _fzf_path_completion less complete -o default -F _longopt mknod complete -F _command padsp complete -F _passwd passwd complete -F _filedir_xspec kate complete -F _pkg_config pkg-config complete -o default -F _longopt bison complete -F _filedir_xspec mozilla-firefox complete -F _filedir_xspec kid3-qt complete -o default -F _longopt od complete -F _fzf_path_completion bunzip2 complete -o default -o dirnames -F _mount mount complete -F _function declare complete -F _filedir_xspec pdftex complete -F _ag ag complete -o default -o nospace -F _fzf_var_completion export complete -F _vipw vigr complete -o default -F _ansible-doc ansible-doc complete -F _nslookup nslookup complete -F _ssh slogin complete -o nospace -F _alias alias complete -F _fzf_path_completion gvim complete -F _filedir_xspec kaffeine complete -F _stream stream complete -F _docker drdp complete -o default -F _complete_grape grape.sh complete -F _filedir_xspec mpg123 complete -F _fzf_path_completion find complete -F _filedir_xspec lzegrep complete -o default -F _ansible-pull ansible-pull complete -o default -F _longopt split complete -o bashdefault -o default -F _fzf_path_completion zip complete -F _ssh autossh complete -F _filedir_xspec xv complete -o default -F _longopt fold complete -F _known_hosts mtr complete -o bashdefault -o default -F _fzf_path_completion ruby complete -o nospace -F _fzf_path_completion scp complete -F _known_hosts ping6 complete -F _filedir_xspec timidity complete -F _filedir_xspec xdvi complete -F _filedir_xspec xfig complete -F _filedir_xspec xpdf complete -o default -F _longopt indent complete -o bashdefault -o default -F _fzf_path_completion chmod complete -o nospace -F _user_at_host finger complete -o bashdefault -o default -o nospace -F _python_argcomplete pipx complete -F _ktutil ktutil complete -F _xz xz complete -F _filedir_xspec oobase complete -F _docker dpa complete -F _fzf_path_completion perl complete -F _root_command kdesudo complete -F _docker drmi complete -F _filedir_xspec ogg123 complete -F _filedir_xspec lzgrep complete -u w complete -F _filedir_xspec ee complete -F _sh sh complete -o default -F __start_kubectl kubecolor complete -F _docker dps complete -F _filedir_xspec gharbour complete -u su complete -o default -F _complete_grape grape complete -o default -F _longopt irb complete -F _known_hosts host complete -o default -F __start_kubectl k complete -o bashdefault -o default -F _fzf_path_completion ex complete -o default -F _complete_groovyConsole groovyConsole complete -o nospace -F __gdbus gdbus complete -F _sysctl sysctl complete -F _sqlite3 sqlite3 complete -o default -F _iconv iconv complete -F _command tsocks complete -F _docker d complete -F _xmllint xmllint complete -o default -F _fzf_path_completion diff complete -F _ldapwhoami ldapwhoami complete -F _bzip2 pbzip2 complete -F _postmap postmap complete -o bashdefault -o filenames -F _pandoc pandoc complete -F _filedir_xspec bzcat complete -F _filedir_xspec unlzma complete -F _filedir_xspec dragon complete -F _xzdec xzdec complete -o default -F _longopt shar complete -F _filedir_xspec ooimpress complete -F _cpio cpio complete -F _filedir_xspec xanim complete -o default -F _complete_groovysh groovysh.bash complete -o default -F _ansible-vault ansible-vault complete -j -P '"%' -S '"' disown complete -F _filedir_xspec xine complete -o default -F _longopt bash complete -o default -F _longopt md5sum complete -o bashdefault -o default -F _fzf_path_completion source complete -F _filedir_xspec amaya complete -F _filedir_xspec gv complete -F _make make complete -o default -F _fzf_path_completion curl complete -A stopped -P '"%' -S '"' bg complete -o default -F __start_kubectl kubeproxy complete -F _filedir_xspec kid3 complete -o nospace -F __gresource gresource complete -F _filedir_xspec lilypond complete -o default -F _longopt bc complete -F _identify identify complete -F _filedir_xspec modplug123 complete -o default -F __start_kubectl k4 complete -F _pack200 pack200 complete -A binding bind complete -o default -F _setquota setquota complete -b builtin complete -F _unpack200 unpack200 complete -o default -F _quotacheck quotacheck complete -F _filedir_xspec pbzcat complete -F _known_hosts tracepath6 complete -o default -F _complete_groovyc groovyc complete -o default -F _longopt shasum complete -F _command ltrace complete -o default -F __start_kubectl k3 complete -F _fzf_path_completion gcc complete -F __app gapplication complete -o bashdefault -o default -F _fzf_path_completion xdg-open complete -o default -F _ansible-playbook ansible-playbook complete -u write complete -F _known_hosts traceroute6 complete -F _fzf_path_completion jar complete -o default -F _longopt date complete -F _gcc gcj complete -F _filedir_xspec rgview complete -o default -F _fzf_path_completion cat complete -o default -F _fzf_path_completion awk complete -o default -F _complete_groovyConsole groovyConsole.sh complete -o default -F _longopt sha512sum complete -F _filedir_xspec unxz complete -o default -F _longopt seq complete -o default -F _longopt mkdir complete -F _filedir_xspec rvim complete -o default -F __start_kubectl krn complete -o default -F _longopt sha224sum complete -A helptopic help complete -F _fzf_path_completion sftp complete -A setopt set complete -o default -F __start_kubectl krc complete -F _compare compare complete -F _tmux tmux complete -F _ssh_copy_id ssh-copy-id complete -o default -F _fzf_path_completion sort complete -o default -F _longopt pr complete -o default -F _longopt colordiff complete -o default -F _fzf_path_completion patch complete -F _fzf_path_completion g++ complete -o bashdefault -o default -F _fzf_path_completion python complete -F _conjure conjure complete -F _ldappasswd ldappasswd complete -F _filedir_xspec playmidi complete -o default -F __start_kubectl kcEvicted complete -o default -F _openssl openssl complete -o default -F _longopt fmt complete -o default -F _fzf_path_completion sed complete -F _tcpdump tcpdump complete -F _javadoc javadoc complete -F _filedir_xspec lzcat complete -o default -F _longopt gperf complete -F _command time complete -F _filedir_xspec zcat complete -F _mogrify mogrify complete -F _display display complete -F _root_command fakeroot complete -o default -F _complete_groovy groovy.bash complete -F _filedir_xspec lynx complete -u slay complete -F _filedir_xspec uncompress complete -F _autoreconf autoreconf complete -F _filedir_xspec xzcat complete -o default -F _fzf_dir_completion rmdir complete -F _filedir_xspec slitex complete -o bashdefault -o default -F _fzf_opts_completion vim complete -F _filedir_xspec aaxine complete -F _filedir_xspec advi complete -o bashdefault -o default -F _fzf_path_completion more complete -o default -F _longopt units complete -F _docker dcleanfull complete -o default -F _longopt touch complete -F _filedir_xspec lzmore complete -F _command then complete -F _command command complete -F _docker dkill complete -o default -F __start_kubectl kd complete -F _known_hosts fping6 complete -u runuser complete -F _filedir_xspec dvipdf complete -o default -F __start_kubectl kc complete -F _gradle gradle.bat
osx
[!NOTE|label:references:]
$ brew install bash-completion
# or
$ brew install bash-completion@2
# -- add to bash_profile --
$ echo '[[ -r "$(brew --prefix)/etc/profile.d/bash_completion.sh" ]] && source "$(brew --prefix)/etc/profile.d/bash_completion.sh"' >> ~/.bash_profile
$ echo 'command -v brew >/dev/null && source "$(brew --prefix git)"/etc/bash_completion.d/git-*.sh || source "$(brew --prefix git)"/etc/bash_completion.d/git-prompt.sh' >> ~/.bash_profile
# or
$ echo "[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion" >> ~/.bash_profile
$ cat ~/.bash_profile
[ -f /usr/local/etc/bash_completion ] && . /usr/local/etc/bash_completion
to check link of bash-completion
$ brew unlink bash-completion --dry-run Would remove: /usr/local/etc/bash_completion /usr/local/etc/bash_completion.d/abook /usr/local/etc/bash_completion.d/ant ...
add more completion files
$ fd --gen-completions bash | sudo tee $(brew --prefix)/etc/bash_completion.d/fd
more
$ brew search completion ==> Formulae apm-bash-completion docker-completion open-completion stormssh-completion bash-completion ✔ fabric-completion packer-completion t-completion bash-completion@2 gem-completion pip-completion tmuxinator-completion boom-completion gradle-completion ✔ rails-completion vagrant-completion brew-cask-completion ✔ grunt-completion rake-completion wp-cli-completion bundler-completion kitchen-completion ruby-completion yarn-completion cap-completion launchctl-completion rustc-completion zsh-completions conda-zsh-completion maven-completion sonar-completion django-completion mix-completion spring-completion ==> Casks compositor
linux
enable
if ! shopt -oq posix; then if [ -f /usr/share/bash-completion/bash_completion ]; then . /usr/share/bash-completion/bash_completion elif [ -f /etc/bash_completion ]; then . /etc/bash_completion fi fi
add more completion files
$ fd --gen-completions bash | sudo tee /usr/share/bash-completion/completions/fd
centos
$ fd --gen-completions bash | sudo tee /etc/bash_completion.d/fd
completion for alias
[!TIP|label:rerefences:]
download/install
# download bash_completion.sh for kubectl $ curl -fsSL https://github.com/cykerway/complete-alias/raw/master/complete_alias -o ~/.bash_completion.sh # or rhel/centos $ sudo curl -fsSL https://github.com/marslo/dotfiles/raw/main/.marslo/.completion/complete_alias -o /etc/profile.d/complete_alias.sh # or osx $ sudo curl -fsSL https://github.com/marslo/dotfiles/raw/main/.marslo/.completion/complete_alias -o $(brew --prefix)/etc/bash_completion.d/complete_alias $ sudo chmod +x !$
setup for specific alias
$ echo "complete -F _complete_alias <alias>" >> ~/.bash_profile
example
# i.e.: for kubec* ( kubectl or kubecolor ) $ complete -o nosort -o bashdefault -o default -F _complete_alias $(alias | sed -rn 's/^alias ([^=]+)=.+kubec.+$/\1/p' | xargs) # or $ alias k=kubectl $ echo "complete -F _complete_alias k" >> ~/.bash_profile
troubleshooting
$ ssh bash_completion: _comp_compgen_known_hosts__impl: -F: an empty filename is specified
[!NOTE|label:references:]
clear completion
$ complete -r ssh
or add into
/usr/local/etc/bash_completion.d/ssh
or$(brew --prefix)/etc/bash_completion.d/ssh
# https://unix.stackexchange.com/a/181603/29178 _ssh_hosts() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" opts=$(command grep '^Host' ~/.ssh/config ~/.ssh/config.d/* 2>/dev/null | command grep -v '[?*]' | cut -d ' ' -f 2-) COMPREPLY=( $(compgen -W "$opts" -- ${cur}) ) return 0 } _ssh() { local cur prev configfile local -a config # configfile="$HOME/.ssh/config" COMPREPLY=() _get_comp_words_by_ref -n : cur prev #cur=`_get_cword :` #prev=`_get_pword` _ssh_suboption_check && return 0 case $prev in -F|-i|-S) _filedir return 0 ;; -c) _ssh_ciphers return 0 ;; -m) _ssh_macs return 0 ;; -l) COMPREPLY=( $( compgen -u -- "$cur" ) ) return 0 ;; -o) _ssh_options return 0 ;; -w) _available_interfaces return 0 ;; -b) _ssh_bindaddress return 0 ;; esac if [[ "$cur" == -F* ]]; then cur=${cur#-F} _filedir # Prefix completions with '-F' COMPREPLY=( "${COMPREPLY[@]/#/-F}" ) cur=-F$cur # Restore cur elif [[ "$cur" == -* ]]; then COMPREPLY=( $( compgen -W '-1 -2 -4 -6 -A -a -C -f -g -K -k -M \ -N -n -q -s -T -t -V -v -X -v -Y -y -b -b -c -D -e -F \ -i -L -l -m -O -o -p -R -S -w' -- "$cur" ) ) else # Search COMP_WORDS for '-F configfile' or '-Fconfigfile' argument set -- "${COMP_WORDS[@]}" while [ $# -gt 0 ]; do if [ "${1:0:2}" = -F ]; then if [ ${#1} -gt 2 ]; then configfile="$(dequote "${1:2}")" else shift [ "$1" ] && configfile="$(dequote "$1")" fi break fi shift done # marslo >> disable _known_hosts_real from $configfile # marslo >> using self-defined _ssh_hosts function # _known_hosts_real -a -F "$configfile" "$cur" _ssh_hosts if [ $COMP_CWORD -ne 1 ]; then _compopt_o_filenames COMPREPLY=( "${COMPREPLY[@]}" $( compgen -c -- "$cur" ) ) fi fi return 0 } shopt -u hostcomplete && complete -F _ssh ssh slogin autossh $ complete -F _ssh ssh
tricky
alias for sudo
[!TIP|label:references:]
alias sudo='sudo '
get md5sum
get file in tar without exacting
$ tar -O -xf file.tar.gz file.txt | md5sum # or $ tar xfO file.tar.gz file.txt | md5sum
get file in zip without extracting
$ unzip -p file.zip file.txt | md5sum
env
HISTTIMEFORMAT
# https://www.commandlinefu.com/commands/view/3642/save-date-and-time-for-each-command-in-history export HISTTIMEFORMAT="%h/%d-%H:%M:%S " # or: YYYY-MM-DD HH:MM:SS : https://www.commandlinefu.com/commands/view/3646/save-date-and-time-for-each-command-in-history $ export HISTTIMEFORMAT='%F %T '
$ GREP_OPTIONS='-D skip --binary-files=without-match --ignore-case'
shortcuts
inserts the results of an autocompletion in the command line
$ <command> <kbd>esc</kbd> <kbd>*</kbd>
i.e.:
$ echo |
-> esc *
man
$ man hier
show ascii
$ man ascii
$ showkey -a
[!TIP]
PS4 The value of this parameter is expanded like PS1 and the expanded value is the prompt printed before the command line is echoed when the -x option is set (see The Set Builtin). The first character of the expanded value is replicated multiple times, as necessary, to indicate multiple levels of indirection. The default is ‘+ ’.
$ export PS4='+\033[37;2;3m(${BASH_SOURCE}:${LINENO})\033[0m: \033[35;2;3m${FUNCNAME[0]:+${FUNCNAME[0]}():}\033[0m ' # or $ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' # even more: $ export PS4='Line $LINENO @ $(date +%s.%N): '
[!NOTE|label:references:]
Bash VariablesBASH_LINENO An array variable whose members are the line numbers in source files where each corresponding member of
FUNCNAME
was invoked.${BASH_LINENO[$i]}
is the line number in the source file (${BASH_SOURCE[$i+1]}
) where${FUNCNAME[$i]}
was called (or${BASH_LINENO[$i-1]}
if referenced within another shell function). UseLINENO
to obtain the current line number.FUNCNAME An array variable containing the names of all shell functions currently in the execution call stack. The element with index 0 is the name of any currently-executing shell function. The bottom-most element (the one with the highest index) is "main". This variable exists only when a shell function is executing. Assignments to
FUNCNAME
have no effect. IfFUNCNAME
is unset, it loses its special properties, even if it is subsequently reset.This variable can be used with
BASH_LINENO
andBASH_SOURCE
. Each element ofFUNCNAME
has corresponding elements inBASH_LINENO
andBASH_SOURCE
to describe the call stack. For instance,${FUNCNAME[$i]}
was called from the file${BASH_SOURCE[$i+1]}
at line number${BASH_LINENO[$i]}
. Thecaller
builtin displays the current call stack using this information.
#!/usr/bin/env bash function log() { echo "LINENO: ${LINENO}" echo "BASH_LINENO: ${BASH_LINENO[*]}; LINENO: ${LINENO}" } function foo() { log "$@"; } foo "$@"
# result $ bash -x debug.sh +(debug.sh:12): foo +(debug.sh:9): foo(): log +(debug.sh:4): log(): echo 'LINENO: 4' LINENO: 4 +(debug.sh:5): log(): echo 'BASH_LINENO: 9 12 0; LINENO: 5' BASH_LINENO: 9 12 0; LINENO: 5
Last updated
Was this helpful?