oneline commands

[!TIP]

cat and EOF

[!NOTE|label:references:]

  • Chapter 19. Here Documents
  • bash Heredoc
    • 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
      
  • * POSIX.1 states
    ...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 and timestamp

$ tail -f file | while read line; do echo -n $(date -u -Ins); echo -e "\t$line"; done

backup multiple files

$ 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 -"

find and rename

$ find -iname "*.sh" -exec rename "s/.sh$/.shell/" {} \; -print

find and sort

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>
    

mirror website

$ 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
  • download image only
    $ 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

show 256 colors

$ 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 and exclude

$ 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 file to equal size

$ 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

[!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:]

  • eval

    $ aa='echo me'
    $ var='aa'
    $ eval echo \$$var
    echo me
    
  • ${!var}

    $ 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
    1.2.1.2.1 -- using string as var name

<<<, < <(..)

[!TIP]

  • < <( is Process Substitution
    • The difference between <(...) and >(...) is merely which way the redirections are done

< <(..) && > >(..)

[!NOTE]

  • process substitution
  • syntax

    $ command1 < <( command2 )
    # equals to
    $ command2 | command1
    
    # if read from file, then using `< /path/to/file`
    
  • SubShell

  • 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:]

    • subshell
    • 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]

    • Process Substitution
      • >(...) is used less frequently; the most common situation is in conjunction with tee(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

EXPR DESCRIPTION
${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

EXPR DESCRIPTION
$@
           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
    
    sample script c.sh
    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}"
    
    result
    $ ./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

EXPR DESCRIPTION
${#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

SC2155

  • problematic code:
    ([ "$x" ] || [ "$y" ]) && [ "$z" ]
    
  • correct code:
    { [ "$x" ] || [ "$y" ]; } && [ "$z" ]
    
  • example

SC2155

  • problematic code:
    export foo="$(mycmd)"
    
  • correct code:
    foo="$(mycmd)"
    export foo
    

escape code

[!TIP] references:

ESCAPE CODE LANGUAGE DESCRIPTION
\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]

  • 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]

  • 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]

  • 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
    
  • list all completions

    [!TIP|label:references:]

    $ compgen --help
    Display possible completions depending on the options
    
    $ complete
    
    # show all commands
    $ compgen -c
    

    | COMMAND | DESCRIPTION | |:------------------------------|-------------| | $ compgen -c | commands | | $ compgen -a | aliases | | $ compgen -b | built-ins | | $ compgen -k | keywords | | $ compgen -A function | functions | | $ compgen -A function -abck | all above |

details...
  $ 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

  • -bash: _compopt_o_filenames: command not found

  • [-bash: [: too many arguments](../../linux/devenv.md#bash--too-many-arguments)

  • $ 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

      ssh completion script
      # 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

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

    $ GREP_OPTIONS='-D skip --binary-files=without-match --ignore-case'
    

shortcuts

man

debugging a script

  • making xtrace more useful

    [!TIP]

    • PS4 has to be start with + | and
    • 5.2 Bash Variables - PS4

      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): '
    
  • LINENO and BASH_LINENO

    [!NOTE|label:references:]

    • Bash Variables BASH_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). Use LINENO 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. If FUNCNAME is unset, it loses its special properties, even if it is subsequently reset.

      This variable can be used with BASH_LINENO and BASH_SOURCE. Each element of FUNCNAME has corresponding elements in BASH_LINENO and BASH_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]}. The caller 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
    
Copyright © marslo 2020-2024 all right reserved,powered by GitbookLast Modified: 2025-04-15 03:38:49

results matching ""

    No results matching ""