[PATCH] pass find: Add --find flag

Alejandro Colomar alx at kernel.org
Sun Sep 24 21:44:14 UTC 2023


This flag modifies the command to use find(1) instead of tree(1).

A few tweaks are performed to the result of find:

(1)  Add a trailing slash to directories.  This is a useful way to
     distinguish files from dirs at first glance.  In the tree(1)
     version, it colors differently (as tree(1) does by default), so it
     seems consistent to distinguish them.

(2)  Remove the location of the password-store prefix from the path.

(3)  Remove the .gpg suffix from files (as is historic behavior of
     pass(1)).

Examples of use:

	$ pass find --find bugzilla
	Search Terms: bugzilla
	www/foss/kernel/bugzilla/
	www/foss/mozilla/bugzilla/
	www/foss/gentoo/bugzilla/
	www/foss/gnu/gcc/bugzilla/

	$ pass find --find kernel
	Search Terms: kernel
	www/foss/kernel/

Those tweaks to the output of find(1) make the output directly usable in
a subsequent invocation of pass(1):

	$ pass find --find kernel \
	  | tail -n -1 \
	  | xargs pass show;
	www/foss/kernel
	├── bugzilla
	│   ├── alx.manpages
	│   │   ├── id
	│   │   └── pass
	│   └── url
	└── smtp
	    └── pass

The tail(1) above is to hide the search terms.

Signed-off-by: Alejandro Colomar <alx at kernel.org>
---
 man/pass.1            | 16 +++++++++++++++-
 src/password-store.sh | 18 +++++++++++++++++-
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/man/pass.1 b/man/pass.1
index 8868b78..b9764c5 100644
--- a/man/pass.1
+++ b/man/pass.1
@@ -104,11 +104,25 @@ .SH COMMANDS
 as-is.
 (Note: the \fIGREP_OPTIONS\fP environment variable functions as well.)
 .TP
-\fBfind\fP \fIpass-names\fP...
+\fBfind\fP [ \fI\-\-find\fP ] \fIpass-names\fP...
 List names of passwords inside the tree that match \fIpass-names\fP by using the
 .BR tree (1)
 program.
 This command is alternatively named \fBsearch\fP.
+If the
+.I \-\-find
+flag is used,
+.BR find (1)
+is used instead;
+this is useful to be able to reuse the output as an input to
+.IR "pass ls" .
+Here's an example:
+.IP
+.in +4n
+.EX
+$ pass find \-\-find foo | tail \-n \-1 | xargs pass ls
+.EE
+.in
 .TP
 \fBshow\fP [ \fI\-\-clip\fP[=\fIline-number\fP], \fI\-c\fP[\fIline-number\fP] ] [ \fI\-\-qrcode\fP[=\fIline-number\fP], \fI\-q\fP[\fIline-number\fP] ] \fIpass-name\fP
 Decrypt and print a password named \fIpass-name\fP.
diff --git a/src/password-store.sh b/src/password-store.sh
index 22e818f..bf0e446 100755
--- a/src/password-store.sh
+++ b/src/password-store.sh
@@ -411,10 +411,26 @@ cmd_show() {
 }
 
 cmd_find() {
+	local opts find=0
+	opts="$($GETOPT -o "" -l find -n "$PROGRAM" -- "$@")"
+	local err=$?
+	eval set -- "$opts"
+	while true; do case $1 in
+		--find) find=1; shift ;;
+		--) shift; break ;;
+	esac done
+
 	[[ $# -eq 0 ]] && die "Usage: $PROGRAM $COMMAND pass-names..."
 	IFS="," eval 'echo "Search Terms: $*"'
 	local terms="*$(printf '%s*|*' "$@")"
-	tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
+
+	if [[ $find -eq 1 ]]; then
+		local n="$(echo "$PREFIX" | wc -c)"
+
+		find -L "$PREFIX" -iname "${terms%|*}" | sed 's,$,/,' | sed "s/^.\{$n\}//" | sed 's,\.gpg/$,,'
+	else
+		tree -N -C -l --noreport -P "${terms%|*}" --prune --matchdirs --ignore-case "$PREFIX" 3>&- | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g'
+	fi
 }
 
 cmd_grep() {
-- 
2.40.1



More information about the Password-Store mailing list