9

I have an Open Office Spreadsheet document stored inside a bash variable. I want to do something like the following to feed Open Office via STDIN:

echo "$openOfficeDoc" | ooffice

But it doesn't work.

Note: The content of the bash variable must not be written to disk.

I'll emphasize that I'm trying to pass to Open Office the actual data of the file.

I'm trying to store passwords in an Open Office Spreadsheet file. The passwords are encrypted using GPG. I don't want the passwords to be written to disk for security reasons.

The bash variable value is a binary blob of an Open Office Spreadsheet document. It is not ASCII.

The bash code I used to create the blob is:

data=$(cat "Encrypted.gpg" | gpg -u "Dor" -d)

While Encrypted.gpg is an encrypted file of an Open Office Spreadsheet.

Is it possible to feed Open Office via STDIN?

Aditya
  • 964
Dor
  • 2,535
  • 2
    Could you use a RAM disk? – Raphael Ahrens Sep 17 '13 at 17:41
  • Do you have any reason to believe that ooffice should accept input from STDIN? That is a feature that must be implemented by an individual program, it is not true for any and all executables. Note that command line arguments are not STDIN -- i.e., mycommand somearg is not at all the same as echo somearg | mycommand. – goldilocks Sep 17 '13 at 17:57
  • @RaphaelAhrens: No, I can't use RAM disk. – Dor Sep 17 '13 at 18:07
  • 2
    @Dor Maybe you should explain why you don't want to use any disk. Is it because of a security reason or has the machine no disk. – Raphael Ahrens Sep 17 '13 at 18:11
  • @Dor - how is the data formatted? – slm Sep 17 '13 at 18:13
  • @RaphaelAhrens: I'm trying to store passwords in an Open Office Spreadsheet file. The passwords are encrypted using GPG. I don't want the passwords to be written to disk for security reasons. – Dor Sep 17 '13 at 18:15
  • @sim: It is the format of an Open Office spreadsheet file. It is the actual file's content that's stored in the bash variable. It is a binary blob, not an ASCII. – Dor Sep 17 '13 at 18:16
  • @Dor - please show the command you used to create this blob. – slm Sep 17 '13 at 18:20
  • 3
    @Dor: note that other users may be able to read your secret content via /proc/<pid of echo>/cmdline if you're passing it to echo as an argument. The echo process will terminated immediately after it has printed its argument (it will not run all the time just because ooffice is still running), but it seems unsafe to me nonetheless. – Martin von Wittich Sep 17 '13 at 18:21
  • @MartinvonWittich - excellent point. The command line is notoriously easy to pick info from. – slm Sep 17 '13 at 18:22
  • @Dor: also if you're using a swap file or partition, your passwords may be written to the disk anyway. – Martin von Wittich Sep 17 '13 at 18:25
  • @sim: I've added the bash command to create the blob. – Dor Sep 17 '13 at 18:31
  • @MartinvonWittich: I'm trying to solve one problem at a time XD. The preferred approach is not using any disk. – Dor Sep 17 '13 at 18:31
  • Well, you could run ooffice as a server that accepts remote control commands over a TCP socket to create a spreadsheet, but that may be more complicated than what you had in mind. You can also create a spreadsheet in Python using a template. – 200_success Sep 17 '13 at 21:41
  • 2
    @MartinvonWittich: Actually I remembered that using the echo command is safe, because it's a shell built-in so it doesn't appear on the command line of any process. See the comment of the user "Gilles" here: http://unix.stackexchange.com/questions/78757/securely-feeding-a-program-with-a-password – Dor Sep 18 '13 at 11:42
  • You may may want to try something like this: echo -e "HTTP/1.1 200 OK\r\n\r\ncolumn1,column2,column3\nb1,b2,b3\nc1,c2,c3" | nc -i 1 -l 127.0.0.1 8888 that serves the file via HTTP, and then ooffice http://localhost:8888/a.csv. The "only" thing you should modify is to implement a sucessful response to WebDAV's PROPFIND and feed it to nc – Elias Torres Arroyo Sep 18 '13 at 15:06
  • @Dor: good point, hadn't thought of the fact that echo is usually a builtin command. – Martin von Wittich Sep 18 '13 at 16:43

7 Answers7

11

I don't think OpenOffice can be convinced to read from its standard input. But that doesn't matter. Just write the data to a temporary file.

You don't want the passwords to be written to disk. That's fine. Write them to a file that isn't stored on disk.

