contrib: Add bash completion for new bitcoin command
What changed, and why it matters
This commit adds a new bash tab-completion helper script for a new 'bitcoin' command-line wrapper tool. It only lives in the contrib/ directory (optional add-on files) and does not change any Bitcoin Core wallet, networking, or consensus code. There is no security issue visible in the change.
No security action required; review as normal contrib/UX improvement if desired.
Security signals we found
No security signals present: change is a contrib/ shell-completion script with no functional core changes
Evidence from the diff
The patch introduces contrib/completions/bash/bitcoin.bash, a readline completion script. It sources existing completion functions for bitcoind/bitcoin-cli/bitcoin-tx and invokes the wrapper binary with ‘help’ to populate command/option lists. It does not alter core code, does not handle private keys, and does not introduce setuid, network, or file-write behavior beyond standard completion sourcing.
Changed components
contrib/completions/bash/bitcoin.bashInspect captured patch +100 / −0
diff --git a/contrib/completions/bash/bitcoin.bash b/contrib/completions/bash/bitcoin.bash
new file mode 100644
index 00000000..a2ecae03
--- /dev/null
+++ b/contrib/completions/bash/bitcoin.bash
@@ -0,0 +1,100 @@
+# bash programmable completion for bitcoin(1) wrapper
+# Copyright (c) 2026-present The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+# wrapper to delegate completion to the real function
+_bitcoin_wrap() {
+ local delegate="$1" shift_count="$2"
+ local func="_${delegate//-/_}"
+ local words cword dir file
+
+ # load completion script if function not yet defined
+ if ! declare -F $func >/dev/null; then
+ dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ file="$(grep -l -E "complete[[:space:]]+-F[[:space:]]+${func}" "$dir"/* 2>/dev/null | head -n1)"
+ [ -z "$file" ] && file="$(grep -l -E "^[[:space:]]*${func}[[:space:]]*\(\)" "$dir"/* 2>/dev/null | head -n1)"
+ [ -n "$file" ] && source "$file" || return 0
+ fi
+
+ _get_comp_words_by_ref -n = words cword
+
+ COMP_WORDS=( "$delegate" "${words[@]:$shift_count}" )
+ COMP_CWORD=$(( cword - (shift_count - 1) ))
+ COMP_LINE="${COMP_WORDS[@]}"
+ COMP_POINT=${#COMP_LINE}
+ $func "$delegate"
+}
+
+_bitcoin() {
+ local cur prev words cword
+ local bitcoin subcmd offset
+
+ # save and use original argument to invoke bitcoin for help
+ # it might not be in $PATH
+ bitcoin="$1"
+
+ COMPREPLY=()
+ _get_comp_words_by_ref -n = cur prev words cword
+
+ case "${words[1]}" in
+ -m|-M|--multiprocess|--monolithic)
+ subcmd="${words[2]}"
+ offset=3
+ ;;
+ *)
+ subcmd="${words[1]}"
+ offset=2
+ ;;
+ esac
+
+ case "$subcmd" in
+ gui|node)
+ _bitcoin_wrap bitcoind "$offset"
+ return 0
+ ;;
+ rpc)
+ _bitcoin_wrap bitcoin-cli "$offset"
+ return 0
+ ;;
+ tx)
+ _bitcoin_wrap bitcoin-tx "$offset"
+ return 0
+ ;;
+ esac
+
+ case "$cur" in
+ -*=*) # prevent nonsense completions
+ return 0
+ ;;
+ *)
+ local options commands
+
+ # only parse help if sensible
+ if [[ -z "$cur" || "$cur" =~ ^- ]]; then
+ options=$($bitcoin help 2>&1 | awk '{ for(i=1;i<=NF;i++) if ($i~/^--/) { sub(/=.*/, "=",$i); print $i } }' )
+ fi
+ if [[ -z "$cur" || "$cur" =~ ^[a-z] ]]; then
+ commands=$($bitcoin help 2>/dev/null | awk '$1 ~ /^[a-z]/ { print $1; }')
+ fi
+
+ COMPREPLY=( $( compgen -W "$options $commands" -- "$cur" ) )
+
+ # Prevent space if an argument is desired
+ if [[ $COMPREPLY == *= ]]; then
+ compopt -o nospace
+ fi
+ return 0
+ ;;
+ esac
+
+} &&
+complete -F _bitcoin bitcoin
+
+# Local variables:
+# mode: shell-script
+# sh-basic-offset: 4
+# sh-indent-comment: t
+# indent-tabs-mode: nil
+# End:
+# ex: ts=4 sw=4 et filetype=sh
Why this scored 16/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.