re: non-interactive usage, resurrecting this patch (with tests) from 2019. I run it locally (as I am constantly `pass show | grep ...`-ing) and have had no issues with it since developing it.
--Robert Begin forwarded message: On Saturday, July 20, 2019, 2:50 AM, Robert Ames <[email protected]> wrote: > When working with nested password directories / structures, it's a pain to > pick out a particular password key/identifier for copy/paste. This patch > (and test) is the beginning of teaching pass about interactive v. > non-interactive usage so that `pass ls` will print fully qualified > identifiers when in non-interactive mode. > > The gist of it is captured below, and similar behavior can be seen in the > `lastpass-cli` tool (not that lastpass is a great example of what to do in > general, but it's very handy to have access to the fully qualified password > identifiers). > > https://github.com/lastpass/lastpass-cli/blob/master/cmd-ls.c#L287-L288 > > $ ./src/password-store.sh ls > Password Store > ├── xxxxxxxx > │ └── xxxxx.xxx > └── xxxxx > ├── xxxxxxxxxxxxx.xxx > ├── xxxxxxx.xxx > ├── xxxxxxx.xxx > ├── xxxxxxxxx.xxx > ├── xxxxxxxxxxxxxxxxxxx.xxx > ├── xxxxxxxx.xxx > ├── xx.xx-xxxxxxxx > ├── xx.xxxxx.xxx > │ └── xxx-xxx > ├── xxxxxxx.xxx > ├── xxxxxxxx > │ ├── xxxxxx-xxxxx > │ ├── xxxxx-xxxxx-xxxxxxxx > │ └── xxxxx-xxxxx-xxxxxxx > └── xxxxxx.xxx > > $ ./src/password-store.sh ls | cat > xxxxxxxx/xxxxx.xxx > xxxxx/xxxxxxx.xxx > xxxxx/xx.xxxxx.xxx/xxx-xxx > xxxxx/xxxxxxx.xxx > xxxxx/xxxxxxx.xxx > xxxxx/xxxxxxxx.xxx > xxxxx/xx.xx-xxxxxxxx > xxxxx/xxxxxxxxxxxxx.xxx > xxxxx/xxxxxxxxx.xxx > xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxxx > xxxxx/xxxxxxxx/xxxxxx-xxxxx > xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxx > xxxxx/xxxxxx.xxx > xxxxx/xxxxxxxxxxxxxxxxxxx.xxx > > $ ./src/password-store.sh ls | while read id ; do echo "--==[[ $id ]]==--" ; > echo ./src/password-store.sh show $id ; done > --==[[ xxxxxxxx/xxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxxxxx/xxxxx.xxx > --==[[ xxxxx/xxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxx.xxx > --==[[ xxxxx/xx.xxxxx.xxx/xxx-xxx ]]==-- > ./src/password-store.sh show xxxxx/xx.xxxxx.xxx/xxx-xxx > --==[[ xxxxx/xxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxx.xxx > --==[[ xxxxx/xxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxx.xxx > --==[[ xxxxx/xxxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxx.xxx > --==[[ xxxxx/xx.xx-xxxxxxxx ]]==-- > ./src/password-store.sh show xxxxx/xx.xx-xxxxxxxx > --==[[ xxxxx/xxxxxxxxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxxxxxxx.xxx > --==[[ xxxxx/xxxxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxxx.xxx > --==[[ xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxxx > --==[[ xxxxx/xxxxxxxx/xxxxxx-xxxxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxx/xxxxxx-xxxxx > --==[[ xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxx/xxxxx-xxxxx-xxxxxxx > --==[[ xxxxx/xxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxx.xxx > --==[[ xxxxx/xxxxxxxxxxxxxxxxxxx.xxx ]]==-- > ./src/password-store.sh show xxxxx/xxxxxxxxxxxxxxxxxxx.xxx > > > > >>
From 8e70219ffb7730f524d4eaeaf23409f8ecdd67f3 Mon Sep 17 00:00:00 2001 From: Robert Ames <[email protected]> Date: Fri, 19 Jul 2019 23:49:21 -0700 Subject: [PATCH] Print full paths in pipeline / non-interactive usage When using nested directories for password management, the use of "tree" during password listing makes it difficult to copy/paste password identifiers. Attempt basic detection of "TTY" (interactive) as a pre-requisite for displaying a tree. For non-interactive uses prefer a simple find statement which emits full password identifiers ready to by copy/pasted or proper filtering by any element of the path. This more closely matches the behaviour of other CLI password tools, for example `lastpass-cli`[1], and "print_tree" / "isatty" [1]: https://github.com/lastpass/lastpass-cli/blob/2a70884ed7ef48a8d621687acb96202cc354245b/cmd-ls.c#L287-L288 --- src/password-store.sh | 11 +++++++++-- tests/t0020-show-tests.sh | 8 ++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/password-store.sh b/src/password-store.sh index 1d119f2..66fe4f1 100755 --- a/src/password-store.sh +++ b/src/password-store.sh @@ -5,6 +5,7 @@ umask "${PASSWORD_STORE_UMASK:-077}" set -o pipefail +[[ -t 1 ]] && YES_TTY=1 GPG_OPTS=( $PASSWORD_STORE_GPG_OPTS "--quiet" "--yes" "--compress-algo=none" "--no-encrypt-to" ) GPG="gpg" @@ -395,11 +396,17 @@ cmd_show() { fi elif [[ -d $PREFIX/$path ]]; then if [[ -z $path ]]; then - echo "Password Store" + if [[ $YES_TTY -eq 1 ]] ; then + echo "Password Store" + fi else echo "${path%\/}" fi - tree -C -l --noreport "$PREFIX/$path" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors + if [[ -z $YES_TTY ]] ; then + find "$PREFIX/$path" -type f -iname \*.gpg | sed -e 's/\.gpg$//g' -e "s,^$PREFIX,,g" -e 's/^\///g' # when non-interactive (pipeline) print full-path-per-entry (for easy copy/paste or filtering) + else + tree -C -l --noreport "$PREFIX/$path" | tail -n +2 | sed -E 's/\.gpg(\x1B\[[0-9]+m)?( ->|$)/\1\2/g' # remove .gpg at end of line, but keep colors + fi elif [[ -z $path ]]; then die "Error: password store is empty. Try \"pass init\"." else diff --git a/tests/t0020-show-tests.sh b/tests/t0020-show-tests.sh index a4b782f..c3671b2 100755 --- a/tests/t0020-show-tests.sh +++ b/tests/t0020-show-tests.sh @@ -19,4 +19,12 @@ test_expect_success 'Test "show" of nonexistant password' ' test_must_fail "$PASS" show cred2 ' +test_expect_success 'Test "show" command with simple tree' ' + "$PASS" insert -e tree/of/creds1 <<<"blah" && + "$PASS" insert -e tree/of/creds2 <<<"blah" && + [[ $("$PASS" show | grep "tree.of" | wc -l | sed "s/ *//g") == "2" ]] && + "$PASS" rm tree/of/creds1 && + "$PASS" rm tree/of/creds2 +' + test_done -- 2.17.1
