pipe output from interactive command to less
Asked Answered
A

2

7

I'd like to do something like

openssl enc -d -aes256 -in somefile | less

openssl requires a password from stdin. and this gets all messed up when less is involved.

Is there a way to take the output from an interactive command (like openssl asking for a password) and pipe the output into less?

Or is there a better technique using a bash script?

Animal answered 23/8, 2013 at 2:13 Comment(2)
the following would work, but i was hoping to find a way that didn't use temp files... $tmp_file=$(mktemp); openssl enc -d -in somefile > $tmp_file; less $tmp_file; rm $tmp_fileAnimal
I do this all the time with rsync over ssh, and usually have no problems. When things do get mixed up, it seems to be a timing thing - it's not happened for a while, but as I recall, if rsync was slow at asking for a password, things went haywire.Policewoman
H
3

Perhaps have the shell script ask for the key, then store the key in a temp file and use openssl's -kfile option to find it. Hope your version of openssl supports -kfile.

I'd worry about security with this, but with a little care the security hole is perhaps smaller than you might think. (But do you trust your sysadmin and sudoers...?)

#!/bin/bash

INFILE=somefile

read -s -p "Enter key for $INFILE: " key
echo

# write the key to a temp file; use mktemp(1)
# for safer creation of a privately-owned file.
#
TMPKEY=$(mktemp -t) || exit 1
echo "$key" > "$TMPKEY"

# will remove the temp file on script exit
trap 'rm -f "$TMPKEY"' EXIT

# remove the key file a couple seconds after openssl runs
(sleep 2; rm -f "$TMPKEY") &

openssl enc -d -aes256 -in "$INFILE" -kfile "$TMPKEY" | less

[ -f "$TMPKEY" ] && rm -f "$TMPKEY"
trap - EXIT

# rest of script...

exit 0
Halo answered 23/8, 2013 at 3:23 Comment(4)
Please don't forget to use double quotes around variables. Replace $TMPKEY with "$TMPKEY". This is very important because if a file contains a space character, then it is going to be split into two separate parameters. For example: myFile='my awesome file' rm "$myFile" is going to remove one file which is called my awesome file, this is correct. But rm $myFile is going to remove three files: my , awesome and file which is wrong and unpredictable, unless you really know what you're doing.Chorea
In general, a very good rule. Having created and then used the TMPKEY variable all within a dozen lines in the sample script, I knew it contained no spaces ($$ resolves to all digits). But as you say, most scripts should use the safer technique: quote variables that hold a single, arbitrary, path name.Halo
The point is that your script is an example and most probably people will change the variables to their own liking, but they're not expecting that it will fail just because of the spaces in a directory. Could you please fix it so I can vote it up?Chorea
Edited to use mktemp(1) to pick the temp file name and create it, so the sub-shell and umask technique not needed. Quoted variables storing file names.Halo
C
1

You can try this:

echo 'mypassword' | openssl enc -d -aes256 -in somefile | less

But this doesn't look secure.

I have not tried running openssl this way, but in case it is too verbose and if previous code is not going to work then you can always try using expect. Here's an example:

expect -c '
    spawn yourscript
    expect "Please enter your password:"
    send "$PASSWORD"
'
Chorea answered 23/8, 2013 at 2:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.