Many systems use an in-memory filesystem (tmpfs) for /tmp. Solaris has been doing that for ages; Linux distributions have been slow to come to the mix (Fedora 18 adopted it, Debian and Ubuntu still haven't budged) so it usually requires the system administrator to set it up manually. However, modern Linux distributions mount a tmpfs filesystem somewhere; recent versions of the standard library require it. The standard location for tmpfs is /run, with /run/shm being world-writable (same permissions as /tmp), but some distributions may not have it yet; look at /dev/shm and perhaps other locations.

3

Importing textual data

Your questions isn't entirely clear to me but it almost reads as if you have data that you want to import into OpenOffice. If that is the case then I would use one of these approaches below.

CSV file

I'd write that data out to a CSV file (.csv) and then open that file in OpenOffice.

csv2odf

Another idea would be to use the command line tool csv2odf to write your CSV formatted data into an ODF file.

Real file

Just opening a file

However if you're simply just trying to open a ODF document from the command line then you should be able to do it like so:

$ openoffice "$openOfficeDoc"

Importing binary data

Piping contents to OpenOffice

In looking at this several ways I do not believe there is a method that will allow you to do the following:

$ echo "$data" | openoffice

The limiting factor is not Linux though. You can echo data stored in variables just fine, and pipe it to tools that know how to open incoming file data on their STDIN.

Example

$ echo $data|strings| head -10
[Content_Types].xml 
E`2+
)+Bp_9
no+yV
2q^QF
M xv
C1lA
d:NA
_rels/.rels 
b"gi

The limiting factor here is OpenOffice. In looking through it's options I saw no method for coaxing it to open data via STDIN. It only knows how to open files.

slm
  • 369,824
  • Thanks for the detailed answer but all those solutions involve writing to disk... – Dor Sep 17 '13 at 18:08
  • @Dor - well as I said your Q isn't clear whether you're trying to pass the name of the file or the actual data through your example. Can you expand your Q so it's clearer? Showing the data you're echo'ing would be a big help. – slm Sep 17 '13 at 18:10
  • @sim: The data that I'm echo'ing is the actual data of the openOffice file (the actual content, not the name of the file). – Dor Sep 17 '13 at 18:13
  • @Dor - as in it's "col1 | col2 | col3" ascii data or a binary blob of the file? – slm Sep 17 '13 at 18:15
  • @sim: It is a binary blob of the file. (not ASCII) – Dor Sep 17 '13 at 18:16
1

Use an anonymous pipe as the file:

ooffice <(echo "$openOfficeDoc")

See also https://stackoverflow.com/questions/345505/how-can-you-diff-two-pipelines-in-bash

1

There is a zsh-only solution:

oofice =(echo $openOfficeDoc)

I use it a lot with a cli tool of mine that outputs some csv (with libreoffice, but it's the same idea).

If you want to stick with bash, you can still install zsh and invoke it just for this command:

TMP=$openOfficeDoc zsh -c 'oofice =(echo $TMP)'

NOTE: The zsh/bash <() notation does not work with ooffice/libreoffice according to my test, see a possible explanation why.

autra
  • 111
0

Open/Star/Libreoffice can receive data from STDIN via the Python-UNO bridge. The Input can then go into any Libreoffice document, here it is a Writer document.

This was tested on Ubuntu 16.04 with Libreoffice5. You need a python interpreter which has the uno libs included ! Libreoffice needs to be started as a service:

# soffice "--accept=socket,host=localhost,port=2002;urp;" --writer
# echo "test" | ./reader_uno.py
#!/usr/bin/python3
import sys
import uno
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
                "com.sun.star.bridge.UnoUrlResolver", localContext )
# connect to the running office
ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
# get the central desktop object
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
# access the current writer document
model = desktop.getCurrentComponent()
# access the document's text property
text = model.Text
# create a cursor
cursor = text.createTextCursor()
# read from STDIN and insert the text into the document
for line in sys.stdin:
  sys.stdout.write(line)
  text.insertString(cursor,line, 0 )
ctx.ServiceManager

More details can be found on my blog "bitkistl".
http://www.bitkistl.com/2016/02/libreopenstaroffice-hints-and-tips.html

0

This is not really an answer to your question, but a complete alternative to what you're currently trying to do: just use either a password manager like Revelation, or store your passwords as GPG-encrypted plain text.

  • Yeah thought of that but it bummers me out that I can't use any type of document that I want. It just can't be impossible, it's Linux :) But a plain text really seems the easiest choice for now. – Dor Sep 17 '13 at 18:34
0

Both Apache Open Office and Libre Office have the ability to save a file with a password - encrypting it with, e.g., blowfish or AES.

Look for the "Save With Password" checkbox on the "Save As" dialog box. You will then be prompted for the password and to confirm the password.

cas
  • 78,579